google的GCM推送使用簡介


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
版權聲明:本文為博主原創文章,轉載請附上博文鏈接!

 
 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM