Skip to content
GCM Implement with HTTP
Java Groovy
Branch: master
Clone or download
Fetching latest commit…
Cannot retrieve the latest commit at this time.
Permalink
Type Name Latest commit message Commit time
Failed to load latest commit information.
GCMClientImplement
GCMServerImplement
README.md

README.md

Google Cloud Message(GCM)是Google提供給開發者使用的推播服務平台(Push Notification Service) 其前身稱為Android Cloud to Device Messaging(C2DM),此於Android 2.2(Froyo)開始支援 在2012/6/27更名為Google Cloud Message(在Android 4.1發佈前)

GCM主要功能是透過Google的連結伺服器發佈信息給Android的裝置,藉此達到通知的功能 舉例來說:A在B的FB塗鴉牆上留言,FB將藉由推播系統通知B說"有人在你塗鴉牆留言",這時候B的手機就會跳出通知來了唷。 **不過!**這個例子其實不太正確,原因是FB並不是使用GCM達到這些功能的,Facebook使用MQTT這項技術自行架設推播服務平台,這樣一來就不會受限於Google了! 若你有安裝Facebook APP的話可以在 設定 -> 應用程式管理 -> 執行中 點擊該應用程式來看即會看到如下畫面: MqttPushService即是一支背景程式負責接收來自FB的推播訊息
Screenshot_2014-09-23-16-54-11[1].png


在開發上,GCM的應用主要架構如下圖所示:

GCM Architecture


(Reference: [https://developer.android.com/google/gcm/gcm.html](https://developer.android.com/google/gcm/gcm.html))

其中3rd-Party App Server是指由開發者所架設的伺服器,是訊息發布的來源,connection server只是當成轉傳中繼站。(至於Google公司有沒有把所有訊息備份下來我就不清楚了XD)

看到這裡可能會有人覺得納悶,為何不要直接第三方主機直接對手機傳送訊息就好? 這是由於手機有可能處於NAT網路後面,並不是固定IP,這時伺服器就無法主動找到手機發布訊息了,Connection Server就是解決連線問題的存在。 這也是許多APP應用上使用Push Notification Service的原因,至於是怎麼樣解決連線問題可以尋找一些關鍵技術: XMPPMQTTHTTP Binding


接下來將透過範例來說明整個GCM的運作過程,在開始前先提醒開發者,網路上可以找到許多GCM的實作案例,但是**Google官方在Android 3.1之後將實作的部分整合成API GoogleCloudMessaging,有些實作方式已經被棄用了!**
  • Get API Key

    首先,想要在第三方伺服器上使用GCM的推播服務需要先向Google申請使用API的金鑰。 所以請開發者先到**Google Developers Console**申請專案與開啟API Key

    • Create Project
    create_project.png


創建完後即可得到所謂的SenderID即是下圖中的Project Number,這會在APP的程式中使用到。
senderid.png

  • Apply API

enableGCM.png

* Get Server Key

getkey.png


按下後會詢問指定伺服器IP,可以選擇不填寫,這樣任何IP都能使用這一組金鑰,如下圖所示,紅色框起來的部分就是產生的金鑰,隨後需要放到第三方伺服器的程式碼之中。

key.png


+ Implement 3rd-party Server

在實作第三方伺服器時有兩種選擇,主要是選擇Connection Server的種類:HTTP or XMPP。 兩者的差異可參考**Android官方說明**,本篇將介紹使用HTTP的方法,透過JSON檔將要推播的訊息進行封裝,藉由HTTP POST的方式傳送到Connection Server轉發給各推播對象。

這個Server主要有三個功能:註冊regID註銷regID推播訊息regID是由Android裝置向Google取得的一串識別碼,在選擇推播對象時即是使用此碼,為此Server需要將regID儲存起來,作為推播時的**"收件者"。 當然有註冊就有註銷的功能,是為了讓APP端選擇終止推播服務時不會再被推播打擾,這點很重要,是因為在APP端並無法透過API註銷**!這點將在後面做說明。

在此提供我實作的程式碼**GCMImplement,這是依據Google官方所提供的範例程式**修改而成(沒甚麼改才對XD)。 這邊提供我實作上的步驟與問題: 我使用的IDE是Intellij與架設Tomcat Server。

  • Create Project

new_project.png


如果是第一次設定的下需要指定Tomcat Server的家目錄位址

indicate_server.png

  • Modify API Key
    在[project_home]/web/WEB-INF/classes/api.key檔案中,將在Developers Console取得的API KEY換上即可。
  • Error – no json library with gcm server API
    Google所提供的範例程式碼會使用到JSON的library,創建新專案實並不會導入及編譯。
    可以透過下列方法解決:
    File -> Project Structure -> Libraries -> "+" -> "com.googlecode.json-simple:json-simple:1.1"

json.png


+ Implement Client(APP)

由於APP要使用GCM需要用到額外的libraries,所以在實作前請確認Android SDK是否有下載必要的library。
lib.png
在APP這邊主要歸分為三大類功能:取得regID註冊或註銷regID處理推播訊息

  • 取得regID
    在取得regID的部分主要透過API GoogleCloudMessaging進行,將想要接收的SenderID進行註冊,SenderID可以是多個來源。
    主要程式碼如下:
String[] SENDER_ID = {"1011748981590", "75870242865"};
GoogleCloudMessaging gcm;
gcm = GoogleCloudMessaging.getInstance(getApplicationContext());
String regid = gcm.register(SENDER_ID);

Register.png

Screenshot_2014-09-24-22-56-55.png

  • 註冊或註銷regID
    向Server註冊或註銷的功能主要都在ServerUtilities.java這支程式裡。在取得regID後,即可透過**HTTP Request(POST)**的方式將regID送至第三方伺服器進行儲存。而在用戶端如果想要終止推播功能的話,則可透過向Server註銷regID的方式達成。這時有人可能會問,GoogleCloudMessaging有提供unregister的API使用,怎麼還要註銷在Server所儲存的regID?
    官方的解釋為unregister的功能為使用在更新取的新的regID使用,註銷後重新透過register功能再向Google索取新的ID,經過測試確實unregister功能呼叫後,APP仍可接收到由Server推播出來的訊息

  • 處理推播訊息
    在處理推播訊息上,由前面介紹的內容可知,GCM機制透過內建於Android系統內的Gcm service發送廣播(Broadcast)給各APP,所以在APP的部分就由BroadcastReceiver進行接收處理。
    由於應用程式常不在前景運作,故BroadcastReceiver會啟動Service去處理相關的事情,在程式碼中的GcmIntentService.java即是處理訊息的Service,將由GcmService傳來的Intent擷取出Bundle找出夾帶訊息,所要得出的值(value)需要一把鑰匙(key),這個鑰匙及是在第三方伺服器傳送時使用Message API實所封裝的,如下列程式碼中的**"message"**

Message message = new Message.Builder().addData("message", userMessage).build();

sendnotification.png


至於Connection Server到手機的這個步驟可以透過adb shell command看到手機一直使用HTTP Binding的方式連結著Server,如下圖所示。

binding.png

You can’t perform that action at this time.