Notifiche remote con Google Cloud Messaging
Avviso
Google deprecato GCM a partire dal 10 aprile 2018. I documenti e i progetti di esempio seguenti potrebbero non essere più mantenuti. Le API client e server GCM di Google verranno rimosse non appena il 29 maggio 2019. Google consiglia di eseguire la migrazione di app GCM a Firebase Cloud Messaging (FCM). Per altre informazioni sulla deprecazione e la migrazione di GCM, vedere Google Cloud Messaging - DEPRECATO.
Per iniziare a usare le notifiche remote con Firebase Cloud Messaging con Xamarin, vedere Remote Notifications with FCM (Notifiche remote con FCM).
Questa procedura dettagliata fornisce una spiegazione dettagliata di come usare Google Cloud Messaging per implementare notifiche remote (dette anche notifiche push) in un'applicazione Xamarin.Android. Descrive le varie classi che è necessario implementare per comunicare con Google Cloud Messaging (GCM), spiega come impostare le autorizzazioni nel manifesto Android per l'accesso a GCM e illustra la messaggistica end-to-end con un programma di test di esempio.
Panoramica delle notifiche GCM
In questa procedura dettagliata verrà creata un'applicazione Xamarin.Android che usa Google Cloud Messaging (GCM) per implementare le notifiche remote (note anche come notifiche push). Implementeremo i vari servizi intenti e listener che usano GCM per la messaggistica remota e testeremo l'implementazione con un programma da riga di comando che simula un server applicazioni.
Prima di poter procedere con questa procedura dettagliata, è necessario acquisire le credenziali necessarie per usare i server GCM di Google; questo processo è illustrato in Google Cloud Messaging. In particolare, sarà necessaria una chiave API e un ID mittente da inserire nel codice di esempio presentato in questa procedura dettagliata.
Verranno usati i passaggi seguenti per creare un'app client Xamarin.Android abilitata per GCM:
- Installare pacchetti aggiuntivi necessari per le comunicazioni con i server GCM.
- Configurare le autorizzazioni dell'app per l'accesso ai server GCM.
- Implementare il codice per verificare la presenza di Google Play Services.
- Implementare un servizio di finalità di registrazione che negozia con GCM per un token di registrazione.
- Implementare un servizio listener ID istanza in ascolto degli aggiornamenti del token di registrazione da GCM.
- Implementare un servizio listener GCM che riceve messaggi remoti dal server app tramite GCM.
Questa app userà una nuova funzionalità GCM nota come messaggistica degli argomenti. Nella messaggistica dell'argomento il server app invia un messaggio a un argomento, anziché a un elenco di singoli dispositivi. I dispositivi che sottoscrivono tale argomento possono ricevere messaggi di argomento come notifiche push.
Quando l'app client è pronta, verrà implementata un'applicazione C# della riga di comando che invia una notifica push all'app client tramite GCM.
scenario
Per iniziare, creare una nuova soluzione vuota denominata RemoteNotifications. Aggiungere quindi un nuovo progetto Android a questa soluzione basato sul modello App Android. Chiamare questo progetto ClientApp. Se non si ha familiarità con la creazione di progetti Xamarin.Android, vedere Hello, Android.) Il progetto ClientApp conterrà il codice per l'applicazione client Xamarin.Android che riceve notifiche remote tramite GCM.
Aggiungere pacchetti obbligatori
Prima di poter implementare il codice dell'app client, è necessario installare diversi pacchetti che verranno usati per la comunicazione con GCM. Inoltre, è necessario aggiungere l'applicazione Google Play Store al dispositivo, se non è già installata.
Aggiungere il pacchetto GCM di Xamarin Google Play Services
Per ricevere messaggi da Google Cloud Messaging, il framework di Google Play Services deve essere presente nel dispositivo. Senza questo framework, un'applicazione Android non può ricevere messaggi dai server GCM. Google Play Services viene eseguito in background mentre il dispositivo Android è acceso, ascoltando tranquillamente i messaggi da GCM. Quando arrivano questi messaggi, Google Play Services converte i messaggi nelle finalità e quindi trasmette queste finalità alle applicazioni registrate per loro.
In Visual Studio fare clic con il pulsante destro del mouse su Riferimenti > gestisci pacchetti NuGet ...; in Visual Studio per Mac fare clic con il pulsante destro del mouse su Pacchetti Aggiungi pacchetti>.... Cercare Xamarin Google Play Services - GCM e installare questo pacchetto nel progetto ClientApp:
Quando si installa Xamarin Google Play Services - GCM, Xamarin Google Play Services - Base viene installato automaticamente. Se viene visualizzato un errore, modificare l'impostazione Minimum Android (Android minimo) del progetto impostando come destinazione un valore diverso da Compile using SDK version (Compila usando la versione dell'SDK) e riprovare a installare NuGet.
Modificare quindi MainActivity.cs e aggiungere le istruzioni seguenti using
:
using Android.Gms.Common;
using Android.Util;
In questo modo i tipi nel pacchetto GMS di Google Play Services sono disponibili per il codice e aggiungono funzionalità di registrazione che useremo per tenere traccia delle transazioni con GMS.
Google Play Store
Per ricevere messaggi da GCM, è necessario installare l'applicazione Google Play Store nel dispositivo. Ogni volta che viene installata un'applicazione Google Play in un dispositivo, google Play Store viene installato anche, quindi è probabile che sia già installato nel dispositivo di test. Senza Google Play, un'applicazione Android non può ricevere messaggi da GCM. Se non hai ancora installato l'app Google Play Store sul tuo dispositivo, visita il sito Web di Google Play per scaricare e installare Google Play .
In alternativa, è possibile usare un emulatore Android che esegue Android 2.2 o versione successiva anziché un dispositivo di test (non è necessario installare Google Play Store in un emulatore Android). Tuttavia, se usi un emulatore, devi usare Wi-Fi per connettersi a GCM e devi aprire diverse porte nel firewall Wi-Fi, come illustrato più avanti in questa procedura dettagliata.
Impostare il nome del pacchetto
In Google Cloud Messaging è stato specificato un nome di pacchetto per l'app abilitata per GCM (questo nome del pacchetto funge anche da ID applicazione associato alla chiave API e all'ID mittente). Aprire le proprietà per il progetto ClientApp e impostare il nome del pacchetto su questa stringa. In questo esempio il nome del pacchetto viene impostato su com.xamarin.gcmexample
:
Si noti che l'app client non sarà in grado di ricevere un token di registrazione da GCM se questo nome del pacchetto non corrisponde esattamente al nome del pacchetto immesso nella console di Google Developer.
Aggiungere autorizzazioni al manifesto Android
Un'applicazione Android deve disporre delle autorizzazioni seguenti configurate prima di poter ricevere notifiche da Google Cloud Messaging:
com.google.android.c2dm.permission.RECEIVE
– Concede l'autorizzazione all'app per registrare e ricevere messaggi da Google Cloud Messaging. (Cosac2dm
significa? Questo è l'acronimo di Cloud to Device Messaging, che è il predecessore ora deprecato di GCM. GCM usac2dm
ancora in molte delle stringhe di autorizzazione.android.permission.WAKE_LOCK
– (Facoltativo) Impedisce la sospensione della CPU del dispositivo durante l'ascolto di un messaggio.android.permission.INTERNET
– Concede l'accesso a Internet in modo che l'app client possa comunicare con GCM..permission.C2D_MESSAGE
package_name: registra l'applicazione con Android e richiede l'autorizzazione per ricevere esclusivamente tutti i messaggi C2D (da cloud a dispositivo). Il prefisso package_name corrisponde all'ID applicazione.
Queste autorizzazioni verranno impostate nel manifesto Android. È possibile modificare AndroidManifest.xml e sostituire il contenuto con il codice XML seguente:
<?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>
Nel codice XML precedente modificare YOUR_PACKAGE_NAME con il nome del pacchetto per il progetto dell'app client. Ad esempio: com.xamarin.gcmexample
.
Verificare la presenza di Google Play Services
Per questa procedura dettagliata viene creata un'app bare-bones con un'unica TextView
nell'interfaccia utente. Questa app non indica direttamente l'interazione con GCM. Si osserverà invece la finestra di output per vedere come l'handshake dell'app con GCM e si verificherà la presenza di nuove notifiche nella barra delle notifiche man mano che arrivano.
Creare prima di tutto un layout per l'area dei messaggi. Modificare Resources.layout.Main.axml e sostituire il contenuto con il codice XML seguente:
<?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>
Salvare Main.axml e chiuderlo.
All'avvio dell'app client, è necessario verificare che Google Play Services sia disponibile prima di tentare di contattare GCM. Modificare MainActivity.cs e sostituire la dichiarazione della count
variabile di istanza con la dichiarazione di variabile di istanza seguente:
TextView msgText;
Aggiungere quindi il metodo seguente alla 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;
}
}
Questo codice controlla il dispositivo per verificare se è installato l'APK di Google Play Services. Se non è installato, viene visualizzato un messaggio nell'area dei messaggi che indica all'utente di scaricare un APK da Google Play Store (o abilitarlo nelle impostazioni di sistema del dispositivo). Poiché si vuole eseguire questo controllo all'avvio dell'app client, si aggiungerà una chiamata a questo metodo alla fine di OnCreate
.
Sostituire quindi il OnCreate
metodo con il codice seguente:
protected override void OnCreate (Bundle bundle)
{
base.OnCreate (bundle);
SetContentView (Resource.Layout.Main);
msgText = FindViewById<TextView> (Resource.Id.msgText);
IsPlayServicesAvailable ();
}
Questo codice verifica la presenza dell'APK di Google Play Services e scrive il risultato nell'area dei messaggi.
Ricompilare ed eseguire completamente l'app. Verrà visualizzata una schermata simile alla schermata seguente:
Se non si ottiene questo risultato, verificare che l'APK di Google Play Services sia installato nel dispositivo e che il pacchetto Xamarin Google Play Services - GCM venga aggiunto al progetto ClientApp come illustrato in precedenza. Se viene visualizzato un errore di compilazione, provare a pulire la soluzione e compilare di nuovo il progetto.
Successivamente, si scriverà il codice per contattare GCM e si otterrà un token di registrazione.
Registrarsi con GCM
Prima che l'app possa ricevere notifiche remote dal server app, deve registrarsi con GCM e ottenere un token di registrazione. Il lavoro di registrazione dell'applicazione con GCM viene gestito da un oggetto IntentService
creato. La IntentService
procedura seguente viene eseguita:
Usa l'API InstanceID per generare token di sicurezza che autorizzano l'app client ad accedere al server app. In cambio, viene restituito un token di registrazione da GCM.
Inoltra il token di registrazione al server app (se il server app lo richiede).
Sottoscrive uno o più canali di argomenti di notifica.
Dopo l'implementazione di , IntentService
verrà testato per verificare se viene restituito un token di registrazione da GCM.
Aggiungere un nuovo file denominato RegistrationIntentService.cs e sostituire il codice del modello con quanto segue:
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);
}
}
}
Nel codice di esempio precedente modificare YOUR_edizione Standard NDER_ID in Numero ID mittente per il progetto dell'app client. Per ottenere l'ID mittente per il progetto:
Accedere a Google Cloud Console e selezionare il nome del progetto dal menu a discesa. Nel riquadro Informazioni progetto visualizzato per il progetto fare clic su Vai alle impostazioni del progetto:
Nella pagina Impostazioni individuare il numero di progetto, ovvero l'ID mittente per il progetto:
Si vuole avviare l'app all'avvio RegistrationIntentService
dell'esecuzione. Modifica MainActivity.cs e modifica il OnCreate
metodo in modo che il nostro RegistrationIntentService
venga avviato dopo aver verificato la presenza di Google Play Services:
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);
}
}
Si esaminerà ora ogni sezione di RegistrationIntentService
per comprendere il funzionamento.
Prima di tutto, viene annotato RegistrationIntentService
con l'attributo seguente per indicare che il servizio non deve essere creata un'istanza dal sistema:
[Service (Exported = false)]
Il RegistrationIntentService
costruttore assegna un nome al thread di lavoro RegistrationIntentService per semplificare il debug.
public RegistrationIntentService() : base ("RegistrationIntentService") { }
La funzionalità di base di RegistrationIntentService
risiede nel OnHandleIntent
metodo . Esaminiamo questo codice per vedere come registra l'app con GCM.
Richiedere un token di registrazione
OnHandleIntent
chiama prima il metodo InstanceID.GetToken di Google per richiedere un token di registrazione da GCM. Questo codice viene eseguito in modo lock
da evitare la possibilità che si verifichino più finalità di registrazione contemporaneamente, lock
assicurando che queste finalità vengano elaborate in sequenza. Se non si ottiene un token di registrazione, viene generata un'eccezione e viene registrato un errore. Se la registrazione ha esito positivo, token
viene impostata sul token di registrazione restituito da 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 ...
Inoltrare il token di registrazione al server app
Se si ottiene un token di registrazione (ovvero non è stata generata alcuna eccezione), viene chiamato SendRegistrationToAppServer
per associare il token di registrazione dell'utente all'account lato server (se presente) gestito dall'applicazione. Poiché questa implementazione dipende dalla progettazione del server app, viene fornito un metodo vuoto qui:
void SendRegistrationToAppServer (string token)
{
// Add custom implementation here as needed.
}
In alcuni casi, il server app non necessita del token di registrazione dell'utente; in tal caso, questo metodo può essere omesso. Quando un token di registrazione viene inviato al server app, SendRegistrationToAppServer
deve mantenere un valore booleano per indicare se il token è stato inviato al server. Se questo valore booleano è false, SendRegistrationToAppServer
invia il token al server app. In caso contrario, il token è già stato inviato al server app in una chiamata precedente.
Sottoscrivere l'argomento di notifica
Successivamente, viene chiamato il Subscribe
metodo per indicare a GCM che si vuole sottoscrivere un argomento di notifica. In Subscribe
viene chiamato l'API GcmPubSub.Subscribe per sottoscrivere l'app client a tutti i messaggi in /topics/global
:
void Subscribe (string token)
{
var pubSub = GcmPubSub.GetInstance(this);
pubSub.Subscribe(token, "/topics/global", null);
}
Il server app deve inviare messaggi di notifica a /topics/global
se devono essere ricevuti. Si noti che il nome dell'argomento in /topics
può essere qualsiasi elemento desiderato, purché il server app e l'app client siano entrambi d'accordo su questi nomi. In questo caso è stato scelto il nome global
per indicare che si vogliono ricevere messaggi in tutti gli argomenti supportati dal server app.
Implementare un servizio listener ID istanza
I token di registrazione sono univoci e sicuri; Tuttavia, l'app client (o GCM) potrebbe dover aggiornare il token di registrazione in caso di reinstallazione dell'app o di un problema di sicurezza. Per questo motivo, è necessario implementare un oggetto InstanceIdListenerService
che risponde alle richieste di aggiornamento dei token da GCM.
Aggiungere un nuovo file denominato InstanceIdListenerService.cs e sostituire il codice del modello con quanto segue:
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);
}
}
}
Annotare InstanceIdListenerService
con l'attributo seguente per indicare che il servizio non deve essere creata un'istanza dal sistema e che può ricevere richieste di aggiornamento del token di registrazione GCM (detto anche ID istanza):
[Service(Exported = false), IntentFilter(new[] { "com.google.android.gms.iid.InstanceID" })]
Il OnTokenRefresh
metodo nel servizio avvia in RegistrationIntentService
modo che possa intercettare il nuovo token di registrazione.
Testare la registrazione con GCM
Ricompilare ed eseguire completamente l'app. Se si riceve correttamente un token di registrazione da GCM, il token di registrazione deve essere visualizzato nella finestra di output. Ad esempio:
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
Gestire i messaggi downstream
Il codice implementato finora è solo codice "set-up" ; verifica se Google Play Services è installato e negozia con GCM e il server app per preparare l'app client per la ricezione di notifiche remote. Tuttavia, è ancora necessario implementare il codice che riceve ed elabora effettivamente i messaggi di notifica downstream. A tale scopo, è necessario implementare un servizio listener GCM. Questo servizio riceve messaggi di argomento dal server app e li trasmette in locale come notifiche. Dopo aver implementato questo servizio, verrà creato un programma di test per inviare messaggi a GCM in modo che sia possibile verificare se l'implementazione funziona correttamente.
Aggiungere un'icona di notifica
Aggiungere prima di tutto un'icona piccola che verrà visualizzata nell'area di notifica all'avvio della notifica. È possibile copiare questa icona nel progetto o creare un'icona personalizzata. Il file icona verrà denominato ic_stat_button_click.png e copiarlo nella cartella Resources/drawable . Ricordarsi di usare Aggiungi > elemento esistente ... per includere questo file icona nel progetto.
Implementare un servizio listener GCM
Aggiungere un nuovo file denominato GcmListenerService.cs e sostituire il codice del modello con il codice seguente:
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());
}
}
}
Esaminiamo ogni sezione del nostro GcmListenerService
per capire come funziona.
Prima di tutto, viene annotato GcmListenerService
con un attributo per indicare che questo servizio non deve essere creata un'istanza dal sistema e viene incluso un filtro finalità per indicare che riceve messaggi GCM:
[Service (Exported = false), IntentFilter (new [] { "com.google.android.c2dm.intent.RECEIVE" })]
Quando GcmListenerService
riceve un messaggio da GCM, viene richiamato il OnMessageReceived
metodo . Questo metodo estrae il contenuto del messaggio dal passato Bundle
, registra il contenuto del messaggio (in modo da poterlo visualizzare nella finestra di output) e chiama SendNotification
per avviare una notifica locale con il contenuto del messaggio ricevuto:
var message = data.GetString ("message");
Log.Debug ("MyGcmListenerService", "From: " + from);
Log.Debug ("MyGcmListenerService", "Message: " + message);
SendNotification (message);
Il SendNotification
metodo usa Notification.Builder
per creare la notifica e quindi usa per NotificationManager
avviare la notifica. In effetti, questo converte il messaggio di notifica remota in una notifica locale da presentare all'utente.
Per altre informazioni sull'uso Notification.Builder
di e NotificationManager
, vedere Notifiche locali.
Dichiarare il ricevitore nel manifesto
Prima di poter ricevere messaggi da GCM, è necessario dichiarare il listener GCM nel manifesto Android. Modificare AndroidManifest.xml e sostituire la <application>
sezione con il codice XML seguente:
<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>
Nel codice XML precedente modificare YOUR_PACKAGE_NAME con il nome del pacchetto per il progetto dell'app client. Nell'esempio di procedura dettagliata il nome del pacchetto è com.xamarin.gcmexample
.
Verranno ora esaminate le operazioni che ogni impostazione in questo codice XML esegue:
Impostazione | Descrizione |
---|---|
com.google.android.gms.gcm.GcmReceiver |
Dichiara che l'app implementa un ricevitore GCM che acquisisce ed elabora i messaggi di notifica push in ingresso. |
com.google.android.c2dm.permission.SEND |
Dichiara che solo i server GCM possono inviare messaggi direttamente all'app. |
com.google.android.c2dm.intent.RECEIVE |
Filtro finalità pubblicità che l'app gestisce i messaggi trasmessi da GCM. |
com.google.android.c2dm.intent.REGISTRATION |
Annunci di filtro finalità che l'app gestisce le nuove finalità di registrazione, ovvero è stato implementato un servizio listener ID istanza. |
In alternativa, è possibile decorare GcmListenerService
con questi attributi anziché specificarli in XML. In questo caso vengono specificati in AndroidManifest.xml in modo che gli esempi di codice siano più facili da seguire.
Creare un mittente di messaggi per testare l'app
Aggiungere ora un progetto di applicazione console desktop C# alla soluzione e chiamarlo MessageSender. Questa applicazione console verrà usata per simulare un server applicazioni, che invierà messaggi di notifica a ClientApp tramite GCM.
Aggiungere il pacchetto Json.NET
In questa app console si sta creando un payload JSON che contiene il messaggio di notifica che si vuole inviare all'app client. Verrà usato il pacchetto Json.NET in MessageSender per semplificare la compilazione dell'oggetto JSON richiesto da GCM. In Visual Studio fare clic con il pulsante destro del mouse su Riferimenti > gestisci pacchetti NuGet ...; in Visual Studio per Mac fare clic con il pulsante destro del mouse su Pacchetti Aggiungi pacchetti>....
Cercare il pacchetto Json.NET e installarlo nel progetto:
Aggiungere un riferimento a System.Net.Http
Sarà anche necessario aggiungere un riferimento a System.Net.Http
in modo che sia possibile creare un'istanza HttpClient
di per inviare il messaggio di test a GCM. Nel progetto MessageSender fare clic con il pulsante destro del mouse su Riferimenti > Aggiungi riferimento e scorrere verso il basso fino a visualizzare System.Net.Http. Inserire un segno di spunta accanto a System.Net.Http e fare clic su OK.
Implementare il codice che invia un messaggio di test
In MessageSender modificare Program.cs e sostituire il contenuto con il codice seguente:
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);
}
}
}
}
Nel codice precedente modificare YOUR_API_KEY alla chiave API per il progetto dell'app client.
Questo server dell'app di test invia il seguente messaggio in formato JSON a GCM:
{
"to": "/topics/global",
"data": {
"message": "Hello, Xamarin!"
}
}
GCM, a sua volta, inoltra questo messaggio all'app client. Compilare MessageSender e aprire una finestra della console in cui è possibile eseguirla dalla riga di comando.
Prova
A questo momento è possibile testare l'app client. Se si usa un emulatore o se il dispositivo comunica con GCM tramite Wi-Fi, è necessario aprire le porte TCP seguenti sul firewall per ottenere i messaggi GCM: 5228, 5229 e 5230.
Avviare l'app client e controllare la finestra di output. Dopo aver RegistrationIntentService
ricevuto correttamente un token di registrazione da GCM, la finestra di output dovrebbe visualizzare il token con output del log simile al seguente:
I/RegistrationIntentService(16103): GCM Registration Token: eX9ggabZV1Q:APA91bHjBnQXMUeBOT6JDiLpRt8m2YWtY ...
A questo punto l'app client è pronta per ricevere un messaggio di notifica remota. Dalla riga di comando eseguire il programma MessageSender.exe per inviare un messaggio di notifica "Hello, Xamarin" all'app client. Se il progetto MessageSender non è ancora stato compilato, procedere ora.
Per eseguire MessageSender.exe in Visual Studio, aprire un prompt dei comandi, passare alla directory MessageSender/bin/Debug ed eseguire il comando direttamente:
MessageSender.exe
Per eseguire MessageSender.exe in Visual Studio per Mac, aprire una sessione terminale, passare a MessageSender/bin/Debug della directory e usare mono per eseguire MessageSender.exe
mono MessageSender.exe
La propagazione del messaggio tramite GCM e il backup nell'app client potrebbero essere necessari fino a un minuto. Se il messaggio viene ricevuto correttamente, verrà visualizzato un output simile al seguente nella finestra di output:
D/MyGcmListenerService(16103): From: /topics/global
D/MyGcmListenerService(16103): Message: Hello, Xamarin!
È inoltre necessario notare che nella barra delle notifiche è presente una nuova icona di notifica:
Quando si apre la barra delle notifiche per visualizzare le notifiche, verrà visualizzata la notifica remota:
Congratulazioni, l'app ha ricevuto la prima notifica remota.
Si noti che i messaggi GCM non verranno più ricevuti se l'app viene arrestata forzatamente. Per riprendere le notifiche dopo un arresto forzato, l'app deve essere riavviata manualmente. Per altre informazioni su questo criterio Android, vedere Avviare i controlli nelle applicazioni arrestate e questo post di overflow dello stack.
Riepilogo
Questa procedura dettagliata illustra in dettaglio i passaggi per l'implementazione di notifiche remote in un'applicazione Xamarin.Android. È stato descritto come installare pacchetti aggiuntivi necessari per le comunicazioni GCM e come configurare le autorizzazioni dell'app per l'accesso ai server GCM. Ha fornito codice di esempio che illustra come verificare la presenza di Google Play Services, come implementare un servizio di ascolto delle finalità di registrazione e un servizio listener ID istanza che negozia con GCM per un token di registrazione e come implementare un servizio listener GCM che riceve ed elabora messaggi di notifica remota. Infine, è stato implementato un programma di test da riga di comando per inviare notifiche di test all'app client tramite GCM.