Vzdálená oznámení pomocí služby Google Cloud Messaging

Upozorňující

Google od 10. dubna 2018 vyřadil GCM. Následující dokumenty a ukázkové projekty už nemusí být zachovány. Od 29. května 2019 dojde k odebrání serveru a klientských rozhraní API GCM společnosti Google. Google doporučuje migrovat aplikace GCM na Firebase Cloud Messaging (FCM). Další informace o vyřazení a migraci GCM najdete v tématu Google Cloud Messaging – ZASTARALÉ.

Pokud chcete začít používat vzdálená oznámení pomocí služby Firebase Cloud Messaging s Xamarinem, přečtěte si téma Vzdálená oznámení s FCM.

Tento názorný postup obsahuje podrobné vysvětlení toho, jak pomocí služby Google Cloud Messaging implementovat vzdálená oznámení (označovaná také jako nabízená oznámení) v aplikaci Xamarin.Android. Popisuje různé třídy, které je nutné implementovat pro komunikaci s Google Cloud Messaging (GCM), vysvětluje, jak nastavit oprávnění v manifestu Android pro přístup k GCM a ukazuje kompletní zasílání zpráv pomocí ukázkového testovacího programu.

Přehled oznámení GCM

V tomto názorném postupu vytvoříme aplikaci Xamarin.Android, která k implementaci vzdálených oznámení (označovaných také jako nabízená oznámení) používá Google Cloud Messaging (GCM). Implementujeme různé služby záměru a naslouchacího procesu, které používají GCM pro vzdálené zasílání zpráv, a otestujeme implementaci pomocí programu příkazového řádku, který simuluje aplikační server.

Než budete moct pokračovat v tomto návodu, musíte získat potřebné přihlašovací údaje pro použití serverů GCM společnosti Google; tento proces je vysvětlený ve službě Google Cloud Messaging. Konkrétně budete potřebovat klíč rozhraní API a ID odesílatele k vložení do ukázkového kódu uvedeného v tomto názorném postupu.

K vytvoření klientské aplikace Xamarin.Android s podporou GCM použijeme následující postup:

  1. Nainstalujte další balíčky potřebné pro komunikaci se servery GCM.
  2. Nakonfigurujte oprávnění aplikace pro přístup k serverům GCM.
  3. Implementujte kód pro kontrolu přítomnosti služeb Google Play.
  4. Implementujte službu záměru registrace, která vyjednává s GCM pro registrační token.
  5. Implementujte službu naslouchacího procesu ID instance, která naslouchá aktualizacím registračního tokenu z GCM.
  6. Implementujte službu naslouchacího procesu GCM, která přijímá vzdálené zprávy z aplikačního serveru prostřednictvím GCM.

Tato aplikace bude používat novou funkci GCM, která se označuje jako zasílání zpráv tématu. V tématu zasílání zpráv odešle aplikační server zprávu do tématu, nikoli do seznamu jednotlivých zařízení. Zařízení, která se přihlásí k odběru daného tématu, můžou přijímat zprávy témat jako nabízená oznámení.

Jakmile je klientská aplikace připravená, implementujeme aplikaci v jazyce C# příkazového řádku, která odešle nabízené oznámení do klientské aplikace prostřednictvím GCM.

Názorný postup

Začněme vytvořením nového prázdného řešení s názvem RemoteNotifications. V dalším kroku přidáme do tohoto řešení nový projekt pro Android, který je založený na šabloně aplikace pro Android. Pojďme volat tuto aplikaci ClientApp projektu. (Pokud nevíte, jak vytvářet projekty Xamarin.Android, přečtěte si téma Dobrý den, Android.) Projekt ClientApp bude obsahovat kód klientské aplikace Xamarin.Android, která přijímá vzdálená oznámení prostřednictvím GCM.

Přidání požadovaných balíčků

Než budeme moct implementovat kód klientské aplikace, musíme nainstalovat několik balíčků, které použijeme pro komunikaci s GCM. Také musíme přidat aplikaci Google Play Store do našeho zařízení, pokud ještě není nainstalovaná.

Přidání balíčku GCM služby Xamarin Google Play Services

