Google Cloud Messaging (以下簡稱GCM),廣泛運用於各種APP上
何謂GCM? 如下圖框中所示
這就是GCM的主要功用了。
廢話不多說,馬上進入主題
GCM 是由Google提供的服務之一,詳情請到 Google Cloud Messaging for Android 觀看
如何運作的呢? 大致上流程是
一、手機進入APP時向Google取得一組Registration ID (以下簡稱RegID),再將RegID送回我們自己的Server上儲存
二、Server端廣播時,找出要廣播的RegID後,發向給Google GCM 的 Server
三、Google GCM Server幫我們向這些RegID發送訊息
實作部分
首先一定要有Google帳號~ 然後再到 Google Cloud Console
若之前無使用過Google的API 請新建一個專案(點擊 Create Project )囉~
然後會得到一組Project Number(若無找到,可以看網址上的一串數字也是專案號碼哦) 請將這組數字記下來 稍後會用到!!
之後 點選 APIs & auth 下的 APIs 找到 Google Cloud Messaging for Android 並把它改成ON的狀態
然後剛剛的APIs下有一個 Registered apps 點進去,點選上面的 REGISTER APP按鈕
輸入名稱,選擇類型 為 Android 下的 Accessing APIs via a web server
然後大力按下 Register 吧 快成功了 建立後會進入這個APP
如下圖,請把框中的API KEY記下來 等等會用到
然後開啟eclipsr吧~~~
再立馬開啟SDK Manager 安裝 Google Play Services
裝好之後建立一個Android 專案囉,至少要Android 2.3 以上
再來匯入jar檔
至SDK的安裝路徑 (..\sdk\extras\google\gcm\gcm-client\dist ) 下複製 gcm.jar
把他丟到傳案內的 libs 資料夾
再到 sdk\extras\google\google_play_services\libproject\google-play-services_lib\libs 路徑下
複製 google-play-services.jar 一樣丟到 libs
再到 \sdk\extras\google\gcm\samples\gcm-demo-client\src\com\google\android\gcm\demo\app
複製 ServerUtilities.java 、 GCMIntentService.java 、 CommonUtilities.java 到 專案下的 package
當然一開始會有錯誤
首先進入 CommonUtilities 修改使用參數
SERVER_URL -> 放置Server的IP位置
SENDER_ID -> Project Number
DISPLAY_MESSAGE_ACTION -> 填入完整的package名稱.DISPLAY_MESSAGE
package com.example.gcm_project; ... static final String SERVER_URL = "http://192.168.1.1:8080/gcm"; static final String SENDER_ID = "填入剛剛的Project Number"; static final String DISPLAY_MESSAGE_ACTION = "com.example.gcm_project.DISPLAY_MESSAGE"; ...
儲存
開啟 ServerUtilities 修改以下code
package com.example.gcm_project; import static com.example.gcm_project.CommonUtilities.SERVER_URL; import static com.example.gcm_project.CommonUtilities.TAG; import static com.example.gcm_project.CommonUtilities.displayMessage; ...
儲存後還是會有錯誤,由於使用一些gcm的string
以下code請加入string.xml 中
...
<string name="error_config">Please set the %1$s constant and recompile the app.</string>
<string name="already_registered">Device is already registered on server.</string>
<string name="gcm_registered">From GCM: device successfully registered!</string>
<string name="gcm_unregistered">From GCM: device successfully unregistered!</string>
<string name="gcm_message">From GCM: you got message!</string>
<string name="gcm_error">From GCM: error (%1$s).</string>
<string name="gcm_recoverable_error">From GCM: recoverable error (%1$s).</string>
<string name="gcm_deleted">From GCM: server deleted %1$d pending messages!</string>
<string name="server_registering">Trying (attempt %1$d/%2$d) to register device on Demo Server.</string>
<string name="server_registered">From Demo Server: successfully added device!</string>
<string name="server_unregistered">From Demo Server: successfully removed device!</string>
<string name="server_register_error">Could not register device on Demo Server after %1$d attempts.</string>
<string name="server_unregister_error">Could not unregister device on Demo Server (%1$s).</string>
<string name="options_register">Register</string>
<string name="options_unregister">Unregister</string>
<string name="options_clear">Clear</string>
<string name="options_exit">Exit</string>
...
再來開啟 GCMIntentService 修改一些code
package com.example.gcm_project; import static com.example.gcm_project.CommonUtilities.SERVER_URL; import static com.example.gcm_project.CommonUtilities.displayMessage; ...
目前這 3 個檔案算完成,開始撰寫主程式囉~
開啟 MainActivity 修改code
GoogleCloudMessaging gcm; private Context context; private String strRegId; private TextView tvRegisterMsg; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); tvRegisterMsg = (TextView)findViewById(R.id.action_settings); context = getApplicationContext(); gcm = GoogleCloudMessaging.getInstance(this); setGCM_RegID(); } // get GCM Reg ID and Save to our server (use ServerUtilities.java) public void setGCM_RegID() { registerReceiver(mHandleMessageReceiver, new IntentFilter( DISPLAY_MESSAGE_ACTION)); // register with Google. new AsyncTask<Void, String, String>() { @Override protected String doInBackground(Void... params) { String msg = ""; try { if (gcm == null) { gcm = GoogleCloudMessaging.getInstance(context); } strRegId = gcm.register(SENDER_ID); msg = "Device registered, registration id=" + strRegId; // send id to our server boolean registered = ServerUtilities.register(context, strRegId); } catch (IOException ex) { msg = "Error :" + ex.getMessage(); } return msg; } @Override protected void onPostExecute(String msg) { // tvRegisterMsg.append(msg + "\n"); } }.execute(null, null, null); } @Override protected void onDestroy() { super.onDestroy(); unregisterReceiver(mHandleMessageReceiver); // 在Activity // 消滅時才unregister } // Create a broadcast receiver to get message and show on screen private final BroadcastReceiver mHandleMessageReceiver = new BroadcastReceiver() { private final static String MY_MESSAGE = "com.stu.phonebook.DISPLAY_MESSAGE"; @Override public void onReceive(Context context, Intent intent) { if (MY_MESSAGE.equals(intent.getAction())) { final String newMessage = intent.getExtras().getString( EXTRA_MESSAGE); tvRegisterMsg.setText(newMessage); } } }; ...
修改所需要的權限~記得替換掉package的名稱哦 還有把全形" < "改成半形的
開啟 AndroidManifest.xml
... <permission android:name="com.example.gcm_project.permission.C2D_MESSAGE" android:protectionLevel="signature" /> <uses-permission android:name="com.example.gcm_project.permission.C2D_MESSAGE" /> <uses-permission android:name="android.permission.INTERNET" /> <uses-permission android:name="com.google.android.c2dm.permission.RECEIVE" /> <uses-permission android:name="android.permission.GET_ACCOUNTS" /> <uses-permission android:name="android.permission.WAKE_LOCK" /> <uses-permission android:name="android.permission.VIBRATE" />
於application中新增一個 receiver
... <receiver android:name="com.google.android.gcm.GCMBroadcastReceiver" android:permission="com.google.android.c2dm.permission.SEND" > <intent-filter> <action android:name="com.google.android.c2dm.intent.RECEIVE" /> <action android:name="com.google.android.c2dm.intent.REGISTRATION" /> <category android:name="com.example.gcm_project" /> </intent-filter> </receiver> <service android:name=".GCMIntentService" />
然後呢~需要建個收regId的 php 至於怎麼做...就收到存資料庫吧 很簡單
主要是要傳送GCM怎麼送呢~下面這個PHP 小範例 看一下吧
<?php // 這支程式就是將自己模擬成 client 端, // 發送 POST 給 Google GCM server // function sendModifyGCM($regID){ $regID = array(); array_push($regID, $_GET["regId"]); $apiKey = "google給你的那組key~~"; // Set POST variables $url = 'https://android.googleapis.com/gcm/send'; $message = $_GET['message']; $fields = array('registration_ids' => $regID, 'data' => array( 'message' => $message) ); $headers = array('Content-Type: application/json', 'Authorization: key='.$apiKey ); // Open connection $ch = curl_init(); // Set the url, number of POST vars, POST data curl_setopt( $ch, CURLOPT_URL, $url ); curl_setopt( $ch, CURLOPT_POST, true ); curl_setopt( $ch, CURLOPT_SSL_VERIFYPEER, false); curl_setopt( $ch, CURLOPT_HTTPHEADER, $headers); curl_setopt( $ch, CURLOPT_RETURNTRANSFER, true ); // Disabling SSL Certificate support temporarly // curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false); // 發送的訊息內容轉成 JSON 格式 curl_setopt( $ch, CURLOPT_POSTFIELDS, json_encode( $fields ) ); // 傳送到 Google GCM server, // 並接收回傳結果 $result = curl_exec($ch); // Close connection if ($result === FALSE) { die('Curl failed: ' . curl_error($ch)); } curl_close($ch); echo 'result =='.$result; // 這裡只是讓您知道訊息發送結果是否成功 // }
然後就~直接去測試吧!
GET 一組regId跟 message給他吧~
正常來說~沒意外的話 就能看到手機彈出來囉 記得把app刷進手機!
Sample code
留言列表