Добавление push-уведомлений в приложение Xamarin.Android
Обзор
В этом руководстве мы добавим push-уведомления в проект быстрого запуска Xamarin.Android, чтобы при каждом добавлении новой записи на устройство отправлялось push-уведомление.
Если вы не используете скачанный проект сервера, необходимо добавить пакет расширений для push-уведомлений. Дополнительные сведения см. в статье Работа с пакетом SDK для внутреннего сервера .NET для мобильных приложений Azure.
Предварительные требования
Для работы с этим руководством требуется настройка:
- Активная учетная запись Google. Вы можете зарегистрировать учетную запись Google на сайте accounts.google.com.
- Компонент клиента Google Cloud Messaging.
Настройка концентратора уведомлений
Компонент мобильных приложений в службе приложений Azure использует Центры уведомлений Azure для отправки push-уведомлений, поэтому вам нужно настроить центр уведомлений для мобильного приложения.
На портале Azure щелкните Службы приложений, а затем выберите серверную часть приложения. В разделе Параметры выберите Push.
Чтобы добавить в приложение ресурс концентратора уведомлений, нажмите кнопку Подключить. Вы можете создать центр или подключиться к существующему.
Теперь центр уведомлений подключен к серверной части проекта вашего мобильного приложения. Позднее вы настроите этот концентратор уведомлений, чтобы подключиться к системе отправки уведомлений платформы (PNS), которая отправляет push-уведомления на устройства.
Включение Firebase Cloud Messaging
Войдите в консоль Firebase. Создайте проект Firebase, если его еще нет.
После создания проекта выберите Add Firebase to your Android app (Добавить Firebase в приложение Android).
Выполните следующие действия на странице Add Firebase to your Android app (Добавление Firebase в приложение Android):
Для Имя пакета Android скопируйте свое значение applicationId в файл приложения build.gradle. В нашем примере он выглядит следующим образом:
com.fabrikam.fcmtutorial1app
.Выберите Регистрация приложения.
Выберите Download google-services.json (Загрузить google-services.json), сохраните файл в папку приложения проекта, а затем выберите Далее.
Внесите следующие изменения конфигурации в проект в Android Studio.
В файл build.gradle уровня проекта (<project>/build.gradle) добавьте следующий текст в раздел зависимости.
classpath 'com.google.gms:google-services:4.0.1'
В файле build.gradle уровня приложения (<project>/<app-module>/build.gradle) в раздел зависимостей добавьте следующий текст.
implementation 'com.google.firebase:firebase-core:16.0.8' implementation 'com.google.firebase:firebase-messaging:17.3.4'
Добавьте следующую строку в конец файла build.gradle уровня приложения после раздела с зависимостями.
apply plugin: 'com.google.gms.google-services'
На панели инструментов щелкните Синхронизировать сейчас.
Выберите Далее.
Выберите Пропустить этот шаг.
В консоли Firebase щелкните значок шестеренки возле имени проекта. Выберите пункт Project Settings (Параметры проекта).
Если вы еще не скачали файл google-services.json в папку app проекта Android Studio, это можно сделать на этой странице.
Переключитесь на вкладку Обмен сообщениями в облаке в верхней части.
Скопируйте и сохраните Ключ сервера для последующего использования. Это значение используется для настройки имени центра.
Настройка Azure для отправки push-запросов
На портале Azure щелкните Просмотреть все>Службы приложений, а затем выберите серверную часть своего мобильного приложения. В разделе Параметры щелкните App Service Push (Push-уведомления службы приложений) и выберите имя центра уведомлений.
Выберите Google (GCM), введите значение ключа сервера, полученное от Firebase в ходе предыдущей процедуры, и нажмите кнопку Сохранить.
Теперь серверная часть вашего мобильного приложения настроена для использования Firebase Cloud Messaging. Это позволяет отправлять push-уведомления приложению Android через центр уведомлений.
Обновление серверного проекта для отправки push-уведомлений
В этом разделе описывается обновление кода в существующем проекте серверной части мобильных приложений, которое позволит отправлять push-уведомления при каждом добавлении нового элемента. Этот процесс реализуется с помощью шаблонов Центров уведомлений, включая отправку push-уведомлений между разными платформами. Разные клиенты регистрируются для обмена push-уведомлениями с помощью шаблонов; одно такое универсальное push-уведомление можно получать на всех клиентских платформах.
Выберите одну из следующих процедур, которые соответствуют типу проекта серверной части — серверной части .NET или Node.js серверной части.
Серверный проект .NET
В Visual Studio щелкните правой кнопкой мыши серверный проект. Затем выберите Управление пакетами NuGet. Найдите
Microsoft.Azure.NotificationHubs
, а затем нажмите кнопку Установить. Этот процесс устанавливает библиотеку Центров уведомлений для отправки уведомлений из серверной части.В серверном проекте откройте файл Controllers>TodoItemController.cs. Затем добавьте следующие операторы using:
using System.Collections.Generic; using Microsoft.Azure.NotificationHubs; using Microsoft.Azure.Mobile.Server.Config;
В метод PostTodoItem добавьте следующий код после вызова 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"); }
При вставке нового элемента отправляется шаблонное уведомление, содержащее item.Text.
Повторная публикация серверного проекта
Серверный проект Node.js
Настройте внутренний проект.
Замените существующий код в файле todoitem.js следующим кодом:
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;
При вставке нового элемента отправляется шаблонное уведомление, содержащее item.Text.
При редактировании этого файла на локальном компьютере повторно опубликуйте серверный проект.
Настройка клиентского проекта для использования push-уведомлений
В представлении решения (или Обозреватель решений в Visual Studio) щелкните правой кнопкой мыши папку "Компоненты", выберите команду "Получить дополнительные компоненты...", найдите компонент клиента Google Cloud Messaging и добавьте его в проект.
Откройте файл проекта ToDoActivity.cs и добавьте в класс следующую инструкцию using:
using Gcm.Client;
Добавьте в класс ToDoActivity следующий новый код:
// 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; } }
Это позволяет получать доступ к экземпляру мобильного клиента, используя процесс службы обработчика push-действий.
После создания MobileServiceClient добавьте в метод OnCreate следующий код:
// 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);
Ваш класс ToDoActivity теперь готов для добавления push-уведомлений.
Добавление кода push-уведомлений в приложение
Создайте класс в проекте с именем
ToDoBroadcastReceiver
.Добавьте следующие инструкции using в класс ToDoBroadcastReceiver :
using Gcm.Client; using Microsoft.WindowsAzure.MobileServices; using Newtonsoft.Json.Linq;
Добавьте следующие разрешения запросов между операторами using и объявлением 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")]
Замените существующее определение класса ToDoBroadcastReceiver следующим:
[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>" }; }
В приведенном выше коде необходимо заменить
<PROJECT_NUMBER>
номером проекта, назначенным службой Google при подготовке приложения к работе на портале разработчика Google.В файле проекта ToDoBroadcastReceiver.cs добавьте следующий код, который определяет класс 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) { } }
Обратите внимание, что этот класс является производным от GcmServiceBase, поэтому к нему необходимо применить атрибут Service.
Примечание
Класс GcmServiceBase реализует методы OnRegistered(), OnUnRegistered(), OnMessage() и OnError(). Эти методы необходимо переопределить в классе PushHandlerService .
Добавьте приведенный ниже код в класс PushHandlerService, который переопределяет обработчик событий 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)); } }
В этом методе возвращенный идентификатор регистрации GCM используется для регистрации push-уведомлений в службе Azure. Теги могут добавляться к регистрации только после ее создания. Дополнительные сведения см. в разделе Практическое руководство. Включение принудительной отправки push-уведомлений с использованием тегов.
Переопределите метод OnMessage в PushHandlerService с использованием следующего кода:
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); } }
Переопределите методы OnUnRegistered() и OnError() с помощью следующего кода:
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)); }
Тестирование push-уведомлений в приложении
Приложение можно проверить, используя виртуальное устройство в эмуляторе. Для запуска в эмуляторе необходимо выполнить дополнительную настройку.
На виртуальном устройстве необходимо задать API-интерфейсы Google в качестве целевого объекта для диспетчера виртуальных устройств Android (AVD).
Добавьте учетную запись Google на устройство Android, нажав кнопку "Параметры>приложений>" добавить учетную запись, а затем следуйте инструкциям.
Запустите приложение todolist, как ранее, и вставьте новый элемент списка дел. На этот раз в области уведомлений отображается значок уведомления. Вы можете открыть панель уведомлений, чтобы просмотреть полный текст уведомления.