Aby bylo možné přijímat zprávy ze služby Google Cloud Messaging, musí být na zařízení k dispozici architektura služeb Google Play. Bez této architektury nemůže aplikace pro Android přijímat zprávy ze serverů GCM. Služby Google Play běží na pozadí, zatímco zařízení s Androidem je zapnuté a tiše naslouchá zpráv z GCM. Když tyto zprávy dorazí, služba Google Play převede zprávy na záměry a pak tyto záměry vysílá aplikacím, které jsou pro ně zaregistrované.

V sadě Visual Studio klikněte pravým tlačítkem na Odkazy > Spravovat balíčky NuGet ...; v Visual Studio pro Mac klikněte pravým tlačítkem na Balíčky Přidat balíčky....> Vyhledejte služby Xamarin Google Play – GCM a nainstalujte tento balíček do projektu ClientApp:

Installing Google Play Services

Při instalaci Xamarin Google Play Services - GCM, Xamarin Google Play Services - Base se automaticky nainstaluje. Pokud se zobrazí chyba, změňte nastavení Minimální Android projektu na cílové nastavení na jinou hodnotu než Zkompilovat pomocí verze sady SDK a zkuste instalaci NuGet zopakovat.

Dále upravte MainActivity.cs a přidejte následující using příkazy:

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

To zpřístupňuje typy v balíčku GMS služeb Google Play pro náš kód a přidává funkce protokolování, které použijeme ke sledování našich transakcí pomocí GMS.

Google Play Store

Aby bylo možné přijímat zprávy z GCM, musí být na zařízení nainstalovaná aplikace Google Play Store. (Vždy, když je na zařízení nainstalovaná aplikace Google Play, nainstaluje se také Google Play Store, takže je pravděpodobné, že už je nainstalovaná na testovacím zařízení.) Bez Google Play nemůže aplikace pro Android přijímat zprávy ze služby GCM. Pokud ještě nemáte na svém zařízení nainstalovanou aplikaci Google Play Store, navštivte web Google Play a stáhněte a nainstalujte Google Play .

Alternativně můžete místo testovacího zařízení použít emulátor Androidu se systémem Android 2.2 nebo novějším (nemusíte instalovat Google Play Store na emulátor Androidu). Pokud ale používáte emulátor, musíte k připojení k GCM použít Wi-Fi a musíte otevřít několik portů v bráně Firewall Wi-Fi, jak je vysvětleno dále v tomto názorném postupu.

Nastavení názvu balíčku

Ve službě Google Cloud Messaging jsme pro naši aplikaci s podporou GCM zadali název balíčku (tento název balíčku slouží také jako ID aplikace přidružené k klíči rozhraní API a ID odesílatele). Pojďme otevřít vlastnosti projektu ClientApp a nastavit název balíčku na tento řetězec. V tomto příkladu nastavíme název balíčku na com.xamarin.gcmexample:

Setting the package name

Upozorňujeme, že klientská aplikace nebude moct získat registrační token od GCM, pokud tento název balíčku přesně neodpovídá názvu balíčku, který jsme zadali do konzoly Google Developer Console.

Přidání oprávnění do manifestu Androidu

Aplikace pro Android musí mít nakonfigurovaná následující oprávnění, aby mohl přijímat oznámení ze služby Google Cloud Messaging:

  • com.google.android.c2dm.permission.RECEIVE – Uděluje naší aplikaci oprávnění k registraci a přijímání zpráv z Google Cloud Messaging. (Co znamená c2dm ? To je zkratka pro zasílání zpráv typu Cloud to Device Messaging, což je nyní zastaralý předchůdce GCM. GCM stále používá c2dm v mnoha svých řetězcích oprávnění.)

  • android.permission.WAKE_LOCK – (Volitelné) Zabrání procesoru zařízení v přechodu do režimu spánku při naslouchání zprávy.

  • android.permission.INTERNET – Uděluje přístup k internetu, aby klientská aplikace mohl komunikovat s GCM.

  • .permission.C2D_MESSAGE package_name – Zaregistruje aplikaci v Androidu a požádá o oprávnění k výhradnímu příjmu všech zpráv C2D (cloud na zařízení). Předpona package_name je stejná jako ID vaší aplikace.

Tato oprávnění nastavíme v manifestu Androidu. Pojďme upravit AndroidManifest.xml a nahradit obsah následujícím kódem XML:

