Aggiungere notifiche push all'app Xamarin.Android

Overview

In questa esercitazione vengono aggiunte notifiche push al progetto avvio rapido di Xamarin.Android, in modo che una notifica push venga inviata al dispositivo a ogni inserimento di record.

Se non si usa il progetto server di avvio rapido scaricato, sarà necessario aggiungere il pacchetto di estensione di notifica push. Per altre informazioni, vedere Usare l'SDK del server back-end .NET per App per dispositivi mobili di Azure.

Prerequisiti

Per completare questa esercitazione, è necessario disporre di:

Configurare un hub di notifica

Poiché le funzioni delle app per dispositivi mobili del Servizio app di Azure usano Hub di notifica di Azure per inviare push, si dovrà configurare un hub di notifica per l'app per dispositivi mobili.

  1. Nel Portale di Azure andare in Servizi app, quindi fare clic sul back-end dell'app. In Impostazioni fare clic su Push.
  2. Fare clic su Connetti per aggiungere una risorsa dell'hub di notifica all'app. È possibile creare un hub o connettersi a uno esistente.

A questo punto un hub di notifica è stato connesso al progetto di back-end dell'app per dispositivi mobili. In seguito si configurerà l'hub di notifica per la connessione a un Platform Notification System (PNS) per effettuare il push ai dispositivi.

