Partager via


Notifications à distance avec Google Cloud Messaging

Avertissement

Google a déconseillé GCM depuis le 10 avril 2018. Les documents et exemples de projets suivants peuvent ne plus être conservés. Le serveur GCM et les API clientes de Google seront supprimées dès le 29 mai 2019. Google recommande de migrer des applications GCM vers Firebase Cloud Messaging (FCM). Pour plus d’informations sur la dépréciation et la migration de GCM, consultez Google Cloud Messaging - DEPRECATED.

Pour commencer à utiliser les notifications à distance à l’aide de Firebase Cloud Messaging avec Xamarin, consultez Notifications à distance avec FCM.

Cette procédure pas à pas fournit une explication pas à pas de l’utilisation de Google Cloud Messaging pour implémenter des notifications à distance (également appelées notifications Push) dans une application Xamarin.Android. Il décrit les différentes classes que vous devez implémenter pour communiquer avec Google Cloud Messaging (GCM), il explique comment définir des autorisations dans le manifeste Android pour l’accès à GCM, et il illustre la messagerie de bout en bout avec un exemple de programme de test.

Vue d’ensemble des notifications GCM

Dans cette procédure pas à pas, nous allons créer une application Xamarin.Android qui utilise Google Cloud Messaging (GCM) pour implémenter des notifications à distance (également appelées notifications Push). Nous allons implémenter les différents services d’intention et d’écouteur qui utilisent GCM pour la messagerie à distance, et nous allons tester notre implémentation avec un programme en ligne de commande qui simule un serveur d’applications.

Avant de pouvoir procéder à cette procédure pas à pas, vous devez acquérir les informations d’identification nécessaires pour utiliser les serveurs GCM de Google . ce processus est expliqué dans Google Cloud Messaging. En particulier, vous aurez besoin d’une clé API et d’un ID d’expéditeur à insérer dans l’exemple de code présenté dans cette procédure pas à pas.

Nous allons utiliser les étapes suivantes pour créer une application cliente Xamarin.Android avec GCM :

  1. Installez des packages supplémentaires requis pour les communications avec les serveurs GCM.
  2. Configurez les autorisations d’application pour l’accès aux serveurs GCM.
  3. Implémentez du code pour case activée pour la présence des services Google Play.
  4. Implémentez un service d’intention d’inscription qui négocie avec GCM un jeton d’inscription.
  5. Implémentez un service d’écouteur d’ID instance qui écoute les mises à jour des jetons d’inscription à partir de GCM.
  6. Implémentez un service d’écouteur GCM qui reçoit des messages distants du serveur d’applications via GCM.

Cette application utilisera une nouvelle fonctionnalité GCM appelée messagerie de rubrique. Dans la messagerie de rubrique, le serveur d’applications envoie un message à une rubrique plutôt qu’à une liste d’appareils individuels. Les appareils qui s’abonnent à cette rubrique peuvent recevoir des messages de rubrique sous forme de notifications Push.

Lorsque l’application cliente est prête, nous implémentons une application C# de ligne de commande qui envoie une notification Push à notre application cliente via GCM.

Procédure pas à pas

Pour commencer, créons une solution vide appelée RemoteNotifications. Ensuite, nous allons ajouter un nouveau projet Android à cette solution basé sur le modèle d’application Android . Appelons ce projet ClientApp. (Si vous n’êtes pas familiarisé avec la création de projets Xamarin.Android, consultez Hello, Android.) Le projet ClientApp contiendra le code de l’application cliente Xamarin.Android qui reçoit des notifications à distance via GCM.

Ajouter les packages requis

Avant de pouvoir implémenter le code de notre application cliente, nous devons installer plusieurs packages que nous utiliserons pour la communication avec GCM. En outre, nous devons ajouter l’application Google Play Store à notre appareil s’il n’est pas déjà installé.

Ajouter le package GCM Xamarin Google Play Services

Pour recevoir des messages de Google Cloud Messaging, l’infrastructure Des services Google Play doit être présente sur l’appareil. Sans cette infrastructure, une application Android ne peut pas recevoir de messages des serveurs GCM. Google Play Services s’exécute en arrière-plan pendant que l’appareil Android est sous tension, en écoutant silencieusement les messages de GCM. Lorsque ces messages arrivent, les services Google Play convertissent les messages en intentions, puis les diffusent aux applications qui s’y sont inscrites.