<?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>

Ve výše uvedeném kódu XML změňte YOUR_PACKAGE_NAME na název balíčku projektu klientské aplikace. Například com.xamarin.gcmexample.

Kontrola služeb Google Play

Pro účely tohoto názorného postupu vytváříme holou aplikaci s jedním TextView v uživatelském rozhraní. Tato aplikace přímo neindikuje interakci s GCM. Místo toho se podíváme na výstupní okno, abychom viděli, jak naše aplikace handshakes s GCM, a při příchodu zkontrolujeme oznamovací zásobník pro nová oznámení.

Nejprve vytvoříme rozložení pro oblast zprávy. Upravte Resources.layout.Main.axml a nahraďte obsah následujícím kódem XML:

<?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>

Uložte Soubor Main.axml a zavřete ho.

Když se klientská aplikace spustí, chceme, aby před pokusem o kontaktování služby GCM ověřila dostupnost služeb Google Play. Upravte MainActivity.cs a nahraďte count deklaraci proměnné instance následující deklarací proměnné instance:

TextView msgText;

Dále do třídy MainActivity přidejte následující metodu:

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;
    }
}

Tento kód zkontroluje zařízení a zjistí, jestli je nainstalován soubor APK služeb Google Play. Pokud není nainstalovaná, zobrazí se v oblasti zprávy zpráva, která uživateli dá pokyn ke stažení APK z Obchodu Google Play (nebo ji povolí v nastavení systému zařízení). Protože chceme tuto kontrolu spustit při spuštění klientské aplikace, přidáme volání této metody na konci OnCreate.

Dále nahraďte metodu OnCreate následujícím kódem:

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

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

    IsPlayServicesAvailable ();
}

Tento kód zkontroluje přítomnost apk služeb Google Play a zapíše výsledek do oblasti zprávy.

Pojďme aplikaci zcela znovu sestavit a spustit. Měla by se zobrazit obrazovka, která vypadá jako na následujícím snímku obrazovky:

Google Play Services is available

Pokud se vám tento výsledek nezobrazí, ověřte, že je na vašem zařízení nainstalován soubor APK služeb Google Play a že se do projektu ClientApp přidá balíček Xamarin Google Play Services – GCM, jak je vysvětleno výše. Pokud se zobrazí chyba sestavení, zkuste řešení vyčistit a znovu sestavit projekt.

Dále napíšeme kód pro kontaktování GCM a vrátíme registrační token.

Registrace pomocí GCM

Než může aplikace přijímat vzdálená oznámení ze serveru aplikace, musí se zaregistrovat v GCM a získat zpět registrační token. Činnost registrace aplikace v GCM se zpracovává vytvořením IntentService . Provedeme IntentService následující kroky:

  1. Pomocí rozhraní API PRO ID instance vygeneruje tokeny zabezpečení, které autorizuje naši klientskou aplikaci pro přístup k aplikačnímu serveru. Vrátíme zpět registrační token ze služby GCM.

  2. Předá registrační token aplikačnímu serveru (pokud ho aplikační server vyžaduje).

  3. Přihlásí se k odběru jednoho nebo více kanálů témat oznámení.

Po implementaci IntentServiceho otestujeme, abychom zjistili, jestli z GCM získáme registrační token.

Přidejte nový soubor s názvem RegistrationIntentService.cs a nahraďte kód šablony následujícím kódem:

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);
        }
    }
}

Ve výše uvedeném vzorovém kódu změňte YOUR_SENDER_ID na číslo ID odesílatele projektu klientské aplikace. Získání ID odesílatele pro váš projekt:

  1. Přihlaste se ke konzole Google Cloud Console a v rozevírací nabídce vyberte název projektu. V podokně Informace o projektu, které se zobrazí pro váš projekt, klikněte na Přejít do nastavení projektu:

    Selecting XamarinGCM project

  2. Na stránce Nastavení vyhledejte číslo projektu – toto je ID odesílatele pro váš projekt:

    Project number displayed

Chceme spustit naši RegistrationIntentService aplikaci, když se spustí naše aplikace. Upravte MainActivity.cs a upravte metodu OnCreate tak, aby byla RegistrationIntentService spuštěna po kontrole přítomnosti služeb 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);
    }
}

