• [Xamarin.Android] 結合Windows Azure與Google cloud message 來實現Push Notification (转帖)


    這一篇要討論如何使用Xamarin.Android 整合GCM以及Windows Azure來實作Android手機上的推播通知服務。

    這篇文章比較著重概念的部分,在開始讀這篇之前,也可以先參考一下Xamarin網站上的文章原文來了解Android GCM的運作邏輯:

    Remote Notifications:An Overview of Remote Notifications in Xamarin.Android

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

     

    1. GCM Overview

    GCM(Google cloud messaging )是Google提供的一個免費的 Service,這個Service功能是在handles,sending,routing,queuing從Service 端要推播給你手機的訊息。

    若你的手機要能接收從GCM傳送的訊息,你的手機上必須要有安裝Google Service Framework。Google Service Framework是在你的手機上有安裝Google Play Application的時候會自動安裝起來。在你的手機開機執行的時候,Google Service Framework會Run在背景執行程序中。然後在背景程序裡面接聽GCM傳送過來的訊息。接著它會負責將訊息反序列化給註冊在App中的Intents 或是broadcast。

    clip_image002

     

    2. GCM Requirements

    •  4kb message limit -你要推送的訊息大小不可以超過4kb。
    •  Android 2.2-你的Android devices必須run在Android 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 Cloud Messaging in Action

    3.1 App GCM註冊流程

    App在一開始行時,App必須先向GCM註冊。註冊完成,GCM會回傳一個registration ID給App。

    這個registration ID是你的App run在這個Android Device的唯一識別。這個App會負責傳送registration ID給Server Application。當Server Application收到了registration ID後,目前這個註冊的流程才被視為完成。

    clip_image004

    *官方是說這個registration ID不是常常更改,所以你不需要在每次App被啓用的時候都去Run這個註冊過程。

    如果GCM要改變registration ID,GCM會在發送個通知給Android Application。

     

    3.1 Server Application 推播訊息給Android Device流程

    在Server Application要發送一個推播通知到Client端的時候,Server Application會把Message送給GCM,GCM會負責傳送這個訊息給Device。GCM允許Server Application一次指定1000個接受訊息者。

    clip_image006

    * 如果當Server嘗試要推播資訊給一個Device,而這個Device剛好是離線的狀態。(ex.關機中,收不到訊號)。

    GCM會Queue著這個訊息,等到Device重新連上線時,GCM會再重新傳送這個訊息。不過GCM只會傳送近期的訊息,這個設計是為了避免一些過期的資訊或是重複性的訊息。(ex.你的Server正在推播一些限時優惠,但是使用者可能是關機的狀態,等使用者重新開機後,這個限時優惠有可能已經過期了,這時候就沒有在推播的必要。)

    *如果使用者從手機上移除這個Application。但是Server application 與 GCM都還不知道這個Device上App已經被移除了。這個推播訊息會繼續被傳送到Device上。不過Google Services Framework會接收到Server Application推送過來的訊息,然後它會發現這個App已經在手機上被移除了。這時候這個Device會回送一個訊息給GCM,告知GCM這個registration ID已經無效了。

     

    3.3 GCM嘗試推播資訊給一個已經移除APPAndroid Device流程

    當Server application嘗試推播一個訊息給一個已經無效的registration ID,GCM會回傳一個錯誤訊息"Device Not Registered"。接著Server application就可以負責在它儲存registration ID的資料庫列表中移除掉已經失效的registration ID

    clip_image008

     

    4. Setting Up Google 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.Net,PHP…。在這一次的範例我先用Windows Azure來擔任Server Application。

    所以在這個範例中主要的執行流程如下:

    1. 前往Google APIs網站上啓用 Google Cloud Message服務。

    2. 建立API鑰匙。

    3. 在Windows Azure上建立Mobile Service。

    4. 在Windows Azure上輸入CGM的API Key。

    5. 在Visual Studio 2012裡面新建一個Android Application 專案。

    6. 修改程式專案程式

    4.1 Creating a Google API Project

    4.1.1在開始Google Cloud Message前,首先要在Google apis裡面建立一個Project.

    請連結底下的網址來登入Google apis:

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

    clip_image010

     

    4.1.2完成建立Google apis project之後,可以在網址列上看見你的Project ID。稍後會在建立Android App時用到這個Project ID。

    clip_image011

     

    4.1.3接著在Google apis網站上,點選左邊的Services按鈕。這時會看到中間的網頁部分List出所有的Service服務。

    clip_image013

     

    4.1.4在下方找到Google Cloud Messaging for Android 這個服務,然後把它開啓。

    clip_image015

     

    4.1.5然後點選左邊的API Access,這個步驟我們要建立一個API Key,這個Key是要給Server Application所使用的。

    在這個頁面中間下方,點選下方[Create Android key]。

    clip_image017

     

    4.1.6在彈出的Configure Server Key for Xamarin Evolve GCM Example對話筐中,在Accept requests from these server IP adderss下方輸入你的GCM允許從那些IP位置來的Server Application可以傳送推播訊息。若你在這邊沒有輸入特定的IP位置,那就代表預設你允許任何IP位置來的Server Application要求這個GCM執行推播訊息的動作。

    clip_image019

     

    4.1.7 建立完成可以看到一個Key for server apps,底下的API Key會是在你建立Server Application時所需要的必要項目。

    clip_image021

     

    4.2 Create the Android Application

    在建立Android App時,首先很重要的是要取得Google API Project ID,這是作為App中的Sender ID。

    接下來會有三個主要的步驟要處理:

    1. 權限(Permissions):一個Android application 必須要設定權限可以使用Internet以及從GCM接收訊息。

    2. 廣播接受器(BroadcastReceiver:當GCM要推送一個訊息到Android Device,Device上的背景程序Google Service Framework會負責接收由GCM推送過來的訊息,接著Google Service Framework會把這個訊息在傳送給App。

    在這個App裡面我們就要建立一個廣播接受器(BroadcastReceiver),來接收一個由Google Service Framework送過來的訊息。

    3. IntentService : 當廣播接受器(BroadcastReceiver)並不會去對訊息做一些處理,如果要處理這些訊息,廣播接受器會啓動一個IntentService來處理接收到的訊息。

     

    4.2.1. Declare Permissions

    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可以接收這些訊息。

    01 // This will prevent other apps on the device from receiving GCM messages for this app
    02 // It is crucial that the package name does not start with an uppercase letter - this is forbidden by Android.
    03 [assembly: Permission(Name = "xamarin.sample.com.permission.C2D_MESSAGE")]
    04 [assembly: UsesPermission(Name = "xamarin.sample.com.permission.C2D_MESSAGE")]
    05  
    06 // Gives the app permission to register and receive messages.
    07 [assembly: UsesPermission(Name = "com.google.android.c2dm.permission.RECEIVE")]
    08  
    09 // This permission is necessary only for Android 4.0.3 and below.
    10 [assembly: UsesPermission(Name = "android.permission.GET_ACCOUNTS")]
    11  
    12 // Need to access the internet for GCM
    13 [assembly: UsesPermission(Name = "android.permission.INTERNET")]
    14  
    15 // Needed to keep the processor from sleeping when a message arrives
    16 [assembly: UsesPermission(Name = "android.permission.WAKE_LOCK")]

     

     

     

    4.2.2. Creating a 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類別的範例程式:

    01 [BroadcastReceiver(Permission= "com.google.android.c2dm.permission.SEND")]
    02 [IntentFilter(new string[] { "com.google.android.c2dm.intent.RECEIVE" }, Categories = new string[] {"@PACKAGE_NAME@" })]
    03 [IntentFilter(new string[] { "com.google.android.c2dm.intent.REGISTRATION" }, Categories = new string[] {"@PACKAGE_NAME@" })]
    04 [IntentFilter(new string[] { "com.google.android.gcm.intent.RETRY" }, Categories = new string[] { "@PACKAGE_NAME@"})]
    05 public class MyGCMBroadcastReceiver : BroadcastReceiver
    06 {
    07     const string TAG = "PushHandlerBroadcastReceiver";
    08     public override void OnReceive(Context context, Intent intent)
    09     {
    10         MyIntentService.RunIntentInService(context, intent);
    11         SetResult(Result.Ok, null, null);
    12     }
    13 }

     

     

    4.2.3. AndroidManifest.xml裡面新增底下的權限 to support the receiver:

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

     

     

    4.2.4. Creating the IntentService

    BroadcastReceiver裡面不應該包括著處理通知訊息的邏輯,所以我們這邊要在撰寫一個IntentService類別,讓這個Serveice來負責處理當收到訊息時要和使用者進行的互動。

    在上一個小節,在BroadcastReceiver的OnReceive事件裡面呼叫了MyIntentService.RunIntentInService(context, intent);

    這個方法。可以看到這個方法是被宣告在MyIntenService類別裡面的一個靜態方法。而在下方Service類別中,裡面有一段intent.Action;宣告,表示你可以經由這個宣告來判定目前所接收到的訊息到底是由App向GCM註冊後得到回傳的訊息還是由GCM發起推播,Device接收到訊息?

    01 [Service]
    02 public class MyIntentService : IntentService
    03 {
    04     static PowerManager.WakeLock sWakeLock;
    05     static object LOCK = new object();
    06  
    07     static void RunIntentInService(Context context, Intent intent)
    08     {
    09         lock (LOCK)
    10         {
    11             if (sWakeLock == null)
    12             {
    13                 // This is called from BroadcastReceiver, there is no init.
    14                 var pm = PowerManager.FromContext(context);
    15                 sWakeLock = pm.NewWakeLock(
    16                 WakeLockFlags.Partial, "My WakeLock Tag");
    17             }
    18         }
    19  
    20         sWakeLock.Acquire();
    21         intent.SetClass(context, typeof(MyIntentService));
    22         context.StartService(intent);
    23     }
    24  
    25     protected override void OnHandleIntent(Intent intent)
    26     {
    27         try
    28         {
    29             Context context = this.ApplicationContext;
    30             string action = intent.Action;
    31  
    32             if (action.Equals("com.google.android.c2dm.intent.REGISTRATION"))
    33             {
    34                 HandleRegistration(context, intent);
    35             }
    36             else if (action.Equals("com.google.android.c2dm.intent.RECEIVE"))
    37             {
    38                 HandleMessage(context, intent);
    39             }
    40         }
    41         finally
    42         {
    43             lock (LOCK)
    44             {
    45                 //Sanity check for null as this is a public method
    46                 if (sWakeLock != null)
    47                     sWakeLock.Release();
    48             }
    49         }
    50     }
    51 }

     

     

     

    4.2.5. Registering with Google Cloud Messaging

     

    接下來就是了解Android App如何去向GCM做註冊的動作。在Android Application要去向GCM註冊前,首先Android App會傳送一個com.google.android.c2dm.intent.REGISTER Intent給GCM。

     

    這個Intent會需要兩個參數值:

    app – 這是一個允許Google Services Framework去向Application取得向GCM註冊必要資訊的PendingIntent。

    Sender- 這是一個用逗號分隔字串陣列,裡面包含著要推播資訊給這個App的Sender IDs。

     

    請參考下方的Sample code。

     

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

     

     

    4.3 Roles of the Application Server

    在這一篇我們是用Window Azure來當作我們的Server Application。在Windows Azure上要執行的步驟有底下幾個:

    1. 建立一個Mobile Service

    在Windows Azure網站上按[New]的項目,然後選擇建立Mobile Service。

    clip_image022

     

     

    這邊需要自定一個Mobile Service URL 名稱。到這個步驟Windows Azure Mobile Service就建立完成。

    clip_image024

     

     

    2. 建立一個todoitem資料庫

    點選到剛剛建立的Mobile Service,展開畫面中間下方的[CREATE A NEW ANDROID APP],在中間找到

    [Create a table]。這邊Windows Azure會幫我們在Windows Azure上面建立一個[Todoitem]資料庫。

    clip_image026

     

    3. 新增你的API KeyWindows Azure

    點選Windows Azure上方的PUSH項目,找到[Google Cloud messaging settings],把在Google apis裡面建立的API Key貼過來。在Windows Azure的設定到目前為止就完成了。

    clip_image028

     

    clip_image030

    4. 新增Server siteScript

     

    01 function insert(item, user, request) {
    02     request.execute({
    03         success: function() {
    04             // Write to the response and then send the notification in the background
    05             request.respond();
    06             push.gcm.send(item.channel, item.text, {
    07                 success: function(response) {
    08                     console.log('Push notification sent: ', response);
    09                 }, error: function(error) {
    10                     console.log('Error sending push notification: ', error);
    11                 }
    12             });
    13         }
    14     });
    15 }

     

     

     

    4.4 測試Android App

     

    要能在模擬器上測試GCM,你的模擬器必須要有支援with Google Apps的模擬器。

    範例程式可從Xamarin的網站下載。

     

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

    這個範例需要根據Windows Azure的資料庫結構做一些微調,在我的測試中,我在Android應用程式中新增了文字之後,按下Add Item的按鈕。

    clip_image032

     

    可以看到Android 手機的左上角出現了一個小icon。

    clip_image034

     

    下拉這一個icon,可以看到GCM送來的通知項目。

    clip_image035

    這時我們回到Windows Azure的資料庫上去查詢剛剛被我們寫入的資料,可以看到多了一筆我們剛剛新增的資料。

    在這邊有兩個部分比較重要,第三個complete欄位裡面是一個false值,這個欄位是用來判斷使用者到底讀取了這則訊息沒有。

    第四個channel欄位裡面記載的就是Android Device向GCM註冊後,GCM回傳的registration ID。

    clip_image037

    回到Android Device點選到剛剛推播過來的訊息,這時資訊已經被讀取。接著再回到Windows Azure查詢資料庫,可以看見complete欄位的屬性被改成true。

    clip_image039

    參考文獻

    Remote Notifications

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

    Get started with push notifications in Mobile Services

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

  • 相关阅读:
    linux nfs
    gsoap
    error: ignoring return value of 编译错误处理
    SSIS可靠性和扩展性—错误输出
    SSIS中的脚本—脚本组件
    SQL点滴24—监测表的变化(转载)
    SSIS中的脚本—脚本任务
    SSIS可靠性和扩展性—简介
    SSIS中的脚本—表达式
    SSIS可靠性和扩展性—可扩展性
  • 原文地址:https://www.cnblogs.com/whatthehell/p/3444386.html
Copyright © 2020-2023  润新知