Abilitare Firebase Cloud Messaging

  1. Accedere alla console di Firebase. Creare un nuovo progetto Firebase se non è già disponibile.
  2. Dopo aver creato il progetto, fare clic su Add Firebase to your Android app (Aggiungi Firebase all'app Android) e seguire le istruzioni fornite.

  3. Nella console di Firebase fare clic sul file cog per il progetto e quindi fare clic su Impostazioni progetto.

  4. Fare clic sulla scheda Cloud Messaging nelle impostazioni del progetto e copiare il valore di Chiave server e ID mittente. Questi valori verranno usati in un secondo momento per configurare i criteri di accesso dell'hub di notifica de e il gestore delle notifiche nell'app.

Configurare Azure per l'invio di richieste push

  1. Nel Portale di Azure fare clic su Browse All (Esplora tutto) > Servizi app e quindi scegliere il back-end dell'app per dispositivi mobili. In Impostazioni fare clic su App Service Push (Push servizio app), quindi fare clic sul nome dell'hub di notifica.
  2. Passare a Google (GCM), immettere il valore Chiave server ottenuto da Firebase nella procedura precedente, quindi fare clic su Salva.

    Impostare la chiave API di GCM nel portale

Il back-end dell'app per dispositivi mobili è ora configurato per l'uso di Firebase Cloud Messaging. Questo consente di inviare notifiche push all'app in esecuzione su un dispositivo Android usando l'hub di notifica.

Aggiornare il progetto server per l'invio di notifiche push

In questa sezione viene aggiornato il codice nel progetto di back-end dell'app per dispositivi mobili esistente per inviare una notifica push ogni volta che viene aggiunto un nuovo elemento. Questa operazione si basa sulla funzionalità dei modelli di Hub di notifica di Azure, che abilita i push multipiattaforma. I diversi client vengono registrati per le notifiche push usando i modelli e un unico push universale può raggiungere tutte le piattaforme client.

Scegliere una delle seguenti procedure che corrisponde al tipo di progetto di back-end—, che sia back-end .NET o back-end Node.js.

Progetto di back-end .NET

  1. In Visual Studio fare clic con il pulsante destro del mouse sul progetto server, quindi scegliere Gestisci pacchetti NuGet. Cercare Microsoft.Azure.NotificationHubs, quindi fare clic su Installa. Consente di installare la libreria di Hub di notifica per l'invio di notifiche dal back-end.
  2. Nel progetto server aprire Controller > TodoItemController.cs e quindi aggiungere le istruzioni using seguenti:

     using System.Collections.Generic;
     using Microsoft.Azure.NotificationHubs;
     using Microsoft.Azure.Mobile.Server.Config;
    
  3. Nel metodo PostTodoItem aggiungere il codice seguente dopo la chiamata a InsertAsync:

     // Get the settings for the server project.
     HttpConfiguration config = this.Configuration;
     MobileAppSettingsDictionary settings =
         this.Configuration.GetMobileAppSettingsProvider().GetMobileAppSettings();
    
     // Get the Notification Hubs credentials for the Mobile App.
     string notificationHubName = settings.NotificationHubName;
     string notificationHubConnection = settings
         .Connections[MobileAppSettingsKeys.NotificationHubConnectionString].ConnectionString;
    
     // Create a new Notification Hub client.
     NotificationHubClient hub = NotificationHubClient
     .CreateClientFromConnectionString(notificationHubConnection, notificationHubName);
    
     // Sending the message so that all template registrations that contain "messageParam"
     // will receive the notifications. This includes APNS, GCM, WNS, and MPNS template registrations.
     Dictionary<string,string> templateParams = new Dictionary<string,string>();
     templateParams["messageParam"] = item.Text + " was added to the list.";
    
     try
     {
         // Send the push notification and log the results.
         var result = await hub.SendTemplateNotificationAsync(templateParams);
    
         // Write the success result to the logs.
         config.Services.GetTraceWriter().Info(result.State.ToString());
     }
     catch (System.Exception ex)
     {
         // Write the failure result to the logs.
         config.Services.GetTraceWriter()
             .Error(ex.Message, null, "Push.SendAsync Error");
     }
    

    Ogni volta che viene inserito un nuovo elemento, viene inviata una notifica modello contenente l'elemento item.text.

  4. Pubblicare di nuovo il progetto server.

Progetto di back-end Node.js

  1. Se ancora non è stato fatto, scaricare il progetto di back-end di avvio rapido oppure usare l'editor online del Portale di Azure.
  2. Sostituire il codice esistente nel file todoitem.js con il codice seguente:

     var azureMobileApps = require('azure-mobile-apps'),
     promises = require('azure-mobile-apps/src/utilities/promises'),
     logger = require('azure-mobile-apps/src/logger');
    
     var table = azureMobileApps.table();
    
     table.insert(function (context) {
     // For more information about the Notification Hubs JavaScript SDK,
     // see http://aka.ms/nodejshubs
     logger.info('Running TodoItem.insert');
    
     // Define the template payload.
     var payload = '{"messageParam": "' + context.item.text + '" }';  
    
     // Execute the insert.  The insert returns the results as a Promise,
     // Do the push as a post-execute action within the promise flow.
     return context.execute()
         .then(function (results) {
             // Only do the push if configured
             if (context.push) {
                 // Send a template notification.
                 context.push.send(null, payload, function (error) {
                     if (error) {
                         logger.error('Error while sending push notification: ', error);
                     } else {
                         logger.info('Push notification sent successfully!');
                     }
                 });
             }
             // Don't forget to return the results from the context.execute()
             return results;
         })
         .catch(function (error) {
             logger.error('Error while running context.execute: ', error);
         });
     });
    
     module.exports = table;  
    

    Ogni volta che viene inserito un nuovo elemento, viene inviata una notifica modello contenente l'elemento item.text.

  3. Quando si modifica il file nel computer locale, ripubblicare il progetto server.

Configurare il progetto client per le notifiche push

  1. Nella visualizzazione della soluzione (o Esplora soluzioni in Visual Studio) fare clic con il pulsante destro del mouse sulla cartella Componenti, scegliere Ottieni altri componenti, cercare il componente Google Cloud Messaging Client e aggiungerlo al progetto.
  2. Aprire il nuovo file di progetto ToDoActivity.cs e aggiungere l'istruzione using seguente alla classe:

     using Gcm.Client;
    
  3. Nella classe ToDoActivity aggiungere il nuovo codice seguente:

     // Create a new instance field for this activity.
     static ToDoActivity instance = new ToDoActivity();
    
     // Return the current activity instance.
     public static ToDoActivity CurrentActivity
     {
         get
         {
             return instance;
         }
     }
     // Return the Mobile Services client.
     public MobileServiceClient CurrentClient
     {
         get
         {
             return client;
         }
     }
    

    Questa operazione consente di accedere all'istanza del client mobile dal processo del servizio del gestore push.

  4. Aggiungere il codice seguente al metodo OnCreate, dopo la creazione di MobileServiceClient:

    // Set the current instance of TodoActivity.
    instance = this;
    
    // Make sure the GCM client is set up correctly.
    GcmClient.CheckDevice(this);
    GcmClient.CheckManifest(this);
    
    // Register the app for push notifications.
    GcmClient.Register(this, ToDoBroadcastReceiver.senderIDs);
    

La classe ToDoActivity è ora pronta per l'aggiunta di notifiche push.

Aggiungere il codice delle notifiche push all'app

  1. Creare una nuova classe nel progetto denominato ToDoBroadcastReceiver.
  2. Aggiungere le istruzioni using seguenti alla classe ToDoBroadcastReceiver :

     using Gcm.Client;
     using Microsoft.WindowsAzure.MobileServices;
     using Newtonsoft.Json.Linq;
    
  3. Aggiungere le richieste di autorizzazione seguenti tra le istruzioni using e la dichiarazione namespace:

     [assembly: Permission(Name = "@PACKAGE_NAME@.permission.C2D_MESSAGE")]
     [assembly: UsesPermission(Name = "@PACKAGE_NAME@.permission.C2D_MESSAGE")]
     [assembly: UsesPermission(Name = "com.google.android.c2dm.permission.RECEIVE")]
    
     //GET_ACCOUNTS is only needed for android versions 4.0.3 and below
     [assembly: UsesPermission(Name = "android.permission.GET_ACCOUNTS")]
     [assembly: UsesPermission(Name = "android.permission.INTERNET")]
     [assembly: UsesPermission(Name = "android.permission.WAKE_LOCK")]
    
  4. Sostituire la definizione della classe ToDoBroadcastReceiver esistente con la seguente:

     [BroadcastReceiver(Permission = Gcm.Client.Constants.PERMISSION_GCM_INTENTS)]
     [IntentFilter(new string[] { Gcm.Client.Constants.INTENT_FROM_GCM_MESSAGE }, 
         Categories = new string[] { "@PACKAGE_NAME@" })]
     [IntentFilter(new string[] { Gcm.Client.Constants.INTENT_FROM_GCM_REGISTRATION_CALLBACK }, 
         Categories = new string[] { "@PACKAGE_NAME@" })]
     [IntentFilter(new string[] { Gcm.Client.Constants.INTENT_FROM_GCM_LIBRARY_RETRY }, 
     Categories = new string[] { "@PACKAGE_NAME@" })]
     public class ToDoBroadcastReceiver : GcmBroadcastReceiverBase<PushHandlerService>
     {
         // Set the Google app ID.
         public static string[] senderIDs = new string[] { "<PROJECT_NUMBER>" };
     }
    

    Nel codice precedente è necessario sostituire <PROJECT_NUMBER> con il numero di progetto assegnato da Google quando è stato effettuato il provisioning dell'app nel portale per sviluppatori di Google.

  5. Nel file di progetto ToDoBroadcastReceiver.cs aggiungere il codice seguente che definisce la classe PushHandlerService :

     // The ServiceAttribute must be applied to the class.
     [Service] 
     public class PushHandlerService : GcmServiceBase
     {
         public static string RegistrationID { get; private set; }
    
         public PushHandlerService() : base(ToDoBroadcastReceiver.senderIDs) { }
     }
    

    Si noti che questa classe deriva da GcmServiceBase e che l'attributo Service deve essere applicato a questa classe.

    Nota

    La classe GcmServiceBase implementa i metodi OnRegistered(), OnUnRegistered(), OnMessage() e OnError(). È necessario eseguire l'override di questi metodi nella classe PushHandlerService .

  6. Aggiungere il codice seguente alla classe PushHandlerService che sostituisce il gestore di eventi OnRegistered.

     protected override void OnRegistered(Context context, string registrationId)
     {
         System.Diagnostics.Debug.WriteLine("The device has been registered with GCM.", "Success!");
    
         // Get the MobileServiceClient from the current activity instance.
         MobileServiceClient client = ToDoActivity.CurrentActivity.CurrentClient;
         var push = client.GetPush();
    
         // Define a message body for GCM.
         const string templateBodyGCM = "{\"data\":{\"message\":\"$(messageParam)\"}}";
    
         // Define the template registration as JSON.
         JObject templates = new JObject();
         templates["genericMessage"] = new JObject
         {
           {"body", templateBodyGCM }
         };
    
         try
         {
             // Make sure we run the registration on the same thread as the activity, 
             // to avoid threading errors.
             ToDoActivity.CurrentActivity.RunOnUiThread(
    
                 // Register the template with Notification Hubs.
                 async () => await push.RegisterAsync(registrationId, templates));
    
             System.Diagnostics.Debug.WriteLine(
                 string.Format("Push Installation Id", push.InstallationId.ToString()));
         }
         catch (Exception ex)
         {
             System.Diagnostics.Debug.WriteLine(
                 string.Format("Error with Azure push registration: {0}", ex.Message));
         }
     }
    

    Questo metodo usa l'ID di registrazione GCM restituito per la registrazione con Azure per l'invio di notifiche push. I tag possono essere aggiunti solo per la registrazione dopo averla creato. Per ulteriori informazioni, vedere Procedura: Aggiungere tag all'installazione di un dispositivo per abilitare il push dei tag.

  7. Eseguire l'override del metodo OnMessage in PushHandlerService con il codice seguente:

    protected override void OnMessage(Context context, Intent intent)
    {          
        string message = string.Empty;
    
        // Extract the push notification message from the intent.
        if (intent.Extras.ContainsKey("message"))
        {
            message = intent.Extras.Get("message").ToString();
            var title = "New item added:";
    
            // Create a notification manager to send the notification.
            var notificationManager = 
                GetSystemService(Context.NotificationService) as NotificationManager;
    
            // Create a new intent to show the notification in the UI. 
            PendingIntent contentIntent = 
                PendingIntent.GetActivity(context, 0, 
                new Intent(this, typeof(ToDoActivity)), 0);              
    
            // Create the notification using the builder.
            var builder = new Notification.Builder(context);
            builder.SetAutoCancel(true);
            builder.SetContentTitle(title);
            builder.SetContentText(message);
            builder.SetSmallIcon(Resource.Drawable.ic_launcher);
            builder.SetContentIntent(contentIntent);
            var notification = builder.Build();
    
            // Display the notification in the Notifications Area.
            notificationManager.Notify(1, notification);
    
        }
    }
    
  8. Eseguire l'override dei metodi OnUnRegistered() e OnError() con il codice seguente.

    protected override void OnUnRegistered(Context context, string registrationId)
    {
        throw new NotImplementedException();
    }
    
    protected override void OnError(Context context, string errorId)
    {
        System.Diagnostics.Debug.WriteLine(
            string.Format("Error occurred in the notification: {0}.", errorId));
    }
    

Testare le notifiche push nell'app

È possibile testare l'app mediante un dispositivo virtuale nell'emulatore. Ci sono altri passaggi di configurazione richiesti durante l'esecuzione in un emulatore.

  1. Assicurarsi di distribuire o eseguire il debug su un dispositivo virtuale che ha le API Google API impostate come destinazione, come illustrato di seguito nel gestore del dispositivo virtuale Android (AVD).

  2. Aggiungere un account Google al dispositivo Android facendo clic su Apps (App) > Settings (Impostazioni) > Add account (Aggiungi account), quindi seguire le istruzioni.

  3. Eseguire l'app todolist come fatto in precedenza e inserire un nuovo elemento todo. Questa volta, viene visualizzata un'icona di notifica nell'area di notifica. È possibile aprire la cassetta della notifica per visualizzare il testo completo della notifica.