Teď se podíváme na jednotlivé části RegistrationIntentService , abychom pochopili, jak funguje.

Za prvé, anotujeme naši RegistrationIntentService pomocí následujícího atributu, který indikuje, že naše služba není vytvořena instancí systému:

[Service (Exported = false)]

Konstruktor RegistrationIntentService pojmenuje pracovní vlákno RegistrationIntentService , aby se usnadnilo ladění.

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

Základní funkce RegistrationIntentService se nacházejí v OnHandleIntent metodě. Pojďme si projít tento kód a podívat se, jak zaregistruje naši aplikaci v GCM.

Vyžádání registračního tokenu

OnHandleIntent Nejprve zavolá metodu InstanceID.GetToken společnosti Google, která požádá o registrační token z GCM. Tento kód zabalíme do lock ochrany před možností souběžného výskytu více záměrů registrace – lock zajistíme, aby se tyto záměry zpracovávaly postupně. Pokud se nám nepodaří získat registrační token, vyvolá se výjimka a zapíšeme chybu. Pokud registrace proběhne úspěšně, nastaví se na registrační token, token který jsme získali zpět z 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 ...

Předání registračního tokenu na aplikační server

Pokud získáme registrační token (to znamená, že se nevyvolá žádná výjimka), zavoláme SendRegistrationToAppServer , abychom přidružili registrační token uživatele k účtu na straně serveru (pokud existuje), který je udržován naší aplikací. Vzhledem k tomu, že tato implementace závisí na návrhu aplikačního serveru, je zde k dispozici prázdná metoda:

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

V některých případech aplikační server nepotřebuje registrační token uživatele; v takovém případě lze tuto metodu vynechat. Při odeslání registračního tokenu na aplikační server by měla být zachována logická hodnota označující, SendRegistrationToAppServer jestli se token odeslal na server. Pokud je tato logická hodnota false, SendRegistrationToAppServer odešle token na aplikační server – jinak se token už odeslal na aplikační server v předchozím volání.

Přihlášení k odběru tématu oznámení

Dále zavoláme metodu Subscribe , která označuje GCM, že se chceme přihlásit k odběru tématu oznámení. V Subscribezavoláme rozhraní API GcmPubSub.Subscribe, aby se naše klientská aplikace přihlásila k odběru všech zpráv v části /topics/global:

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

Pokud je budeme dostávat, musí aplikační server odesílat zprávy /topics/global s oznámením. Všimněte si, že název /topics tématu může být libovolný, pokud aplikační server i klientská aplikace souhlasí s těmito názvy. (Tady jsme zvolili název global , který označuje, že chceme přijímat zprávy na všech tématech podporovaných aplikačním serverem.)

Implementace služby naslouchacího procesu ID instance

Registrační tokeny jsou jedinečné a zabezpečené; Klientská aplikace (nebo GCM) ale může potřebovat aktualizovat registrační token v případě přeinstalace aplikace nebo problému se zabezpečením. Z tohoto důvodu musíme implementovat InstanceIdListenerService požadavek na aktualizaci tokenů z GCM.

Přidejte nový soubor s názvem InstanceIdListenerService.cs a nahraďte kód šablony následujícím kódem:

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);
        }
    }
}

Přidáním následujícího atributu označte InstanceIdListenerService , že služba není vytvořena instancí systému a že může přijímat žádosti o aktualizaci registračního tokenu GCM (označovaného také jako ID instance):

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

Metoda OnTokenRefresh v naší službě spustí RegistrationIntentService , aby mohl zachytit nový registrační token.

Testování registrace pomocí GCM

Pojďme aplikaci zcela znovu sestavit a spustit. Pokud úspěšně obdržíte registrační token z GCM, měl by se registrační token zobrazit v okně výstupu. Příklad:

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

Zpracování podřízených zpráv

Kód, který jsme zatím implementovali, je pouze "set-up" kód; zkontroluje, jestli je služba Google Play nainstalovaná a vyjednává s GCM a aplikačním serverem, aby připravila naši klientskou aplikaci na příjem vzdálených oznámení. Zatím ale musíme implementovat kód, který skutečně přijímá a zpracovává podřízené zprávy s oznámeními. K tomu musíme implementovat službu naslouchacího procesu GCM. Tato služba přijímá zprávy témat ze serveru aplikací a místně je vysílá jako oznámení. Po implementaci této služby vytvoříme testovací program pro odesílání zpráv do GCM, abychom zjistili, jestli naše implementace funguje správně.