Dans Visual Studio, cliquez avec le bouton droit sur Références > Gérer les packages NuGet... ; dans Visual Studio pour Mac, cliquez avec le bouton droit sur Packages > Ajouter des packages.... Recherchez Xamarin Google Play Services - GCM et installez ce package dans le projet ClientApp :

Installation des services Google Play

Lorsque vous installez Xamarin Google Play Services - GCM, Xamarin Google Play Services - Base est automatiquement installé. Si vous obtenez une erreur, remplacez le paramètre Android minimum du projet pour le définir sur une valeur autre que Compiler à l’aide de la version du KIT de développement logiciel (SDK) et réessayez d’installer NuGet.

Ensuite, modifiez MainActivity.cs et ajoutez les instructions suivantes using :

using Android.Gms.Common;
using Android.Util;

Cela rend les types dans le package GMS des services Google Play disponibles pour notre code et ajoute une fonctionnalité de journalisation que nous utiliserons pour suivre nos transactions avec GMS.

Google Play Store

Pour recevoir des messages de GCM, l’application Google Play Store doit être installée sur l’appareil. (Chaque fois qu’une application Google Play est installée sur un appareil, Google Play Store est également installé. Il est donc probable qu’elle soit déjà installée sur votre appareil de test.) Sans Google Play, une application Android ne peut pas recevoir de messages de GCM. Si l’application Google Play Store n’est pas encore installée sur votre appareil, visitez le site web Google Play pour télécharger et installer Google Play.

Vous pouvez également utiliser un émulateur Android exécutant Android 2.2 ou version ultérieure au lieu d’un appareil de test (vous n’avez pas besoin d’installer Google Play Store sur un émulateur Android). Toutefois, si vous utilisez un émulateur, vous devez utiliser Wi-Fi pour vous connecter à GCM et vous devez ouvrir plusieurs ports dans votre pare-feu Wi-Fi, comme expliqué plus loin dans cette procédure pas à pas.

Définir le nom du package

Dans Google Cloud Messaging, nous avons spécifié un nom de package pour notre application avec GCM (ce nom de package sert également d’ID d’application associé à notre clé API et à notre ID d’expéditeur). Nous allons ouvrir les propriétés du projet ClientApp et définir le nom du package sur cette chaîne. Dans cet exemple, nous définissons le nom du package sur com.xamarin.gcmexample:

Définition du nom du package

Notez que l’application cliente ne pourra pas recevoir de jeton d’inscription de GCM si ce nom de package ne correspond pas exactement au nom du package que nous avons entré dans la console Google Developer.

Ajouter des autorisations au manifeste Android

Une application Android doit disposer des autorisations suivantes configurées pour pouvoir recevoir des notifications de Google Cloud Messaging :

  • com.google.android.c2dm.permission.RECEIVE – Octroie à notre application l’autorisation d’inscrire et de recevoir des messages de Google Cloud Messaging. (Qu’est-ce c2dm que cela signifie ? Il s’agit de Cloud to Device Messaging, qui est le prédécesseur désormais déprécié de GCM. GCM utilise c2dm toujours dans la plupart de ses chaînes d’autorisation.)

  • android.permission.WAKE_LOCK – (Facultatif) Empêche le processeur de l’appareil de se mettre en veille lors de l’écoute d’un message.

  • android.permission.INTERNET – Octroie l’accès Internet afin que l’application cliente puisse communiquer avec GCM.

  • .permission.C2D_MESSAGE package_name – Enregistre l’application auprès d’Android et demande l’autorisation de recevoir exclusivement tous les messages C2D (cloud à appareil). Le préfixe package_name est identique à l’ID de votre application.

Nous allons définir ces autorisations dans le manifeste Android. Nous allons modifier AndroidManifest.xml et remplacer le contenu par le code XML suivant :

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="YOUR_PACKAGE_NAME"
    android:versionCode="1"
    android:versionName="1.0"
    android:installLocation="auto">
    <uses-permission android:name="com.google.android.c2dm.permission.RECEIVE" />
    <uses-permission android:name="android.permission.WAKE_LOCK" />
    <uses-permission android:name="android.permission.INTERNET" />
    <uses-permission android:name="YOUR_PACKAGE_NAME.permission.C2D_MESSAGE" />
    <permission android:name="YOUR_PACKAGE_NAME.permission.C2D_MESSAGE"
                android:protectionLevel="signature" />
    <application android:label="ClientApp" android:icon="@drawable/Icon">
    </application>
