pom
<!-- https://mvnrepository.com/artifact/com.google.gcm/gcm-server --> <dependency> <groupId>com.google.gcm</groupId> <artifactId>gcm-server</artifactId> <version>1.0.0</version> </dependency>
Demo
Sender sender = new Sender("your_google_key");//需要去谷歌注冊,然后獲取你的key Message message = new Message.Builder().addData("標題", "消息體").build(); MulticastResult resultMulti = null; try { Integer retries = 5;//如果失敗重新發送的次數 List<String> appKeys = new ArrayList<>(); appKeys.add("手機的唯一標識"); resultMulti = sender.send(message, appKeys, retries); Integer successCount = resultMulti.getSuccess(); Integer failCount = resultMulti.getFailure(); // TODO:統計成功和失敗次數 return Boolean.TRUE; } catch (IOException e) { LOGGER.error("androidMessage send fail" + title + body); return Boolean.FALSE; }
轉載請注明出處:http://blog.csdn.net/newhope1106/article/details/54709916
GCM即Google Cloud Messaging,主要用於消息推送的,即使在應用沒有起來的情況下,客戶端也能通過GCM收到來自服務器的消息。GCM支持Android、IOS和Chrome。由於GCM需要google service支持,在國內基本不能用,經常會斷線,不過最近項目要求,只在美國上線該項目,因此可以采用GCM實現推送的方式,國內相關文章較少,特意整理了一下客戶端使用的官方文檔。
首先來看看目前應用不啟動實現推送的方式有哪些:
1.使用Google自帶的GCM實現推送
2.采用監聽開機廣播的方式,啟動后台服務,為了防止被殺死,采用多進程的方式,監聽服務是否被殺,被殺之后,把它拉起來(比較流氓)
3.采用第三發方案,如友盟、極光、信鴿
國內第二種和第三種用得比較多,本文主要講解第一種方案,也就是GCM,以下內容均來自官網
一、概述
GCM可以讓開發者在客戶端和服務器之間傳遞消息,有2種方式實現消息推送,一種是xmpp,它即可讓服務器把消息推送給客戶端,也可讓客戶端把消息推送給服務器,另一種方式是http,只能服務器將消息推送給客戶端,以下是其架構圖。
GCM服務器接收應用服務器的消息,然后再把消息轉發給客戶端,服務器端根據自己的需要實現xmpp或者http接口,和GCM服務器進行通信,客戶端想要接收消息,需要使用GCM提供的API。
二.客戶端使用GCM
1.使用限制:
a.最低要求Android 2.2+的設備,並且安裝了Google應用商店
b.想要使用GCM新特性,要求Android 2.3+
c.低於Android 4.0.4版本,需要Google賬號,Android 4.0.4+不需要
2.客戶端使用GCM流程
和使用一般的sdk類似,首先需要在官網注冊自己的應用,獲取一個appid,出於安全要求,需要在本地使用這個appid去獲取動態token,需要把token上傳給服務器,每隔一段時間token可能會失效,需要去重新獲取token。按照上面的過程我們來看看怎么使用的。以下針對Android Studio開發的。
(1)官網注冊應用
首先我們需要到這個網址:https://console.firebase.google.com/ 去注冊自己的應用,按照相關步驟操作之后,點擊下載配置文件,會下載一個叫google-services.json的文件,把它放到自己的項目的app/目錄下。
(2)添加配置文件解析插件依賴
上述下載的google-services.json需要插件進行解析,要在項目中按照下面步驟添加依賴
a.在項目級別(project-level)的build.gradle添加下面依賴
classpath 'com.google.gms:google-services:3.0.0'
b.在自己的應用級別(app-level)的build.gradle添加下面插件
apply plugin: 'com.google.gms.google-services'
(3)添加GCM依賴
代碼中需要用到gcm的api,因此需要添加gcm的依賴,版本請使用最新的版本,下面只是示范
dependencies {
compile "com.google.android.gms:play-services-gcm:10.0.0"
}
(4)修改AndroidMenifest.xml文件
a.添加權限,因為我們不允許其他的應用接收和發送屬於自己應用的消息,因此添加權限屏蔽其他應用,權限格式:<application-package-name> + ".permission.C2D_MESSAGE"
b.定義一個GcmReceiver接收器,用來接收發送給應用的消息,需要添加com.google.android.c2dm.permission.SEND權限
c.定義GcmListenerService服務器,用來處理各種不同的下發信息,上發狀態,自動顯示通知等
d.定義一個集成InstanceIDListenerService的服務,用來獲取、刷新token
e.額外的,可以添加android.permission.WAKE_LOCK權限,保證消息到達的時候,可以得到及時處理
以下是一個demo
<manifest package="com.example.gcm" ...>
<uses-sdk android:minSdkVersion="8" android:targetSdkVersion="17"/>
<uses-permission android:name="android.permission.WAKE_LOCK" />
<permission android:name="<your-package-name>.permission.C2D_MESSAGE"
android:protectionLevel="signature" />
<uses-permission android:name="<your-package-name>.permission.C2D_MESSAGE" />
<application ...>
<receiver
android:name="com.google.android.gms.gcm.GcmReceiver"
android:exported="true"
android:permission="com.google.android.c2dm.permission.SEND" >
<intent-filter>
<action android:name="com.google.android.c2dm.intent.RECEIVE" />
<category android:name="com.example.gcm" />
</intent-filter>
</receiver>
<service
android:name="com.example.MyGcmListenerService"
android:exported="false" >
<intent-filter>
<action android:name="com.google.android.c2dm.intent.RECEIVE" />
</intent-filter>
</service>
<service
android:name="com.example.MyInstanceIDListenerService"
android:exported="false">
<intent-filter>
<action android:name="com.google.android.gms.iid.InstanceID" />
</intent-filter>
</service>
<service
android:name="gcm.play.android.samples.com.gcmquickstart.RegistrationIntentService"
android:exported="false">
</service>
</application>
</manifest>
如果是android 4.4之前的版本,需要在receiver中添加的intent-filter中添加下面的action
<action android:name="com.google.android.c2dm.intent.REGISTRATION" />
3.客戶端獲取、刷新token
(1)先來看看獲取token的接口
String authorizedEntity = PROJECT_ID; // Project id from Google Developer Console
String scope = "GCM"; // e.g. communicating using GCM, but you can use any
// URL-safe characters up to a maximum of 1000, or
// you can also leave it blank.
String token = InstanceID.getInstance(context).getToken(authorizedEntity,scope);
上述的PROJECT_ID是在https://console.developers.google.com/project中注冊得到的,scope,可以自定義
(2)token的更新
在前面有提到AndroidMenifest.xml中注冊一個繼承InstanceIDListenerService的服務,看看具體的實現
public class MyInstanceIDService extends InstanceIDListenerService {
public void onTokenRefresh() {
refreshAllTokens();
}
private void refreshAllTokens() {
// assuming you have defined TokenList as
// some generalized store for your tokens
ArrayList<TokenList> tokenList = TokensList.get();
InstanceID iid = InstanceID.getInstance(this);
for(tokenItem : tokenList) {
tokenItem.token =
iid.getToken(tokenItem.authorizedEntity,tokenItem.scope,tokenItem.options);
// send this tokenItem.token to your server
}
}
}
第一次獲取token,雖然沒有獲取過token,但本質還是刷新,都是調用onTokenRefresh接口,並且把獲取的token發送給服務器。
上面的處理可以最好用一個IntentService來異步處理,不要放在主線程中,上述給一個使用范例而已。
(3)InstanceID
上面我們看到,獲取token的時候,首先需要InstanceID,當設備上線的時候,Instance ID Service會分配一個InstanceID, InstanceID是由一對公鑰和私鑰共同維護的,私鑰保存在本地,公鑰由Instance ID Service注冊產生。可以通過調用geId()方法,隨時更新InstanceId,因為生成的token都是依賴這個InstanceID的。
String iid = InstanceID.getInstance(context).getId();
你也可以刪除一個InstanceID,那么對應的所有token都會失效,用新的InstanceID生成新的token
InstanceID.getInstance(context).deleteInstanceID();
String newIID = InstanceID.getInstance(context).getId();
(4)Instance ID 的生命周期圖
4.客戶端接收服務器下發信息
a.服務器可以通過HTTP(單向)和XMPP(雙向)發送信息,看看下面的demo
HTTP POST Request
https://gcm-http.googleapis.com/gcm/send
Content-Type:application/json
Authorization:key=AIzaSyZ-1u...0GBYzPu7Udno5aA
{ "data": {
"score": "5x1",
"time": "15:10"
},
"to" : "bk3RNwTe3H0:CI2k_HHwgIpoDKCIZvvDMExUdFQ3P1..."
}
XMPP Message
<message id="">
<gcm xmlns="google:mobile:data">
{ "data": {
"score": "5x1",
"time": "15:10"
},
"to" : "bk3RNwTe3H0:CI2k_HHwgIpoDKCIZvvDMExUdFQ3P1..."
}
</gcm>
</message>
b.客戶端處理下發消息
服務器發送的消息,GCM會將接收到的消息轉發給客戶端,在前面的AndroidManifest.xml中,我們定義了一個GcmListenerService來處理消息,可以自己繼承GcmListenerService並且覆蓋onMessageReceived方法。
@Override
public void onMessageReceived(String from, Bundle data) {
String message = data.getString("message");
Log.d(TAG, "From: " + from);
Log.d(TAG, "Message: " + message);
if (from.startsWith("/topics/")) {
// message received from some topic.
} else {
// normal downstream message.
}
// ...
}
5.客戶端上發消息
public void onClick(final View view) {
if (view == findViewById(R.id.send)) {
new AsyncTask<void, void,="" string="" style="box-sizing: inherit;">() {
@Override
protected String doInBackground(Void... params) {
String msg = "";
try {
Bundle data = new Bundle();
data.putString("my_message", "Hello World");
data.putString("my_action","SAY_HELLO");
String id = Integer.toString(msgId.incrementAndGet());
gcm.send(SENDER_ID + "@gcm.googleapis.com", id, data);
msg = "Sent message";
} catch (IOException ex) {
msg = "Error :" + ex.getMessage();
}
return msg;
}
@Override
protected void onPostExecute(String msg) {
mDisplay.append(msg + "\n");
}
}.execute(null, null, null);
} else if (view == findViewById(R.id.clear)) {
mDisplay.setText("");
}
}</void,>
主要是利用了gcm的send接口,上述需要服務器支持xmpp
6.服務器端的實現
可以參考:https://developers.google.com/cloud-messaging/的GCM Connection Server部分
有興趣的可以參考google的代碼demo
https://github.com/google/gcm/
https://github.com/googlesamples/google-services/
---------------------
作者:newhope1106
來源:CSDN
原文:https://blog.csdn.net/newhope1106/article/details/54709916
版權聲明:本文為博主原創文章,轉載請附上博文鏈接!