Přidat ikonu oznámení

Nejdřív přidáme malou ikonu, která se při spuštění oznámení zobrazí v oznamovací oblasti. Tuto ikonu můžete zkopírovat do projektu nebo vytvořit vlastní ikonu. Soubor ikony pojmenujeme ic_stat_button_click.png a zkopírujeme ho do složky Resources/drawable . Nezapomeňte použít přidat > existující položku ... k zahrnutí tohoto souboru ikony do projektu.

Implementace služby naslouchacího procesu GCM

Přidejte nový soubor s názvem GcmListenerService.cs a nahraďte kód šablony následujícím kódem:

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());
        }
    }
}

Pojďme se podívat na jednotlivé části našeho oddílu GcmListenerService , abychom pochopili, jak to funguje.

Nejprve přidáme poznámkami GcmListenerService s atributem, který indikuje, že tato služba není vytvořena instancí systému, a zahrneme filtr záměru, který indikuje, že přijímá zprávy GCM:

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

Při GcmListenerService přijetí zprávy z GCM je OnMessageReceived vyvolána metoda. Tato metoda extrahuje obsah zprávy z předaného Bundle, zaznamená obsah zprávy (abychom ho mohli zobrazit v okně výstupu) a volání SendNotification pro spuštění místního oznámení s přijatým obsahem zprávy:

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

Metoda SendNotification používá Notification.Builder k vytvoření oznámení a pak použije NotificationManager k spuštění oznámení. V podstatě se tím převede vzdálená oznámení na místní oznámení, které se uživateli zobrazí. Další informace o použití Notification.Builder a naleznete v tématu Místní oznámeníNotificationManager.

Deklarace příjemce v manifestu

Než budeme moct přijímat zprávy z GCM, musíme deklarovat naslouchací proces GCM v manifestu Androidu. Pojďme upravit AndroidManifest.xml a nahradit <application> oddíl následujícím kódem XML:

<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>

Ve výše uvedeném kódu XML změňte YOUR_PACKAGE_NAME na název balíčku projektu klientské aplikace. V našem názorném příkladu je com.xamarin.gcmexamplenázev balíčku .

Pojďme se podívat, co dělá každé nastavení v tomto XML:

Nastavení Popis
com.google.android.gms.gcm.GcmReceiver Deklaruje, že naše aplikace implementuje příjemce GCM, který zachycuje a zpracovává příchozí zprávy nabízených oznámení.
com.google.android.c2dm.permission.SEND Deklaruje, že pouze servery GCM můžou odesílat zprávy přímo do aplikace.
com.google.android.c2dm.intent.RECEIVE Inzerce záměru filtruje, že naše aplikace zpracovává zprávy všesměrového vysílání z GCM.
com.google.android.c2dm.intent.REGISTRATION Inzerce záměru filtruje, že naše aplikace zpracovává nové záměry registrace (to znamená, že jsme implementovali službu naslouchacího procesu ID instance).

Alternativně můžete tyto atributy vyzdobit GcmListenerService a nezadávat je v jazyce XML. Tady je zadáme v AndroidManifest.xml , aby byly vzorky kódu snadnější sledovat.

Vytvoření odesílatele zprávy pro otestování aplikace

Pojďme do řešení přidat projekt desktopové konzolové aplikace C# a pojmenovat ho MessageSender. Tuto konzolovou aplikaci použijeme k simulaci aplikačního serveru – odešle zprávy s oznámeními do ClientAppu prostřednictvím GCM.

Přidání balíčku Json.NET

V této konzolové aplikaci vytváříme datovou část JSON, která obsahuje zprávu s oznámením, kterou chceme odeslat do klientské aplikace. Pomocí balíčku Json.NET ve MessageSenderu usnadníme sestavení objektu JSON vyžadovaného GCM. V sadě Visual Studio klikněte pravým tlačítkem na Odkazy > Spravovat balíčky NuGet ...; v Visual Studio pro Mac klikněte pravým tlačítkem na Balíčky Přidat balíčky....>

