Aggiungere notifiche push all'app Xamarin.Android

Panoramica

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 questa esercitazione è necessaria la configurazione:

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 passare a Servizi app e quindi selezionare il back-end dell'app. In Impostazioni selezionare Push.

  2. Per aggiungere una risorsa hub di notifica all'app selezionare Connetti. È possibile creare un hub o connettersi a uno esistente.

    Configurare un hub

A questo punto un hub di notifica è stato connesso al progetto di back-end dell'app per dispositivi mobili. In seguito si configurerà questo hub di notifica per la connessione a un sistema PNS (Platform Notification System) per eseguire 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, selezionare Add Firebase to your Android app (Aggiungi Firebase all'app Android).

    Aggiungere Firebase all'app Android

  3. Nella pagina Aggiungi Firebase all'app Android seguire questa procedura:

    1. Per Android package name (Nome pacchetto Android), copiare il valore di applicationId nel file build.gradle dell'applicazione. In questo esempio è com.fabrikam.fcmtutorial1app.

      Specificare il nome del pacchetto

    2. Selezionare Registra l'app.

  4. Selezionare Download google-services.json (Scarica google-services.json), salvare il file nella cartella app del progetto e quindi selezionare Avanti.

    Scaricare google-services.json

  5. Apportare le seguenti modifiche di configurazione al progetto in Android Studio.

    1. Nel file project-level build.gradle (<project>/build.gradle) aggiungere l'istruzione seguente alla sezione dependencies.

      classpath 'com.google.gms:google-services:4.0.1'
      
    2. Nel file build.gradle a livello di app (<project>/<app-module>/build.gradle) aggiungere le istruzioni seguenti alla sezione dependencies .

      implementation 'com.google.firebase:firebase-core:16.0.8'
      implementation 'com.google.firebase:firebase-messaging:17.3.4'
      
    3. Aggiungere la riga seguente alla fine del file app-level build.gradle dopo la sezione dependencies.

      apply plugin: 'com.google.gms.google-services'
      
    4. Selezionare Sincronizza ora sulla barra degli strumenti.

      Modifiche di configurazione a build.gradle

  6. Selezionare Avanti.

  7. Selezionare Ignora questo passaggio.

    Ignorare l'ultimo passaggio

  8. Nella console di Firebase selezionare il file COG per il progetto. Selezionare quindi Project Settings (Impostazioni progetto).

    Selezionare Project Settings (Impostazioni progetto)

  9. Se il file google-services.json non è stato scaricato nella cartella app del progetto di Android Studio, è possibile eseguire questa operazione in questa pagina.

  10. Passare alla scheda Cloud Messaging in alto.

  11. Copiare e salvare il valore di Chiave server per un uso successivo. Questo valore viene usato per configurare l'hub.

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 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. Questo processo 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 procedure seguenti che corrispondano al tipo di progetto back-end, ovvero back-end .NET o Node.js back-end.

Progetto di back-end .NET

  1. In Visual Studio fare clic con il pulsante destro del mouse sul progetto server. Scegliere quindi Gestisci pacchetti NuGet. Cercare Microsoft.Azure.NotificationHubs e quindi selezionare Installa. Questo processo installa la libreria Hub di notifica per l'invio di notifiche dal back-end.

  2. Nel progetto server aprire Controllers>TodoItemController.cs. Aggiungere quindi 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);
    
    // Send the message so that all template registrations that contain "messageParam"
    // 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");
    }
    

    Questo processo invia una notifica modello contenente item.Text quando viene inserito un nuovo elemento.

  4. Pubblicare di nuovo il progetto server.

Progetto di back-end Node.js

  1. Configurare il progetto back-end.

  2. Sostituire il codice esistente in 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 https://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;  
    

    Questo processo invia una notifica modello contenente item.text quando viene inserito un nuovo elemento.

  3. In caso di modifica del file nel computer locale, ripubblicare il progetto server.

Configurare il progetto client per le notifiche push

  1. Nella visualizzazione Soluzione (o Esplora soluzioni in Visual Studio), fare clic con il pulsante destro del mouse sulla cartella Componenti, scegliere Recupera altri componenti, cercare il componente Client Google Cloud Messaging 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. Il dispositivo virtuale deve avere le API Google impostate come destinazione nella gestione del dispositivo virtuale Android (AVD).

  2. Aggiungere un account Google al dispositivo Android facendo clic suImpostazioni>app>Aggiungi account e 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.