概述
在本教程中,将推送通知添加到 Xamarin.Android 快速入门 项目,以便在每次插入记录时向设备发送推送通知。
如果不使用下载的快速启动服务器项目,则需要推送通知扩展包。 有关详细信息,请参阅 适用于 Azure 移动应用的 .NET 后端服务器 SDK 指南。
先决条件
本教程需要设置:
- 有效的 Google 帐户。 可以在 accounts.google.com 注册 Google 帐户。
- Google Cloud Messaging 客户端组件。
配置通知中心
Azure 应用服务的移动应用功能使用 Azure 通知中心 发送推送,因此你将为移动应用配置通知中心。
在 Azure 门户中,转到 应用服务,然后选择应用后端。 在 设置中,选择 推送。
若要向应用添加通知中心资源,请选择 连接。 可以创建中心或连接到现有中心。
现在,已将通知中心连接到移动应用后端项目。 稍后,请将此通知中心配置为连接到平台通知系统(PNS),以推送到设备。
启用 Firebase Cloud Messaging
登录到 Firebase 控制台。 如果还没有 Firebase 项目,创建一个新项目。
创建项目后,选择“向 Android 应用添加 Firebase”。
在“将 Firebase 添加到 Android 应用”页上,执行以下步骤:
对于“Android 程序包名称”,请在应用程序的 build.gradle 文件中复制 applicationId 的值。 在此示例中,它是
com.fabrikam.fcmtutorial1app
。选择“注册应用”。
选择“下载 google-services.json”,将该文件保存到项目的 app 文件夹中,然后选择“下一步”。
在 Android Studio 中对你的项目进行以下配置更改。
在项目级 build.gradle 文件 (<project>/build.gradle) 中,向 dependencies 部分中添加以下语句。
classpath 'com.google.gms:google-services:4.0.1'
在应用级 build.gradle 文件 (<project>/<app-module>/build.gradle) 中,向 dependencies 部分中添加以下语句。
implementation 'com.google.firebase:firebase-core:16.0.8' implementation 'com.google.firebase:firebase-messaging:17.3.4'
在应用级 build.gradle 文件的末尾,在 dependencies 部分后面添加以下行。
apply plugin: 'com.google.gms.google-services'
在工具栏上选择“立即同步”。
选择“下一步”。
选择“跳过此步骤”。
在 Firebase 控制台中,选择与项目相对应的齿轮图标。 然后,选择“项目设置”。
如果尚未将 google-services.json 文件下载到你的 Android Studio 项目的 app 文件夹中,则可以在此页面上执行此操作。
切换到顶部的“Cloud Messaging”选项卡。
复制并保存服务器密钥以供将来使用。 您可以使用此值来配置集线器。
配置 Azure 以发送推送请求
在 Azure 门户中,单击“浏览所有”>“应用服务”,然后单击您的移动应用后端。 在 设置下,单击 应用服务推送,然后单击通知中心名称。
转到 Google (GCM),输入在上一过程中从 Firebase 获取的 服务器密钥 值,然后单击“保存”。
移动应用后端现已配置为使用 Firebase Cloud Messaging。 这样,便可以使用通知中心将推送通知发送到在 Android 设备上运行的应用。
更新服务器项目以发送推送通知
在本部分中,将更新现有移动应用后端项目中的代码,以每次添加新项时发送推送通知。 此过程由 Azure 通知中心的 模板 功能提供支持,该功能支持跨平台推送。 各种客户端都使用模板注册推送通知,单个通用推送可以访问所有客户端平台。
选择以下过程之一,该过程应与您的后端项目类型匹配:.NET 后端 或 Node.js 后端。
.NET 后端项目
在 Visual Studio 中,右键单击服务器项目。 然后选择 管理 NuGet 包。 搜索
Microsoft.Azure.NotificationHubs
,然后选择 安装。 此过程安装通知中心库,用于从后端发送通知。在服务器项目中,打开 控制器>TodoItemController.cs。 然后使用以下语句添加:
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"); }
此过程发送包含项的模板通知。插入新项时的文本。
重新发布服务器项目。
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 的模板通知。
在本地计算机上编辑该文件时,请重新发布服务器项目。
为推送通知配置客户端项目
在解决方案视图(或 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; } }
这样,便可以从推送处理程序服务进程访问移动客户端实例。
创建 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 现已准备好添加推送通知。
向应用添加推送通知代码
在项目中创建一个名为
ToDoBroadcastReceiver
的新类。将以下 using 语句添加到 ToDoBroadcastReceiver 类:
using Gcm.Client; using Microsoft.WindowsAzure.MobileServices; using Newtonsoft.Json.Linq;
在 using 语句和 命名空间 声明之间添加以下权限请求:
[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 ,并且 服务 属性必须应用于此类。
注释
GcmServiceBase 类实现 OnRegistered()、OnUnRegistered()、OnMessage() 和 OnError() 方法。 必须在 PushHandlerService 类中重写这些方法。
将以下代码添加到替代 OnRegistered 事件处理程序的 PushHandlerService 类。
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 注册 ID 向 Azure 注册以获取推送通知。 只能在创建标记后将其添加到注册中。 有关详细信息,请参阅 如何将标签添加到设备安装以启用标记推送。
使用以下代码替代 PushHandlerService 中的 OnMessage 方法:
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)); }
在应用中测试推送通知
可以在模拟器中使用虚拟设备测试应用。 在模拟器上运行时,还需要执行其他配置步骤。
虚拟设备必须在 Android 虚拟设备(AVD)管理器中将 Google API 设置为目标。
单击 “应用>设置>添加帐户”,将 Google 帐户添加到 Android 设备,然后按照提示作。
像以前一样运行待办事项列表应用,并插入新的待办事项项。 这一次,通知区域会显示一个通知图标。 可以打开通知抽屉以查看通知的全文。