Pojďme vyhledat balíček Json.NET a nainstalovat ho do projektu:

Installing the Json.NET package

Přidání odkazu na System.Net.Http

Budeme také muset přidat odkaz, System.Net.Http abychom mohli vytvořit instanci HttpClient testovací zprávy do GCM. V projektu MessageSender klepněte pravým tlačítkem myši Přidat odkaz > a posuňte se dolů, dokud se nezobrazí System.Net.Http. Umístěte značku zaškrtnutí vedle system.Net.Http a klikněte na TLAČÍTKO OK.

Implementace kódu, který odešle testovací zprávu

Ve MessageSenderu upravte Program.cs a nahraďte obsah následujícím kódem:

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);
            }
        }
    }
}

Ve výše uvedeném kódu změňte YOUR_API_KEY na klíč rozhraní API pro projekt klientské aplikace.

Tento testovací aplikační server odešle do GCM následující zprávu ve formátu JSON:

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

GCM zase přepošla tuto zprávu do klientské aplikace. Pojďme vytvořit MessageSender a otevřít okno konzoly, kde ho můžeme spustit z příkazového řádku.

Můžete je vyzkoušejte.

Teď jsme připraveni otestovat naši klientskou aplikaci. Pokud používáte emulátor nebo pokud vaše zařízení komunikuje s GCM přes Wi-Fi, musíte v bráně firewall otevřít následující porty TCP, abyste mohli procházet zprávy GCM: 5228, 5229 a 5230.

Spusťte klientskou aplikaci a podívejte se na okno výstupu. RegistrationIntentService Po úspěšném přijetí registračního tokenu z GCM by mělo výstupní okno zobrazit token s výstupem protokolu, který se podobá následujícímu:

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

V tuto chvíli je klientská aplikace připravená k přijetí vzdálené zprávy s oznámením. Z příkazového řádku spusťte program MessageSender.exe , který odešle do klientské aplikace zprávu s oznámením "Hello, Xamarin". Pokud jste projekt MessageSender ještě nedefinovali, udělejte to teď.

Pokud chcete spustit MessageSender.exe v sadě Visual Studio, otevřete příkazový řádek, přejděte do adresáře MessageSender/bin/Debug a spusťte příkaz přímo:

MessageSender.exe

Pokud chcete spustit MessageSender.exe v Visual Studio pro Mac, otevřete terminálovou relaci, přejděte na MessageSender/bin/Debug adresář a pomocí mono spusťte MessageSender.exe

mono MessageSender.exe

Rozšíření zprávy prostřednictvím GCM a zpět do klientské aplikace může trvat až minutu. Pokud se zpráva úspěšně přijme, měli bychom vidět výstup podobný následujícímu v okně výstupu:

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

Kromě toho byste si měli všimnout, že se v oznamovací oblasti objevila nová ikona oznámení:

Notification icon appears on device

Když otevřete oznamovací panel pro zobrazení oznámení, měli byste vidět naše vzdálené oznámení:

Notification message is displayed

Blahopřejeme, vaše aplikace přijala první vzdálené oznámení!

Upozorňujeme, že pokud je aplikace vynuceně zastavena, zprávy GCM se už nebudou přijímat. Pokud chcete obnovit oznámení po vynucené zastavení, musí se aplikace ručně restartovat. Další informace o této zásadě pro Android najdete v tématu Spouštění ovládacích prvků u zastavených aplikací a tento příspěvek o přetečení zásobníku.

Shrnutí

Tento názorný postup podrobně popisuje postup implementace vzdálených oznámení v aplikaci Xamarin.Android. Popisuje, jak nainstalovat další balíčky potřebné pro komunikaci GCM a vysvětluje, jak nakonfigurovat oprávnění aplikace pro přístup k serverům GCM. Poskytuje ukázkový kód, který ukazuje, jak zjistit přítomnost služeb Google Play, jak implementovat službu naslouchacího procesu registrace a službu naslouchacího procesu ID instance, která vyjednává s GCM pro registrační token a jak implementovat službu naslouchacího procesu GCM, která přijímá a zpracovává zprávy vzdáleného oznámení. Nakonec jsme implementovali testovací program příkazového řádku pro odesílání testovacích oznámení do klientské aplikace prostřednictvím GCM.