Travaux Pratiques

GCM Google Cloud Messaging

Thème: Partager la même liste de courses entre les membres d'une même famille ou d'une colocation.

Une liste de courses est constituée au fur et à mesure. Chaque modification, achat ou retrait d'un item de la liste entraînent cette même modification sur tous les mobiles abonnés. Ces modifications sont effectives même si l'application n'est pas au premier plan. La liste est persistante.

Notez que les modifications sont liées à la qualité de délivrance des messages via le système de Google. Cet article décrit une évaluation de ce système

 

Préambule:

   

Question 1)

1.1) Une liste de courses partagée


Proposition d'architecture: Toute modification de la liste souhaitée par l'utilisateur à partir de l'IHM est envoyée au Cloud via le contrôleur du Cloud, le message constitué de l'opération à exécuter et de ses paramètres, est ensuite diffusé par le Cloud, à tous les abonnés, incluant l'initiateur de l'opération. Le message transmis contient au minimum le type d'ACTION, le MODE et le type d'OPERATION à exécuter.

    Exemple : Un ajout d'item depuis l'IHM, engendre un "PUBLISH" sur le cloud ...

// Operation d'ajout d'un item,

public void onClickAjouter(View v){
  EditText et = (EditText)findViewById(R.id.
itemTexteId);
  String item = et.getText().toString();

  Intent intentToCloudController = new Intent();

  intentToCloudController.setAction(GCMCloudController.ACTION);

  intentToCloudController.putExtra(MODE_KEY,GCMCloudController.PUBLISH);
  intentToCloudController.putExtra(ACTION_KEY,ItemsController.ACTION);
  intentToCloudController.putExtra(OPERATION_KEY,ItemsController.ADD_TOP);
  intentToCloudController.putExtra(DATA_KEY,item);
  intentToCloudController.putExtra(PUBLISHER_REG_ID_KEY,GCMRegistrar.getRegistrationId(this));

  sendBroadcast(intentToCloudController);

    Installez votre application sur deux émulateurs, vérifiez, le bon fonctionnement. Votre application de liste doit fonctionner même si celle si n'est pas au premier plan ou active

  La liste des items est  persistante,

L'activity, l'IHM, peut ne pas être au premier plan, ne pas être active, la réception par le cloud des modifications effectuées par les autres abonnés doivent être prise en compte.

Le contrôleur (ItemsController) pourrait se charger de la persistance de la liste à chaque modification de celle-ci par un abonné, la vue (MainActivity) chargerait cette liste sauvegardée à chaque installation de celle ci au premier plan.

    La solution de la persistance est au choix SharedPreference, ou bien en fichier, ou encore avec un ContentProvider

 

Question 2)

2.1) La liste d'items peut être modifiée par tout abonné au Cloud, cette modification est diffusée à tous les autres abonnés, même si l'application n'est pas active, au premier plan. Vérifiez avec deux émulateurs que tout fonctionne correctement.

Synchronisation de la liste : un des abonnés décide que sa liste doit être celle de tous les abonnés.

2.2) Au clic sur le bouton actualiser, la liste des items de cet abonné devient la liste des items pour tous les abonnés, complétez la méthode onClickRefresh() de MainActivity, vérifiez...

Une idée de solution possible serait sauvegarder la liste du décideur, de vider toutes les listes de tous les abonnés, puis de publier via le cloud l'ajout de tous les items, l'opération pourrait être coûteuse en temps d'exécution, celle-ci utilisera une instance d'AsyncTask. A partir de cette synchronisation le bouton Actualiser est inhibé définitivement. 

// Operation de synchronisation de la liste des items

public void onClickRefresh(View v){
 
new AsyncTask<Void,Void,Void>(){

  @Override
  protected Void doInBackground(Void... arg0) {
      List<String> copie =
new ArrayList<String>();
      copie.addAll(
items.getList()); // copie de la liste de cet abonné

  Intent intentToCloudController = new Intent();
  intentToCloudController.setAction(GCMCloudController.
ACTION);
  intentToCloudController.putExtra(
MODE_KEY,GCMCloudController.PUBLISH);
  intentToCloudController.putExtra(
ACTION_KEY,ItemsController.ACTION);
  intentToCloudController.putExtra(
OPERATION_KEY,ItemsController.CLEAR);
  intentToCloudController.putExtra(
PUBLISHER_REG_ID_KEY,GCMRegistrar.getRegistrationId(MainActivity.this));
  sendBroadcast(intentToCloudController);
// toutes les listes de tous les abonnés sont vidées

  intentToCloudController.putExtra(OPERATION_KEY,ItemsController.ADD);

  // toutes les listes de tous les abonnés sont reconstituées à partir du contenu de copie
  // à compléter :

  }

  return null;

}

}.execute();

 Vérifiez le bon fonctionnement : vous devriez avoir la même liste quelque soit l'émulateur, le mobile et quelque soit la machine de TP sur laquelle cette application s'exécute.

 

2.3) Dès l'opération de synchronisation effectuée, un contrôle de cohérence pourrait être effectué : toutes les listes de tous les abonnés doivent être égales.

    Ajoutez à l'application cette nouvelle fonctionnalité, notez que certains abonnés peuvent ne pas être joignables, dans ce cas le résultat est partiel, indiquez simplement le nombre d'abonnés avec la cohérence respectée.

 

Annexe: Gestion de la liste des abonnés, un service web existant

Récapitulatif des associations méthodes Java / requêtes HTTP,

  http://jfod.cnam.fr/jnews/tests/http_list.html

Formulaires HTML

  nom=liste_777&commande=ajouter&elt=essai

nom : elt :

  nom=liste_777&commande=retirer&elt=essai

nom : elt :

  nom=liste_777&commande=vider

nom :

  nom=liste_777&commande=estPresent&elt=essai

nom : elt :

  nom=liste_777&commande=taille

nom :

  nom=liste_777&commande=toString

nom :

notez que

  1. Les données manipulées sont des "String", limitées à cette expression régulière : [A-Za-z0-9_\-]+
  2. Toute requête engendre la création de la liste distante, si celle-ci n'existait pas encore sur le serveur.
  3. L'identifiant associé à votre liste doit être unique.

La présence d'un identifiant dans cette table peut être vérifiée avec ce test

identifiant :