Adicionar notificações por push ao aplicativo Xamarin.Android

Visão geral

Neste tutorial, você adicionará notificações por push ao projeto de Início rápido do Xamarin.Android de forma que sempre que um registro for inserido, uma notificação por push seja enviada.

Se você não usar o projeto do servidor de início rápido baixado, precisará do pacote de extensão da notificação por push. Para saber mais, consulte o guia Trabalhar com o SDK do servidor de back-end do .NET para Aplicativos Móveis do Azure.

Pré-requisitos

Este tutorial requer a configuração:

Configurar um Hub de Notificação

O recurso Aplicativos Móveis do Serviço de Aplicativo do Azure usa Hubs de Notificação para enviar por push e, portanto, você deve configurar um hub de notificação para seu aplicativo móvel.

  1. No Portal do Azure, vá para Serviços de Aplicativos e, em seguida, selecione o back-end do aplicativo. Em Configurações, selecione Push.

  2. Para adicionar um recurso do hub de notificação ao aplicativo, selecione Conectar. Você pode criar um hub ou conectar-se a um existente.

    Configurar um hub

Agora você se conectou a um hub de notificação para o projeto de back-end dos Aplicativos Móveis. Posteriormente, você configura esse hub de notificação para conectar um PNS (Sistema de Notificação de Plataforma) a fim de enviar por push para dispositivos.

Habilitar o Firebase Cloud Messaging

  1. Faça logon no console do Firebase. Crie um novo projeto do Firebase se você ainda não tiver um.

  2. Depois de criar seu projeto, selecione Adicionar Firebase ao seu aplicativo Android.

    Adicione o Firebase ao seu aplicativo Android

  3. Siga estas etapas na página Adicionar Firebase ao seu aplicativo Android:

    1. Para Nome do pacote Android, copie o valor de applicationId no arquivo build.gradle do aplicativo. Neste exemplo, é com.fabrikam.fcmtutorial1app.

      Especificar o nome do pacote

    2. Selecione Registrar aplicativo.

  4. Selecione Baixar google-services.json, salve o arquivo na pasta app do projeto e, em seguida, selecione Avançar.

    Baixar google-services.json

  5. Faça as seguintes alterações na configuração do seu projeto no Android Studio.

    1. No arquivo project-level build.gradle (<project>/build.gradle), adicione a seguinte instrução à seção de dependências.

      classpath 'com.google.gms:google-services:4.0.1'
      
    2. No arquivo build.gradle no nível do aplicativo (<project>/<app-module>/build.gradle), adicione as instruções a seguir à seção de dependências.

      implementation 'com.google.firebase:firebase-core:16.0.8'
      implementation 'com.google.firebase:firebase-messaging:17.3.4'
      
    3. Adicione a seguinte linha ao final do arquivo build.gradle no nível do aplicativo após a seção de dependências.

      apply plugin: 'com.google.gms.google-services'
      
    4. Selecione Sincronizar agora na barra de ferramentas.

      Alterações na configuração de build.gradle

  6. Selecione Avançar.

  7. Selecione Ignorar esta etapa.

    Ignorar a última etapa

  8. No console do Firebase, selecione a engrenagem para seu projeto. Em seguida, selecione Configurações do Projeto.

    Selecione Configurações do Projeto

  9. Se você não tiver baixado o arquivo google-services.json para a pasta aplicativo do projeto do Android Studio, será possível fazer isso nesta página.

  10. Mude para a guia Mensagens de Nuvem na parte superior.

  11. Copie e salve a Chave do servidor para uso posterior. Use esse valor para configurar o hub.

Configurar o Azure para enviar notificações por push

  1. No portal do Azure, clique em Procurar Tudo>Serviços de Aplicativos e clique em seu back-end de Aplicativos Móveis. Em Configurações, clique em Push do Serviço de Aplicativo e clique no nome do hub de notificação.

  2. Vá para Google (GCM), insira o valor Chave do Servidor obtido do Firebase no procedimento anterior e clique em Salvar.

    Definir a chave de API no portal

O back-end de Aplicativos Móveis agora está configurado para usar o Firebase Cloud Messaging. Isso permite que você envie notificações por push para seu aplicativo em execução em um dispositivo Android usando o hub de notificação.

Atualizar o projeto de servidor para enviar notificações por push

Nesta seção, você aprenderá a atualizar o código em seu projeto de back-end de Aplicativos Móveis para enviar uma notificação por push sempre que um novo item for adicionado. Esse processo é alimentado pelo recurso modelo dos Hubs de Notificações do Microsoft Azure, que permite pushes de plataforma cruzada. Os vários clientes são registrados para notificações por push usando modelos, e um único envio por push universal pode chegar a todas as plataformas clientes.