</manifest>

Dans le code XML ci-dessus, remplacez YOUR_PACKAGE_NAME par le nom du package pour votre projet d’application cliente. Par exemple : com.xamarin.gcmexample.

Vérifier les services Google Play

Pour cette procédure pas à pas, nous créons une application complète avec un seul TextView dans l’interface utilisateur. Cette application n’indique pas directement l’interaction avec GCM. Au lieu de cela, nous allons watch la fenêtre de sortie pour voir comment notre application se connecte avec GCM, et nous allons case activée la barre d’état de notification pour les nouvelles notifications à mesure qu’elles arrivent.

Tout d’abord, créons une disposition pour la zone de message. Modifiez Resources.layout.Main.axml et remplacez le contenu par le code XML suivant :

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:orientation="vertical"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:padding="10dp">
    <TextView
        android:text=" "
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:id="@+id/msgText"
        android:textAppearance="?android:attr/textAppearanceMedium"
        android:padding="10dp" />
</LinearLayout>

Enregistrez Main.axml et fermez-le.

Lorsque l’application cliente démarre, nous voulons qu’elle vérifie que Google Play Services est disponible avant d’essayer de contacter GCM. Modifiez MainActivity.cs et remplacez la count déclaration de variable instance par la déclaration de variable instance suivante :

TextView msgText;

Ensuite, ajoutez la méthode suivante à la classe MainActivity :

public bool IsPlayServicesAvailable ()
{
    int resultCode = GoogleApiAvailability.Instance.IsGooglePlayServicesAvailable (this);
    if (resultCode != ConnectionResult.Success)
    {
        if (GoogleApiAvailability.Instance.IsUserResolvableError (resultCode))
            msgText.Text = GoogleApiAvailability.Instance.GetErrorString (resultCode);
        else
        {
            msgText.Text = "Sorry, this device is not supported";
            Finish ();
        }
        return false;
    }
    else
    {
        msgText.Text = "Google Play Services is available.";
        return true;
    }
}

Ce code vérifie l’appareil pour voir si l’APK des services Google Play est installé. S’il n’est pas installé, un message s’affiche dans la zone de message qui indique à l’utilisateur de télécharger un FICHIER APK à partir du Google Play Store (ou de l’activer dans les paramètres système de l’appareil). Étant donné que nous voulons exécuter cette case activée au démarrage de l’application cliente, nous allons ajouter un appel à cette méthode à la fin de OnCreate.

Ensuite, remplacez la OnCreate méthode par le code suivant :

protected override void OnCreate (Bundle bundle)
{
    base.OnCreate (bundle);

    SetContentView (Resource.Layout.Main);
    msgText = FindViewById<TextView> (Resource.Id.msgText);

    IsPlayServicesAvailable ();
}

Ce code vérifie la présence de l’APK Google Play Services et écrit le résultat dans la zone de message.

Nous allons complètement reconstruire et exécuter l’application. Vous devriez voir un écran qui ressemble à la capture d’écran suivante :

Google Play Services est disponible

Si vous n’obtenez pas ce résultat, vérifiez que l’APK Google Play Services est installé sur votre appareil et que le package Xamarin Google Play Services - GCM est ajouté à votre projet ClientApp , comme expliqué précédemment. Si vous obtenez une erreur de build, essayez de nettoyer la solution et de générer à nouveau le projet.

Ensuite, nous allons écrire du code pour contacter GCM et récupérer un jeton d’inscription.

S’inscrire auprès de GCM

Pour que l’application puisse recevoir des notifications à distance du serveur d’applications, elle doit s’inscrire auprès de GCM et récupérer un jeton d’inscription. Le travail d’inscription de notre application auprès de GCM est géré par un IntentService que nous créons. Notre IntentService effectue les étapes suivantes :

  1. Utilise l’API InstanceID pour générer des jetons de sécurité qui autorisent notre application cliente à accéder au serveur d’applications. En retour, nous récupérons un jeton d’inscription de GCM.

  2. Transfère le jeton d’inscription au serveur d’applications (si le serveur d’applications en a besoin).

  3. S’abonne à un ou plusieurs canaux de rubrique de notification.

