Android PublishSubscribe Firebase GCM Google Cloud Messaging une
Android Publish/Subscribe, Firebase, GCM, Google Cloud Messaging une introduction jean-michel Douin, douin au cnam point fr version : 2 Juin 2020 Notes de cours Receiver, Firebase Cloud Messaging 1
Sommaire • Le socle, les fondements – Le patron publish-subscribe • En local, un seul mobile – L’entité Android de base : Receiver • • Publication – send. Broadcast(Intent i) , send. Ordered. Broadcast Souscription – on. Receive, (Broadcast. Receiver) • En global, plusieurs mobiles – « Over the Air » : GCM, Google Cloud Messaging – API Google/Firebase • • • https: //firebase. google. com/ https: //console. firebase. google. com Publication – Requête aux serveurs Google Souscription – on. Receive (service android) • Une architecture logicielle possible, pour discussions Receiver, Firebase Cloud Messaging 2
Principale bibliographie • Le tutorial indispensable – https: //firebase. google. com/docs/android/setup? authuser=1 • Avant il y avait c 2 dm (->2016) – Vogella • https: //www. vogella. com/tutorials/Google. Cloud. Messaging/article. html Receiver, Firebase Cloud Messaging 3
Les fondements • Le patron publish/subscribe – Publication à l’occurrence d’un évènement – Un sms entrant, la batterie déchargée, … – Un évènement engendré par l’utilisateur – Souscription à un évènement – Agir en conséquence – Un médiateur se charge • De la réception des évènements, de leur filtrage • De la diffusion auprès des souscripteurs sélectionnés – Diffusion aléatoire ou ordonnée Receiver, Firebase Cloud Messaging 4
Publish-Subscribe, cf NSY 102 • source: http: //www 2. lifl. fr/icar/Chapters/Intro/intro. html Receiver, Firebase Cloud Messaging 5
Publish-subscribe/ pull-push • Les news d’internet, ou le forum de jfod … – Enregistrement d’un « client » à un sujet de discussion, – Un des « clients » décide de poster un message, – Les utilisateurs à leur initiative vont cher l’information, – Publish-subscribe, mode pull • Les listes de diffusion, logiciels de causerie, ( « chat » ) – Abonnement d’un « client » à une liste de diffusion, – Un des « clients » décide de poster un message, – Tous les abonnés reçoivent ce message, – Publish-subscribe, mode push Receiver, Firebase Cloud Messaging 6
Un exemple, mode push Receiver, Firebase Cloud Messaging 7
En Java/ notation UML/Blue. J Receiver, Firebase Cloud Messaging 8
Android et le patron Publish/Subscribe • Une application Android peut : – Souscrire à un thème de publication, • réception de SMS, niveau de batterie, … – Publier un évènement • une alarme à son échéance, un évènement interne à l’application, … – Google Cloud Messaging une API prête à l’emploi • plusieurs mobiles peuvent souscrire et être notifiés « Over the Air » Receiver, Firebase Cloud Messaging 9
Android/Publish-Subscribe : les bases souscription • publication Source : http: //marakana. com/s/architecting_android_apps, 1178/index. html Receiver, Firebase Cloud Messaging 10
Publish-Subscribe/Intent & Context Broadcast. Receiver X, Y Intent • http: //www 2. lifl. fr/icar/Chapters/Intro/intro. html Receiver, Firebase Cloud Messaging 11
Souscription : schéma de programme • Basée sur les – Intent (Topic), – Context (Mediator), – Broadcast. Receiver (Subscriber). import android. content. Intent; import android. content. Context; import android. content. Broadcast. Receiver; import android. util. Log; public class Receiver. Template extends Broadcast. Receiver { public void on. Receive(Context context, Intent intent) { Log. i(TAG, "on. Receive action: "+intent. get. Action() ); } } Receiver, Firebase Cloud Messaging 12
Souscription effective • Déclarative, Android. Manifest. xml – Au sein d’une application <receiver android: name=". Receiver. Template"> <intent-filter> <action android: name=" android. intent. action. SMS_RECEIVED_ACTION " /> </intent-filter> </receiver> • Par programme – get. Application. Context(). register. Receiver( Receiver. Template(), Intent. Filter(Intent. SMS_RECEIVED_ACTION)); Receiver, Firebase Cloud Messaging new 13
Par programme • Cf. le cycle de vie d’une activité • on. Resume – register. Receiver( … • on. Pause – unregister. Receiver( … Receiver, Firebase Cloud Messaging 14
Les acteurs • classe Context, le Mediator – • classe Broadcast. Receiver, le Subscriber – • http: //developer. android. com/reference/android/content/Broadcast. Receiver. html classe Intent + Intent. Filter, X, Y les thèmes – • http: //developer. android. com/reference/android/content/Context. html http: //developer. android. com/reference/android/content/Intent. html À suivre: 3 exemples avec le système Android 1. Le niveau de la batterie vient d’être réactualisé, 2. Un sms vient d’arriver, 3. Un évènement de l’utilisateur. Receiver, Firebase Cloud Messaging 15
Exemple 1 : la batterie a changé d’état public class Low. Battery. Activity extends Activity { private Broadcast. Receiver receiver; public void on. Create(Bundle saved. Instance. State) { …} public void on. Resume() { Intent. Filter filter = new Intent. Filter(Intent. ACTION_BATTERY_CHANGED); this. receiver = new Battery. Changed. Receiver(); // Souscription register. Receiver(this. receiver, filter); } public void on. Pause() { // Dé-souscription unregister. Receiver(this. receiver); } Receiver, Firebase Cloud Messaging 16
Le souscripteur // le Souscripteur private static class Battery. Changed. Receiver extends Broadcast. Receiver { public void on. Receive(Context context, Intent intent) { Toast. make. Text(context, "battery changed", Toast. LENGTH_SHORT). show(); Log. d(TAG, "on. Receive action: "+intent. get. Action() ); } } } • http: //developer. android. com/training/monitoring-device-state/battery-monitoring. html Receiver, Firebase Cloud Messaging 17
La publication par Android ressemblerait à • android. os. Battery. Manager Intent broadcast. Intent = new Intent(); broadcast. Intent. set. Action("ACTION_BATTERY_CHANGED"); broadcast. Intent. put. Extra("level", 3567); // // // http: //developer. android. com/reference/android/os/Battery. Manager. html context. send. Broadcast(broadcast. Intent); Receiver, Firebase Cloud Messaging 18
Exemple 2 : réception d’un SMS // le souscripteur public class SMSReceiver extends Broadcast. Receiver{ @Override public void on. Receive(Context context, Intent intent) { Toast. make. Text(context, "sms received", Toast. LENGTH_SHORT). show(); } } Receiver, Firebase Cloud Messaging 19
Configuration du souscripteur, <receiver /> // Android. Manifest. xml // La souscription <receiver android: name=". SMSReceiver"> <intent-filter> <action android: name="android. intent. action. SMS_RECEIVED_ACTION"/> </intent-filter> </receiver> Souscription effectuée (appel implicite de register. Receiver) au chargement de l’application (unregister. Receiver lorsque l’application est détruite) Receiver, Firebase Cloud Messaging 20
Exemple 3: « un évènement utilisateur » • Ajout, retrait d’un « contrôleur » cf. MVC @Override public void on. Resume(){ super. on. Resume(); Intent. Filter intent. Filter = new Intent. Filter(); intent. Filter. add. Action(Controller. ACTION); register. Receiver(this. controller, intent. Filter); @Override public void on. Pause(){ super. on. Pause(); unregister. Receiver(this. controller); Avec Controller. ACTION public static final String ACTION = "fr. cnam. list. ITEMS"; Receiver, Firebase Cloud Messaging 21
La classe « Controller » , ici gestion d’une liste Le contrôleur agit sur le modèle, ici une liste (classe Items) public class Items. Controller extends Broadcast. Receiver { public static final String ACTION = "fr. cnam. list. ITEMS"; public static final String ADD public static final String REMOVE private Items items; private Context context; = "add"; = "remove"; // valeurs // le modèle // Android framework public Items. Controller(Context context, final Items items){ this. context = context; this. items = items; // le modèle } @Override public void on. Receive(final Context context, final Intent intent) { String operation = intent. get. String. Extra( OPERATION_KEY); if(operation. equals( ADD)) items. ajouter(intent. get. String. Extra( DATA_KEY)); else if(operation. equals( REMOVE)) items. retirer(Integer. parse. Int(intent. get. String. Extra(DATA_KEY))); } } Receiver, Firebase Cloud Messaging 22
Démonstration • Un des trois exemples • Le contrôleur • Optionnels: Intent. ACTION_BATTERY_CHANGED android. intent. action. SMS_RECEIVED_ACTION Receiver, Firebase Cloud Messaging 23
Firebase GCM • Firebase Google Cloud Messaging – Anciennement c 2 dm, Cloud to Delivering Message • >= Android 2. 2 • Message <= 4 ko • Trafic illimité – Nécessite une inscription auprès de Google • Avec de préférence un compte gmail que l’on dédiera à cet usage Receiver, Firebase Cloud Messaging 24
Avertissement • Firebase propose plusieurs modes de diffusion – https: //firebase. google. com/docs/cloud-messaging? authuser=1 • Ici seul est présenté le mode – Send topic messages sans identifier les destinataires • Souscription appel de Firebase. Messaging. get. Instance(). subscribe. Topic("weather") • Réception du message par un service android à installer Receiver, Firebase Cloud Messaging 25
Architecture : Objectifs Avec une authentification, Un certificat en JSON • Un client, tout système connecté – S’adresse au serveur Google qui se chargera de publier auprès des mobiles • Mobiles ayant préalablement souscrits • Mise en œuvre : une librairie toute prête, un appel de méthode suffit Receiver, Firebase Cloud Messaging 26
Deux façons parmi d’autres • Un thème (un nom) est partagé de tous (1) – Souscripteurs comme publieurs – Le plus simple, celui qui est en démonstration • Les identifiants de chaque abonné sont conservés (2) – Envoi sélectif de la notification – Nécessité d’un serveur web mémorisant les identifiants Receiver, Firebase Cloud Messaging 27
(1) Architecture : une simple publication GCM Publication sur un thème • Chaque participant – Doit avoir un compte google, appartient au même projet Receiver, Firebase Cloud Messaging 28
(1) Architecture : notification message • Chaque mobile ayant souscrit au thème est notifié – Un service prêt à l’emploi est créé afin de prendre en compte cette notification • Une de ses méthodes est alors appelée – (on. Message. Received) Receiver, Firebase Cloud Messaging 29
(2) Architecture : Mise en œuvre 1)inscription GCM 2)identifiant 3) dépôt de l’identifiant • Chaque participant • Un serveur mémorise, l’identifiant retourné par GCM – Doit avoir un compte google gmail – S’inscrit auprès de GCM, en retour un identifiant lui est attribué – Un serveur au protocole HTTP de préférence – Ces serveur contient les abonnés Receiver, Firebase Cloud Messaging 30
(2) Architecture : Mise en œuvre, inscriptions • • • id 1 id 2 id 3 … … … • Le serveur contient une liste des identifiants • Un identifiant par application – Application : un service sous Android Receiver, Firebase Cloud Messaging 31
(2) Architecture : publications 1) Demande de la liste 2) [id 1, id 2, id 3, ……] 3) Demande de publication [id 1, id 2, id 3, ……] + message id 1 id 2 message • id 3 Publication par tout système connecté 1, 2) Obtention de la liste des identifiants, des abonnés concernés 3) Envoi de cette liste au serveur Google/GCM accompagnée du message à transmettre GCM se charge de publier le message, de le ré-émettre, de le conserver … Receiver, Firebase Cloud Messaging 32
Démonstration pas à pas • Le projet Android Studio est ici – http: //douin. free. fr/SMB 116_firebase 2. zip • Publication/souscription depuis un mobile – Sources en partie extraites de • https: //medium. com/@That. Jen. Person/authenticating-firebase-cloud-messaging -http-v 1 -api-requests-e 9 af 3 e 0827 b 8 – Authenticating Firebase Cloud Messaging HTTP v 1 API Requests • Cf. la classe Messaging. SMB 116. java • Le projet j 2 se « bluej » de publication est ici – http: //douin. free. fr/Fire. Base. Publisher_bluej. jar • Publication depuis un PC/j 2 se – Permet de voir en clair les messages JSON envoyés Receiver, Firebase Cloud Messaging 33
Le tutorial que l’on se doit de lire • https: //firebase. google. com/docs/cloud-messaging/android/topicmessaging? authuser=1 Receiver, Firebase Cloud Messaging 34
Comment ? Création d’un projet auprès des serveurs Google 1. https: //console. firebase. google. com/u/1/ 2. En retour : dans les paramètres Receiver, Firebase Cloud Messaging 35
Messaging. java • Les constantes sont renseignées avec l’identifiant du projet, ligne 51 • URL de services web, publication, envoi sur un thème – Le thème fait partie du message – Celui-ci doit être authentifié Receiver, Firebase Cloud Messaging 36
Messaging. java, une connexion • get. Access. Token() : l’authentification – La publication est soumise à une authentification Une clef Diapositive suivante Receiver, Firebase Cloud Messaging 37
Obtention de la clef 1. https: //console. firebase. google. com/u/1/ 2. Paramètres puis Comptes de service, en bas de page Générer une nouvelle clé privée 3. Obtention du fichier JSON, cf. ci-dessous Receiver, Firebase Cloud Messaging 38
Messaging. java, un exemple d’envoi • build. Override. Message(), attention Diapositive suivante Receiver, Firebase Cloud Messaging 39
Notification ou non • Si certains paramètres sont présents dans le message, c’est le système Android qui intercepte le message et effectue la notification • Le service n’est pas appelé … • Lire – https: //firebase. google. com/docs/cloud-messaging/android/receive – https: //wajahatkarim. com/2018/05/firebase-notifications-in-background--foreground-in-android/ Receiver, Firebase Cloud Messaging 40
Souscription et abonnement Une démo Receiver, Firebase Cloud Messaging 41
Publication depuis un poste j 2 se • Envoi de ce message… – à destination de tous les souscripteurs au thème smb 116 Receiver, Firebase Cloud Messaging 42
Publication depuis un poste j 2 se • Envoi de ce message… – à destination de tous les souscripteurs au thème smb 116 – Interception par le système android i. e. présence de la clef notification Receiver, Firebase Cloud Messaging 43
Démonstration collaborative • 1) publication depuis un poste PC vers l’émulateur de mon poste au Cnam • 2) depuis vos émulateurs/mobiles • Lecture des sources pas à pas Receiver, Firebase Cloud Messaging 44
Une architecture possible, publication • De type MVC … une proposition pour discussions – Rappels: • Hypothèse – Un receveur et un service prêts à l’emploi » Ce service est appelé à chaque notification depuis le cloud » on. Message. Received, – A chaque réception d’un message, envoi de celui-ci vers le receveur concerné • • Un champ du message contient l’ACTION à déclencher … Les receveurs peuvent être locaux à une activité, un service … publish on. Message. Received(…) receveurs Receiver, Firebase Cloud Messaging 45
Réalisation, on. Message. Received • Émis directement au receveur concerné – intent. To. An. Controller(intent. From. Cloud. get. String. Extra(OPERATION_KEY)); Receiver, Firebase Cloud Messaging 46
Réalisation, une variante on. Message • Un contrôleur dédié au cloud est installé • Il est chargé de générer un journal, d’effectuer des statistiques, de contrôler… Receveur dédié au cloud publish on. Message(…) Receveur associé à l’ACTION Receiver, Firebase Cloud Messaging 47
Publication, le contrôleur dédié au cloud pourrait s’en charger… Receveur dédié au cloud PUBLISH ACTION publish • Publication vers le GCM via le contrôleur Receiver, Firebase Cloud Messaging 48
Une Application • Une liste partagée Receiver, Firebase Cloud Messaging 49
Architecture MVC, rappel • Application: – Une liste d’item : le modèle, du java standard, portable – List. View + List. Activity : la Vue – Un Receiver : le Contrôleur Receiver, Firebase Cloud Messaging 50
Android • Les outils nécessaires • Intent. Filter • Broadcast. Receiver – register. Receiver, Firebase Cloud Messaging 51
La vue, une liste d’items • Affichage • Opérations – d’ajout et de suppression Receiver, Firebase Cloud Messaging 52
La liste d’items • le modèle Items extends Observable • la vue Main. Activity extends List. Activity implements Observer le contrôleur Items. Controler Items. Controller extends Broadcast. Receiver • Items : le modèle • Main. Activity : la vue • Items. Controller : le contrôleur Receiver, Firebase Cloud Messaging 53
La classe Items : le modèle • Java J 2 SE portable – synchronized(this) par précaution (plusieurs contrôleurs) Receiver, Firebase Cloud Messaging 54
Architecture suite • Items : le modèle – extends java. util. Observable • Main. Activity : la vue – extends android. app. List. Activity implements java. util. Observer • Items. Controller : le contrôleur – extends android. content. Broadcast. Receiver, Firebase Cloud Messaging 55
Le contrôleur est un Broadcast. Receiver Items extends Observable Main. Activity extends List. Activity implements Observer send. Broadcast Items. Controler Items. Controller extends Broadcast. Receiver • A chaque Click send. Broadcast • • Intent intent = new Intent(); intent. set. Action(Items. Controller. ACTION); … send. Broadcast( Receiver, Firebase Cloud Messaging 56
Action de l’utilisateur, gérée par le contrôleur Main. Activity extends List. Activity implements Observer send. Broadcast Items. Controler Items. Controller extends Broadcast. Receiver • send. Broadcast Receiver, Firebase Cloud Messaging 57
Items. Controller • A chaque « clic » la méthode on. Receive est exécutée • abort. Broadcast(); si non cumul du comportement Receiver, Firebase Cloud Messaging 58
Contrôleur -> Modèle Items extends Observable Items. Controler Items. Controller extends Broadcast. Receiver • Appel de la méthode ajouter du modèle Receiver, Firebase Cloud Messaging 59
Modèle -> Vue Items extends Observable Main. Activity extends List. Activity implements Observer • La méthode update est déclenchée au sein de l’activité Receiver, Firebase Cloud Messaging 60
La Vue 1/4 initialisation • on. Create de l’activité – Création du modèle et du contrôleur Receiver, Firebase Cloud Messaging 61
La Vue 2/4 enregistrement du contrôleur • on. Resume de l’activité (ou on. Create, dépend de l’application) – enregistrement du contrôleur • on. Pause (ou on. Destroy) Receiver, Firebase Cloud Messaging 62
La Vue 3/4 A chaque clic ! • on. Click. Ajouter Receiver, Firebase Cloud Messaging 63
La Vue 4/4 update • update appelée par le modèle – (extends Observable) – La vue est un observateur( implements java. util. Observer) Receiver, Firebase Cloud Messaging 64
Cloud. Controller • Généralisation, discussions Receiver, Firebase Cloud Messaging 65
MVC • MVC respecté • Couplage faible conservé Items extends Observable • Au sein de la même application Main. Activity extends List. Activity Another. Activity implements Observer extends Activity implements Observer web, cloud Receiver, Firebase Cloud Messaging Items. Controller extends Broadcast. Receiver Cloud. Controller 66
Généralisation • MVC respecté • Couplage faible conservé Main. Activity extends List. Activity Another. Activity implements Observer extends Activity implements Observer web, cloud Items extends Observable Items. Controller extends Broadcast. Receiver Generic. Controller • Le champ Action sélectionne le contrôleur ad’hoc Receiver, Firebase Cloud Messaging 67
Generic. Controller Items. Controller extends Broadcast. Receiver • L’ACTION_KEY est redirigée vers le « bon » contrôleur • Discussion Receiver, Firebase Cloud Messaging 68
Cumul du comportement Items. Controller extends Broadcast. Receiver Items. Controller. Plus extends Items. Controller • Avec une sous classe de Items. Controller: Items. Controller. Plus @Override on. Receive(Context context, Intent intent){ super. on. Receive(context, intent); … … Receiver, Firebase Cloud Messaging 69
Conclusion Receiver, Firebase Cloud Messaging 70
- Slides: 70