Escolha um dos procedimentos a seguir que correspondam ao tipo de projeto de back-end, seja o back-end do .NET ou Node.js back-end.

Projeto de back-end do .NET

  1. No Visual Studio, clique com o botão direito do mouse no projeto do servidor. Em seguida, selecione Gerenciar Pacotes do NuGet. Pesquise Microsoft.Azure.NotificationHubs e, em seguida, selecione Instalar. Esse processo instala a biblioteca dos Hubs de Notificação para enviar notificações do back-end.

  2. No projeto do servidor, abra Controllers>TodoItemController.cs. Em seguida, adicione as seguintes instruções usando:

    using System.Collections.Generic;
    using Microsoft.Azure.NotificationHubs;
    using Microsoft.Azure.Mobile.Server.Config;
    
  3. No método PostTodoItem, adicione o seguinte código após a chamada para 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");
    }
    

    Esse processo envia uma notificação de modelo que contém o item.Texto quando um novo item é inserido.

  4. Republicar o projeto de servidor.

Projeto de back-end do Node.js

  1. Configure seu projeto de back-end.

  2. Substitua o código existente em todoitem.js pelo código a seguir:

    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;  
    

    Esse processo envia uma notificação de modelo que contém o item.text quando um novo item é inserido.

  3. Ao editar o arquivo no computador local, publique o projeto do servidor.

Configurar o projeto para notificações por push

  1. No modo de exibição Solução (ou Gerenciador de Soluções no Visual Studio), clique com o botão direito do mouse na pasta Componentes, clique em Obter Mais Componentes..., pesquise o componente cliente do Google Cloud Messaging e adicione-o ao projeto.

  2. Abra o arquivo de projeto ToDoActivity.cs e adicione a instrução using a seguir à classe:

    using Gcm.Client;
    
  3. Na classe ToDoActivity , adicione o seguinte código novo:

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

    Isso permite que você acesse a instância do cliente móvel do processo de serviço do manipulador por push.

  4. Adicione o código a seguir ao método OnCreate, após a criação do 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);
    

Sua ToDoActivity agora está preparada para adicionar notificações por push.

Adicionar código de notificações por push ao seu aplicativo

  1. Crie uma nova classe no projeto chamado ToDoBroadcastReceiver.

  2. Adicionar o seguinte usando as instruções para a classe ToDoBroadcastReceiver :

    using Gcm.Client;
    using Microsoft.WindowsAzure.MobileServices;
    using Newtonsoft.Json.Linq;
    
  3. Adicione as solicitações de permissão a seguir entre as instruções using e a declaração 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. Substitua a definição da classe ToDoBroadcastReceiver pelo seguinte:

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

    No código acima, você deve substituir <PROJECT_NUMBER> pelo número do projeto atribuído pelo Google ao provisionar o aplicativo no portal do desenvolvedor do Google.

  5. No arquivo de projeto ToDoBroadcastReceiver.cs, adicione o código a seguir, que define a 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) { }
    }
    

    Observe que essa classe deriva de GcmServiceBase e que o atributo Service deve ser aplicado a essa classe.

    Observação

    A classe GcmServiceBase implementa os métodos OnRegistered(), OnUnRegistered(), OnMessage() e OnError(). Você deve substituir esses métodos na classe PushHandlerService .

  6. Adicione o código a seguir à classe PushHandlerService que substitui o manipulador de eventos 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));
        }
    }
    

    Esse método usa a ID de registro retornada do GCM para registrar-se no Azure para notificações por push. Marcas só podem ser adicionadas ao registro depois que ele é criado. Para obter mais informações, veja Como: adicionar marcas à instalação de um dispositivo para habilitar o envio por push para marcas.

  7. Substitua o método OnMessage no PushHandlerService pelo código a seguir:

    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. Substitua os métodos OnUnRegistered() e OnError() pelo código a seguir.

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

Testar notificações por push no seu aplicativo

Você pode testar o aplicativo usando um dispositivo virtual no emulador. Há etapas de configuração adicionais exigidas durante a execução em um emulador.

  1. O dispositivo virtual deve ter APIs do Google definidas como o destino no gerenciador de Dispositivo Virtual Android (AVD).

  2. Adicione uma conta do Google ao dispositivo Android clicando naconta AdicionarConfigurações> de Aplicativos> e siga os prompts.

  3. Execute o aplicativo todolist como feito anteriormente s e insira um novo item de tarefa pendente. Dessa vez, um ícone de notificação é exibido na área de notificação. Você pode abrir a gaveta de notificações para exibir o texto completo da notificação.