Une fois que nous avons implémenté ce IntentService, nous le testerons pour voir si nous récupérons un jeton d’inscription de GCM.

Ajoutez un nouveau fichier appelé RegistrationIntentService.cs et remplacez le code de modèle par ce qui suit :

using System;
using Android.App;
using Android.Content;
using Android.Util;
using Android.Gms.Gcm;
using Android.Gms.Gcm.Iid;

namespace ClientApp
{
    [Service(Exported = false)]
    class RegistrationIntentService : IntentService
    {
        static object locker = new object();

        public RegistrationIntentService() : base("RegistrationIntentService") { }

        protected override void OnHandleIntent (Intent intent)
        {
            try
            {
                Log.Info ("RegistrationIntentService", "Calling InstanceID.GetToken");
                lock (locker)
                {
                    var instanceID = InstanceID.GetInstance (this);
                    var token = instanceID.GetToken (
                        "YOUR_SENDER_ID", GoogleCloudMessaging.InstanceIdScope, null);

                    Log.Info ("RegistrationIntentService", "GCM Registration Token: " + token);
                    SendRegistrationToAppServer (token);
                    Subscribe (token);
                }
            }
            catch (Exception e)
            {
                Log.Debug("RegistrationIntentService", "Failed to get a registration token");
                return;
            }
        }

        void SendRegistrationToAppServer (string token)
        {
            // Add custom implementation here as needed.
        }

        void Subscribe (string token)
        {
            var pubSub = GcmPubSub.GetInstance(this);
            pubSub.Subscribe(token, "/topics/global", null);
        }
    }
}

Dans l’exemple de code ci-dessus, remplacez YOUR_SENDER_ID par le numéro d’ID de l’expéditeur pour votre projet d’application cliente. Pour obtenir l’ID d’expéditeur de votre projet :

  1. Connectez-vous à la console Google Cloud et sélectionnez le nom de votre projet dans le menu déroulant. Dans le volet Informations sur le projet affiché pour votre projet, cliquez sur Accéder aux paramètres du projet :

    Sélection du projet XamarinGCM

  2. Dans la page Paramètres , recherchez le numéro du projet , il s’agit de l’ID d’expéditeur de votre projet :

    Numéro de projet affiché

Nous voulons démarrer notre RegistrationIntentService lorsque notre application commence à s’exécuter. Modifiez MainActivity.cs et modifiez la OnCreate méthode afin que notre RegistrationIntentService soit démarré après que nous avons case activée pour la présence des services Google Play :

protected override void OnCreate (Bundle bundle)
{
    base.OnCreate (bundle);

    SetContentView(Resource.Layout.Main);
    msgText = FindViewById<TextView> (Resource.Id.msgText);

    if (IsPlayServicesAvailable ())
    {
        var intent = new Intent (this, typeof (RegistrationIntentService));
        StartService (intent);
    }
}

Examinons maintenant chaque section de RegistrationIntentService pour comprendre son fonctionnement.

Tout d’abord, nous annoteons notre RegistrationIntentService avec l’attribut suivant pour indiquer que notre service ne doit pas être instancié par le système :

[Service (Exported = false)]

Le RegistrationIntentService constructeur nomme le thread de travail RegistrationIntentService pour faciliter le débogage.

public RegistrationIntentService() : base ("RegistrationIntentService") { }

La fonctionnalité de base de RegistrationIntentService réside dans la OnHandleIntent méthode . Parcourons ce code pour voir comment il inscrit notre application auprès de GCM.

Demander un jeton d’inscription

OnHandleIntent appelle d’abord la méthode InstanceID.GetToken de Google pour demander un jeton d’inscription à GCM. Nous encapsulons ce code dans un lock pour vous prémunir contre la possibilité que plusieurs intentions d’inscription se produisent simultanément, ce lock qui garantit que ces intentions sont traitées de manière séquentielle. Si nous ne parvenons pas à obtenir un jeton d’inscription, une exception est levée et nous enregistrons une erreur. Si l’inscription réussit, token est défini sur le jeton d’inscription que nous avons obtenu de GCM :

