[Xamarin.Android] 结合Windows Azure与Google cloud message 来实现Push Notification

这一篇要讨论如何使用Xamarin.Android整合GCM以及Windows Azure来实作Android手机上的推播通知服务。

这篇文章比较着重概念的部分,在开始读这篇之前,也可以先参考一下Xamarin网站上的文章原文来了解Android GCM的运作逻辑:

RemoteNotificationsAn Overview of Remote Notifications inXamarin.Android

http://docs.xamarin.com/guides/cross-platform/application_fundamentals/notifications/android/remote_notifications_in_android


1. GCM Overview

GCM(Google cloudmessaging )Google提供的一个免费的 Service,这个Service功能是在handlessendingroutingqueuingService端要推播给你手机的讯息。

若你的手机要能接收从GCM传送的讯息,你的手机上必须要有安装Google ServiceFrameworkGoogle Service Framework是在你的手机上有安装Google Play Application的时候会自动安装起来。在你的手机开机执行的时候,Google Service FrameworkRun在背景执行程序中。然后在背景程序里面接听GCM传送过来的讯息。接着它会负责将讯息反串行化给注册在App中的Intents或是broadcast


[Xamarin.Android] 结合Windows Azure与Google cloud message 来实现Push Notification_第1张图片


2. GCMRequirements

4kb message limit -你要推送的讯息大小不可以超过4kb

Android 2.2-你的Android devices必须runAndroid 2.2(API level 8)以上的版本。

Google Play Store – Android Devices必须有安装Google Play Store。如果你要在仿真器上测试GCM功能的话,仿真器上就需要有安装Google APIs

Google Account-如果你的Android Device目前run的版本低于4.0.4的话,你就需要申请一个Google Account


3.Google CloudMessaging in Action


3.1 AppGCM注册流程

App在一开始行时,App必须先向GCM注册。注册完成,GCM会回传一个registration IDApp

这个registrationID是你的App run在这个AndroidDevice的唯一识别。这个App会负责传送registrationIDServer Application。当ServerApplication收到了registration ID后,目前这个注册的流程才被视为完成。



*官方是说这个registration ID不是常常更改,所以你不需要在每次App被启用的时候都去Run这个注册过程。

如果GCM要改变registration IDGCM会在发送个通知给Android Application


3.1 ServerApplication 推播讯息给Android Device流程

Server Application要发送一个推播通知到Client端的时候,Server Application会把Message送给GCMGCM会负责传送这个讯息给DeviceGCM允许Server Application一次指定1000个接受讯息者。


[Xamarin.Android] 结合Windows Azure与Google cloud message 来实现Push Notification_第2张图片


* 如果当Server尝试要推播信息给一个Device,而这个Device刚好是脱机的状态。(ex.关机中,收不到讯号)。

GCMQueue着这个讯息,等到Device重新连上线时,GCM会再重新传送这个讯息。不过GCM只会传送近期的讯息,这个设计是为了避免一些过期的信息或是重复性的讯息。(ex.你的Server正在推播一些限时优惠,但是使用者可能是关机的状态,等使用者重新启动后,这个限时优惠有可能已经过期了,这时候就没有在推播的必要。)

*如果使用者从手机上移除这个Application。但是Server application GCM都还不知道这个DeviceApp已经被移除了。这个推播讯息会继续被传送到Device上。不过Google Services Framework会接收到Server Application推送过来的讯息,然后它会发现这个App已经在手机上被移除了。这时候这个Device会回送一个讯息给GCM,告知GCM这个registration ID已经无效了。


3.3 GCM尝试推播信息给一个已经移除APPAndroid Device流程

Server application尝试推播一个讯息给一个已经无效的registration IDGCM会回传一个错误讯息"Device Not Registered"。接着Server application就可以负责在它储存registration ID的数据库列表中移除掉已经失效的registration ID


[Xamarin.Android] 结合Windows Azure与Google cloud message 来实现Push Notification_第3张图片


4.Setting UpGoogle Cloud Messaging

要建立一个整合GCM功能的App,有底下三个主要步骤要执行:

1.建立一个Google API Project –必须建立一个Google API项目,然后启用CGM服务与建立所对应的API Key

2.开发一个Android App –这边可以建立或者是维护一个Android App