static object locker = new object ();
...
try
{
    lock (locker)
    {
        var instanceID = InstanceID.GetInstance (this);
        var token = instanceID.GetToken (
            "YOUR_SENDER_ID", GoogleCloudMessaging.InstanceIdScope, null);
        ...
    }
}
catch (Exception e)
{
    Log.Debug ...

Transférer le jeton d’inscription au serveur d’applications

Si nous obtenons un jeton d’inscription (autrement dit, aucune exception n’a été levée), nous appelons SendRegistrationToAppServer pour associer le jeton d’inscription de l’utilisateur au compte côté serveur (le cas échéant) qui est géré par notre application. Étant donné que cette implémentation dépend de la conception du serveur d’applications, une méthode vide est fournie ici :

void SendRegistrationToAppServer (string token)
{
    // Add custom implementation here as needed.
}

Dans certains cas, le serveur d’applications n’a pas besoin du jeton d’inscription de l’utilisateur ; dans ce cas, cette méthode peut être omise. Lorsqu’un jeton d’inscription est envoyé au serveur d’applications, SendRegistrationToAppServer doit conserver une valeur booléenne pour indiquer si le jeton a été envoyé au serveur. Si cette valeur booléenne est false, SendRegistrationToAppServer envoie le jeton au serveur d’applications. Sinon, le jeton a déjà été envoyé au serveur d’applications lors d’un appel précédent.

S’abonner à la rubrique notification

Ensuite, nous appelons notre Subscribe méthode pour indiquer à GCM que nous voulons nous abonner à une rubrique de notification. Dans Subscribe, nous appelons l’API GcmPubSub.Subscribe pour abonner notre application cliente à tous les messages sous /topics/global:

void Subscribe (string token)
{
    var pubSub = GcmPubSub.GetInstance(this);
    pubSub.Subscribe(token, "/topics/global", null);
}

Le serveur d’applications doit envoyer des messages de notification à /topics/global si nous voulons les recevoir. Notez que le nom de la rubrique sous /topics peut correspondre à ce que vous voulez, tant que le serveur d’applications et l’application cliente conviennent de ces noms. (Ici, nous avons choisi le nom global pour indiquer que nous voulons recevoir des messages sur toutes les rubriques prises en charge par le serveur d’applications.)

Implémenter un service d’écouteur d’ID d’instance

Les jetons d’inscription sont uniques et sécurisés ; toutefois, l’application cliente (ou GCM) peut avoir besoin d’actualiser le jeton d’inscription en cas de réinstallation de l’application ou d’un problème de sécurité. Pour cette raison, nous devons implémenter un qui répond aux demandes d’actualisation InstanceIdListenerService de jeton de GCM.

Ajoutez un nouveau fichier appelé InstanceIdListenerService.cs et remplacez le code de modèle par les éléments suivants :

using Android.App;
using Android.Content;
using Android.Gms.Gcm.Iid;

namespace ClientApp
{
    [Service(Exported = false), IntentFilter(new[] { "com.google.android.gms.iid.InstanceID" })]
    class MyInstanceIDListenerService : InstanceIDListenerService
    {
        public override void OnTokenRefresh()
        {
            var intent = new Intent (this, typeof (RegistrationIntentService));
            StartService (intent);
        }
    }
}

Annotez InstanceIdListenerService avec l’attribut suivant pour indiquer que le service ne doit pas être instancié par le système et qu’il peut recevoir des demandes d’actualisation de jeton d’inscription GCM (également appelé instance ID) :

[Service(Exported = false), IntentFilter(new[] { "com.google.android.gms.iid.InstanceID" })]

La OnTokenRefresh méthode dans notre service démarre afin RegistrationIntentService qu’elle puisse intercepter le nouveau jeton d’inscription.

Inscription des tests avec GCM

Nous allons complètement reconstruire et exécuter l’application. Si vous recevez un jeton d’inscription de GCM, le jeton d’inscription doit s’afficher dans la fenêtre de sortie. Par exemple :

D/Mono    ( 1934): Assembly Ref addref ClientApp[0xb4ac2400] -> Xamarin.GooglePlayServices.Gcm[0xb4ac2640]: 2
I/RegistrationIntentService( 1934): Calling InstanceID.GetToken
I/RegistrationIntentService( 1934): GCM Registration Token: f8LdveCvXig:APA91bFIsjUAbP-V8TPQdLR89qQbEJh1SYG38AcCbBUf34z5gSdUc5OsXrgs93YFiGcRSRafPfzkz23lf3-LvYV1CwrFheMjHgwPeFSh12MywnRIhz

Gérer les messages en aval

Le code que nous avons implémenté jusqu’à présent n’est que du code « configuré » ; il vérifie si Google Play Services est installé et négocie avec GCM et le serveur d’applications pour préparer notre application cliente à recevoir des notifications à distance. Toutefois, nous n’avons pas encore implémenté de code qui reçoit et traite réellement les messages de notification en aval. Pour ce faire, nous devons implémenter un service d’écouteur GCM. Ce service reçoit les messages de rubrique du serveur d’applications et les diffuse localement sous forme de notifications. Après avoir implémenté ce service, nous allons créer un programme de test pour envoyer des messages à GCM afin de voir si notre implémentation fonctionne correctement.

Ajouter une icône de notification

Ajoutons d’abord une petite icône qui apparaîtra dans la zone de notification lors du lancement de notre notification. Vous pouvez copier cette icône dans votre projet ou créer votre propre icône personnalisée. Nous allons nommer le fichier d’icône ic_stat_button_click.png et le copier dans le dossier Resources/drawable . N’oubliez pas d’utiliser Ajouter un > élément existant ... pour inclure ce fichier d’icônes dans votre projet.

Implémenter un service d’écouteur GCM

Ajoutez un nouveau fichier appelé GcmListenerService.cs et remplacez le code du modèle par les éléments suivants :

using Android.App;
using Android.Content;
using Android.OS;
using Android.Gms.Gcm;
using Android.Util;

namespace ClientApp
{
    [Service (Exported = false), IntentFilter (new [] { "com.google.android.c2dm.intent.RECEIVE" })]
    public class MyGcmListenerService : GcmListenerService
    {
        public override void OnMessageReceived (string from, Bundle data)
        {
            var message = data.GetString ("message");
            Log.Debug ("MyGcmListenerService", "From:    " + from);
            Log.Debug ("MyGcmListenerService", "Message: " + message);
            SendNotification (message);
        }

        void SendNotification (string message)
        {
            var intent = new Intent (this, typeof(MainActivity));
            intent.AddFlags (ActivityFlags.ClearTop);
            var pendingIntent = PendingIntent.GetActivity (this, 0, intent, PendingIntentFlags.OneShot);

            var notificationBuilder = new Notification.Builder(this)
                .SetSmallIcon (Resource.Drawable.ic_stat_ic_notification)
                .SetContentTitle ("GCM Message")
                .SetContentText (message)
                .SetAutoCancel (true)
                .SetContentIntent (pendingIntent);

            var notificationManager = (NotificationManager)GetSystemService(Context.NotificationService);
            notificationManager.Notify (0, notificationBuilder.Build());
        }
    }
}

Examinons chaque section de notre GcmListenerService pour comprendre son fonctionnement.

Tout d’abord, nous annoteons GcmListenerService avec un attribut pour indiquer que ce service ne doit pas être instancié par le système, et nous incluons un filtre d’intention pour indiquer qu’il reçoit des messages GCM :

[Service (Exported = false), IntentFilter (new [] { "com.google.android.c2dm.intent.RECEIVE" })]

Quand GcmListenerService reçoit un message de GCM, la OnMessageReceived méthode est appelée. Cette méthode extrait le contenu du message du message transmis Bundle, journalise le contenu du message (afin que nous puissions l’afficher dans la fenêtre de sortie) et appelle SendNotification pour lancer une notification locale avec le contenu du message reçu :

var message = data.GetString ("message");
Log.Debug ("MyGcmListenerService", "From:    " + from);
Log.Debug ("MyGcmListenerService", "Message: " + message);
SendNotification (message);

La SendNotification méthode utilise Notification.Builder pour créer la notification, puis elle utilise le NotificationManager pour lancer la notification. En fait, cela convertit le message de notification à distance en une notification locale à présenter à l’utilisateur. Pour plus d’informations sur l’utilisation Notification.Builder de et NotificationManager, consultez Notifications locales.

Déclarer le récepteur dans le manifeste

Avant de pouvoir recevoir des messages de GCM, nous devons déclarer l’écouteur GCM dans le manifeste Android. Nous allons modifier AndroidManifest.xml et remplacer la <application> section par le code XML suivant :

<application android:label="RemoteNotifications" android:icon="@drawable/Icon">
    <receiver android:name="com.google.android.gms.gcm.GcmReceiver"
              android:exported="true"
              android:permission="com.google.android.c2dm.permission.SEND">
        <intent-filter>
            <action android:name="com.google.android.c2dm.intent.RECEIVE" />
            <action android:name="com.google.android.c2dm.intent.REGISTRATION" />
            <category android:name="YOUR_PACKAGE_NAME" />
        </intent-filter>
    </receiver>
</application>

Dans le code XML ci-dessus, remplacez YOUR_PACKAGE_NAME par le nom du package pour votre projet d’application cliente. Dans notre exemple de procédure pas à pas, le nom du package est com.xamarin.gcmexample.

Examinons ce que fait chaque paramètre de ce code XML :

Paramètre Description
com.google.android.gms.gcm.GcmReceiver Déclare que notre application implémente un récepteur GCM qui capture et traite les messages de notification Push entrants.
com.google.android.c2dm.permission.SEND Déclare que seuls les serveurs GCM peuvent envoyer des messages directement à l’application.
com.google.android.c2dm.intent.RECEIVE Publicité de filtre d’intention selon laquelle notre application gère les messages diffusés à partir de GCM.
com.google.android.c2dm.intent.REGISTRATION Le filtre d’intention annonce que notre application gère les nouvelles intentions d’inscription (c’est-à-dire que nous avons implémenté un service d’écouteur d’ID d’instance).

Vous pouvez également décorer GcmListenerService avec ces attributs au lieu de les spécifier en XML ; ici, nous les spécifions dans AndroidManifest.xml afin que les exemples de code soient plus faciles à suivre.

Créer un expéditeur de message pour tester l’application

Ajoutons un projet d’application console de bureau C# à la solution et appelons-le MessageSender. Nous allons utiliser cette application console pour simuler un serveur d’applications : elle enverra des messages de notification à ClientApp via GCM.

Ajouter le package Json.NET

Dans cette application console, nous créons une charge utile JSON qui contient le message de notification que nous voulons envoyer à l’application cliente. Nous allons utiliser le package Json.NET dans MessageSender pour faciliter la création de l’objet JSON requis par GCM. Dans Visual Studio, cliquez avec le bouton droit sur Références > Gérer les packages NuGet... ; dans Visual Studio pour Mac, cliquez avec le bouton droit sur Packages > Ajouter des packages....

Nous allons rechercher le package Json.NET et l’installer dans le projet :

Installation du package Json.NET

Ajouter une référence à System.Net.Http

Nous devons également ajouter une référence à System.Net.Http afin de pouvoir instancier un pour envoyer notre message de HttpClient test à GCM. Dans le projet MessageSender , cliquez avec le bouton droit sur Références > Ajouter une référence et faites défiler jusqu’à ce que vous voyiez System.Net.Http. Placez une marque de case activée en regard de System.Net.Http, puis cliquez sur OK.

Implémenter le code qui envoie un message de test

Dans MessageSender, modifiez Program.cs et remplacez le contenu par le code suivant :

using System;
using System.Net.Http;
using System.Net.Http.Headers;
using System.Text;
using System.Threading.Tasks;
using Newtonsoft.Json.Linq;

namespace MessageSender
{
    class MessageSender
    {
        public const string API_KEY = "YOUR_API_KEY";
        public const string MESSAGE = "Hello, Xamarin!";

        static void Main (string[] args)
        {
            var jGcmData = new JObject();
            var jData = new JObject();

            jData.Add ("message", MESSAGE);
            jGcmData.Add ("to", "/topics/global");
            jGcmData.Add ("data", jData);

            var url = new Uri ("https://gcm-http.googleapis.com/gcm/send");
            try
            {
                using (var client = new HttpClient())
                {
                    client.DefaultRequestHeaders.Accept.Add(
                        new MediaTypeWithQualityHeaderValue("application/json"));

                    client.DefaultRequestHeaders.TryAddWithoutValidation (
                        "Authorization", "key=" + API_KEY);

                    Task.WaitAll(client.PostAsync (url,
                        new StringContent(jGcmData.ToString(), Encoding.Default, "application/json"))
                            .ContinueWith(response =>
                            {
                                Console.WriteLine(response);
                                Console.WriteLine("Message sent: check the client device notification tray.");
                            }));
                }
            }
            catch (Exception e)
            {
                Console.WriteLine("Unable to send GCM message:");
                Console.Error.WriteLine(e.StackTrace);
            }
        }
    }
}

Dans le code ci-dessus, remplacez YOUR_API_KEY par clé API pour votre projet d’application cliente.

Ce serveur d’applications de test envoie le message au format JSON suivant à GCM :

{
  "to": "/topics/global",
  "data": {
    "message": "Hello, Xamarin!"
  }
}

GCM, à son tour, transfère ce message à votre application cliente. Nous allons générer MessageSender et ouvrir une fenêtre de console dans laquelle nous pouvons l’exécuter à partir de la ligne de commande.

Essayez !

Nous sommes maintenant prêts à tester notre application cliente. Si vous utilisez un émulateur ou si votre appareil communique avec GCM via Wi-Fi, vous devez ouvrir les ports TCP suivants sur votre pare-feu pour que les messages GCM passent : 5228, 5229 et 5230.

Démarrez votre application cliente et watch la fenêtre de sortie. Une fois que le RegistrationIntentService a reçu avec succès un jeton d’inscription de GCM, la fenêtre de sortie doit afficher le jeton avec la sortie du journal semblable à ce qui suit :

I/RegistrationIntentService(16103): GCM Registration Token: eX9ggabZV1Q:APA91bHjBnQXMUeBOT6JDiLpRt8m2YWtY ...

À ce stade, l’application cliente est prête à recevoir un message de notification à distance. À partir de la ligne de commande, exécutez le programme MessageSender.exe pour envoyer un message de notification « Hello, Xamarin » à l’application cliente. Si vous n’avez pas encore créé le projet MessageSender , faites-le maintenant.

Pour exécuter MessageSender.exe sous Visual Studio, ouvrez une invite de commandes, accédez au répertoire MessageSender/bin/Debug , puis exécutez la commande directement :

MessageSender.exe

Pour exécuter MessageSender.exe sous Visual Studio pour Mac, ouvrez une session Terminal, passez à MessageSender/bin/Déboguer le répertoire et utilisez mono pour exécuter MessageSender.exe

mono MessageSender.exe

La propagation du message via GCM peut prendre jusqu’à une minute et revenir à votre application cliente. Si le message est reçu avec succès, la sortie doit ressembler à ce qui suit dans la fenêtre de sortie :

D/MyGcmListenerService(16103): From:    /topics/global
D/MyGcmListenerService(16103): Message: Hello, Xamarin!

En outre, vous devez remarquer qu’une nouvelle icône de notification s’est affichée dans la barre d’état des notifications :

Icône de notification s’affiche sur l’appareil

Lorsque vous ouvrez la barre d’état des notifications pour afficher les notifications, vous devez voir notre notification à distance :

Le message de notification s’affiche

Félicitations, votre application a reçu sa première notification à distance !

Notez que les messages GCM ne seront plus reçus si l’application est arrêtée de force. Pour reprendre les notifications après un arrêt forcé, l’application doit être redémarrée manuellement. Pour plus d’informations sur cette stratégie Android, consultez Lancer des contrôles sur les applications arrêtées et cette publication de dépassement de pile.

Résumé

Cette procédure pas à pas a détaillé les étapes d’implémentation des notifications à distance dans une application Xamarin.Android. Il décrit comment installer des packages supplémentaires nécessaires pour les communications GCM et explique comment configurer les autorisations d’application pour l’accès aux serveurs GCM. Il a fourni un exemple de code qui montre comment case activée pour la présence des services Google Play, comment implémenter un service d’intention d’inscription et instance service d’écouteur d’ID qui négocie avec GCM un jeton d’inscription, et comment implémenter un service d’écouteur GCM qui reçoit et traite les messages de notification à distance. Enfin, nous avons implémenté un programme de test en ligne de commande pour envoyer des notifications de test à notre application cliente via GCM.