3.建立一个Server Application –这个Server Application是负责推送讯息给Device。这个Server Application可以是任何平台来假设,例如ASP.NetPHP…。在这一次的范例我先用Windows Azure来担任Server Application

所以在这个范例中主要的执行流程如下:

1. 前往Google APIs网站上启用 Google CloudMessage服务。

2. 建立API钥匙。

3. Windows Azure上建立Mobile Service

4. Windows Azure上输入CGMAPI Key

5. Visual Studio 2012里面新建一个AndroidApplication项目。

6. 修改程序项目程序

4.1Creating aGoogle API Project

4.1.1在开始Google Cloud Message前,首先要在Google apis里面建立一个Project.

请连结底下的网址来登入Google apis:

(https://code.google.com/apis/console/)


[Xamarin.Android] 结合Windows Azure与Google cloud message 来实现Push Notification_第4张图片


4.1.2完成建立Google apis project之后,可以在网址列上看见你的Project ID。稍后会在建立Android App时用到这个Project ID


[Xamarin.Android] 结合Windows Azure与Google cloud message 来实现Push Notification_第5张图片


4.1.3接着在Google apis网站上,点选左边的Services按钮。这时会看到中间的网页部分List出所有的Service服务。



4.1.4在下方找到Google Cloud Messaging for Android这个服务,然后把它开启。


[Xamarin.Android] 结合Windows Azure与Google cloud message 来实现Push Notification_第6张图片


4.1.5然后点选左边的API Access,这个步骤我们要建立一个API Key,这个Key是要给Server Application所使用的。

在这个页面中间下方,点选下方[Create Android key]


[Xamarin.Android] 结合Windows Azure与Google cloud message 来实现Push Notification_第7张图片


4.1.6在弹出的Configure Server Key for Xamarin Evolve GCMExample对话筐中,在Accept requestsfrom these server IP adderss下方输入你的GCM允许从那些IP位置来的Server Application可以传送推播讯息。若你在这边没有输入特定的IP位置,那就代表默认你允许任何IP位置来的Server Application要求这个GCM执行推播讯息的动作。


[Xamarin.Android] 结合Windows Azure与Google cloud message 来实现Push Notification_第8张图片


4.1.7 建立完成可以看到一个Key for server apps,底下的API Key会是在你建立Server Application时所需要的必要项目。


[Xamarin.Android] 结合Windows Azure与Google cloud message 来实现Push Notification_第9张图片


4.2Create theAndroid Application

在建立Android App时,首先很重要的是要取得Google API Project ID,这是作为App中的Sender ID

接下来会有三个主要的步骤要处理:

1.权限(Permissions):一个Android application必须要设定权限可以使用Internet以及从GCM接收讯息。

2.广播接受器(BroadcastReceiver:GCM要推送一个讯息到Android DeviceDevice上的背景程序Google Service Framework会负责接收由GCM推送过来的讯息,接着Google Service Framework会把这个讯息在传送给App

在这个App里面我们就要建立一个广播接受器(BroadcastReceiver),来接收一个由Google Service Framework送过来的讯息。

3.IntentService:当广播接受器(BroadcastReceiver)并不会去对讯息做一些处理,如果要处理这些讯息,广播接受器会启动一个IntentService来处理接收到的讯息。


4.2.1. DeclarePermissions

l Android Application里面我们有几个权限必须要宣告,

l android.permission.INTERNET–要与GCM互动,必须允许APP有连接网络的权限。

l android.permission.WAKE_LOCK – 这是要防止在处理关于推播通知时,处理器不会进入睡眠状态。

l com.google.android.c2dm.permission.RECEIVE-这是让App有权限去向GCM注册以及接收GCM要推播的讯息。

l <package_name>.permission.C2D_MESSAGE -这个权限有两个目的,告知我们的Device这个APP可以去接收所有C2D_Messages。也告知Device没有其他的Application可以接收这些讯息。


// This will prevent other apps on the device from receiving GCM messages for this app
// It is crucial that the package name does not start with an uppercase letter - this is forbidden by Android.
[assembly: Permission(Name ="xamarin.sample.com.permission.C2D_MESSAGE")]
[assembly: UsesPermission(Name ="xamarin.sample.com.permission.C2D_MESSAGE")]

// Gives the app permission to register and receive messages
[assembly: UsesPermission(Name ="com.google.android.c2dm.permission.RECEIVE")]

// This permission is necessary only for Android 4.0.3 and below.
[assembly: UsesPermission(Name ="android.permission.GET_ACCOUNTS")]

// Need to access the internet for GCM
[assembly: UsesPermission(Name ="android.permission.INTERNET")]

// Needed to keep the processor from sleeping when a message arrives
[assembly: UsesPermission(Name = "android.permission.WAKE_LOCK")]

4.2.2. Creatinga Broadcast Receiver

接下来建立一个BroadcastReceiver类别,这个会接听以下从GCM回传的Intent:

com.google.android.c2dm.intent.RECEIVE–这是接收GCM推播的讯息。

com.google.android.c2dm.intent.REGISTRATION–这是接收前往GCM注册相关的讯息。

com.google.android.gcm.intent.RETRY–这是接收重新尝试前往GCM注册的讯息。


下方是建立BroadcastReceiver类别的范例程序:


[BroadcastReceiver(Permission= "com.google.android.c2dm.permission.SEND")]
[IntentFilter(new string[] { "com.google.android.c2dm.intent.RECEIVE" }, Categories = new string[] {"@PACKAGE_NAME@" })]
[IntentFilter(new string[] { "com.google.android.c2dm.intent.REGISTRATION" }, Categories = new string[] {"@PACKAGE_NAME@" })]
[IntentFilter(new string[] { "com.google.android.gcm.intent.RETRY" }, Categories = new string[] { "@PACKAGE_NAME@"})]
public class MyGCMBroadcastReceiver : BroadcastReceiver
{
	const string TAG = "PushHandlerBroadcastReceiver";
	public override void OnReceive(Context context, Intent intent)
	{
		MyIntentService.RunIntentInService(context, intent);
		SetResult(Result.Ok, null, null);
	}
}

4.2.3. AndroidManifest.xml里面新增底下的权限 to supportthe receiver:

<uses-permissionandroid:name="android.permission.RECEIVE_BOOT_COMPLETED" />

4.2.4. Creatingthe IntentService

BroadcastReceiver里面不应该包括着处理通知讯息的逻辑,所以我们这边要在撰写一个IntentService类别,让这个Serveice来负责处理当收到讯息时要和用户进行的互动。


在上一个小节,在BroadcastReceiverOnReceive事件里面呼叫了MyIntentService.RunIntentInService(context, intent);

这个方法。可以看到这个方法是被宣告在MyIntenService类别里面的一个静态方法。而在下方Service类别中,里面有一段intent.Action;宣告,表示你可以经由这个宣告来判定目前所接收到的讯息到底是由AppGCM注册后得到回传的讯息还是由GCM发起推播,Device接收到讯息?


[Service]
public class MyIntentService : IntentService
{
	static PowerManager.WakeLock sWakeLock;
	static object LOCK = new object();

	static void RunIntentInService(Context context, Intent intent)
	{
		lock (LOCK)
		{
			if (sWakeLock == null)
			{
			// This is called from BroadcastReceiver, there is no init.
			var pm = PowerManager.FromContext(context);
			WakeLock = pm.NewWakeLock(
			WakeLockFlags.Partial, "My WakeLock Tag");
			}
		}

		sWakeLock.Acquire();
		intent.SetClass(context, typeof(MyIntentService));
		context.StartService(intent);
	}
	protected override void OnHandleIntent(Intent intent)
	{
		try
		{
			Context context = this.ApplicationContext;
			string action = intent.Action;

			if (action.Equals("com.google.android.c2dm.intent.REGISTRATION"))
			{
				HandleRegistration(context, intent);
			}
			else if (action.Equals("com.google.android.c2dm.intent.RECEIVE"))
			{
				HandleMessage(context, intent);
			}
		}
		finally
		{
			lock (LOCK)
			{
				//Sanity check for null as this is a public method
				if (sWakeLock != null)
					sWakeLock.Release();
			}
		}
	}
}

4.2.5.Registering with Google Cloud Messaging

接下来就是了解Android App如何去向GCM做注册的动作。在Android Application要去向GCM注册前,首先Android App会传送一个com.google.android.c2dm.intent.REGISTERIntentGCM

这个Intent会需要两个参数值:

app – 这是一个允许Google Services Framework去向Application取得向GCM注册必要信息的PendingIntent

Sender- 这是一个用逗号分隔字符串数组,里面包含着要推播信息给这个AppSender IDs


请参考下方的Sample code


string senders = "<google cloud="" messaging="" sender="">";
Intent intent = new Intent("com.google.android.c2dm.intent.REGISTER");
intent.SetPackage("com.google.android.gsf");
intent.PutExtra("app", PendingIntent.GetBroadcast(context, 0, new Intent(), 0));
intent.PutExtra("sender", senders);
context.StartService(intent);</google>

4.3 Roles of theApplication Serv


在这一篇我们是用Window Azure来当作我们的ServerApplication。在Windows Azure上要执行的步骤有底下几个:


1. 建立一个Mobile Service

在Windows Azure网站上按[New]的项目,然后选择建立Mobile Service



这边需要自定一个Mobile Service URL名称。到这个步骤WindowsAzure Mobile Service就建立完成。


[Xamarin.Android] 结合Windows Azure与Google cloud message 来实现Push Notification_第10张图片


2. 建立一个todoitem数据库

点选到刚刚建立的Mobile Service,展开画面中间下方的[CREATE A NEWANDROID APP],在中间找到[Create a table]。这边Windows Azure会帮我们在Windows Azure上面建立一个[Todoitem]数据库。



3. 新增你的API KeyWindows Azure

点选Windows Azure上方的PUSH项目,找到[Google Cloud messaging settings],把在Google apis里面建立的API Key贴过来。在Windows Azure的设定到目前为止就完成了。


[Xamarin.Android] 结合Windows Azure与Google cloud message 来实现Push Notification_第11张图片
[Xamarin.Android] 结合Windows Azure与Google cloud message 来实现Push Notification_第12张图片


4. 新增Server siteScript


function insert(item, user, request) {
	request.execute({
		success: function() {
			// Write to the response and then send the notification in the background
			request.respond();
			push.gcm.send(item.channel, item.text, {
				success: function(response) {
					console.log('Push notification sent: ', response);
					}, error: function(error) {
			console.log('Error sending push notification: ', error);
				}
			});
		}
	})
}

4.4 测试Android App

要能在仿真器上测试GCM,你的仿真器必须要有支持with Google Apps的仿真器。

范例程序可从Xamarin的网站下载。

http://components.xamarin.com/view/azure-mobile-services/

这个范例需要根据Windows Azure的数据库结构做一些微调,在我的测试中,我在Android应用程序中新增了文字之后,按下Add Item的按钮。


[Xamarin.Android] 结合Windows Azure与Google cloud message 来实现Push Notification_第13张图片


可以看到Android手机的左上角出现了一个小icon


[Xamarin.Android] 结合Windows Azure与Google cloud message 来实现Push Notification_第14张图片


下拉这一个icon,可以看到GCM送来的通知项目。


[Xamarin.Android] 结合Windows Azure与Google cloud message 来实现Push Notification_第15张图片


这时我们回到Windows Azure的数据库上去查询刚刚被我们写入的资料,可以看到多了一笔我们刚刚新增的资料。

在这边有两个部分比较重要,第三个complete字段里面是一个false值,这个字段是用来判断使用者到底读取了这则讯息没有。

第四个channel字段里面记载的就是AndroidDeviceGCM注册后,GCM回传的registrationID


[Xamarin.Android] 结合Windows Azure与Google cloud message 来实现Push Notification_第16张图片


回到Android Device点选到刚刚推播过来的讯息,这时信息已经被读取。接着再回到Windows Azure查询数据库,可以看见complete字段的属性被改成true





参考文献

RemoteNotifications

http://docs.xamarin.com/guides/cross-platform/application_fundamentals/notifications/android/remote_notifications_in_android

Get started withpush notifications in Mobile Services

http://www.windowsazure.com/en-us/develop/mobile/tutorials/get-started-with-push-android/


转载自:昕力大学




你可能感兴趣的:([Xamarin.Android] 结合Windows Azure与Google cloud message 来实现Push Notification)