Android訊息推送之GCM方式(一)

來源:互聯網
上載者:User

 
點擊“Create project”按鍵後,將引導你建立第一個項目。如果之前有建立項目,將不會看到這個提示,你看到的會是一個面板。點擊左上方的下拉式功能表,選擇“Other projects”-"Create",將會引導你建立一個項目,你的瀏覽器地址將會形如:https://code.google.com/apis/console/#project:812216982441。注意#project:後面的數字812216982441,這將會在後面的GCM服務中作為標識號,用於用戶端向Google伺服器註冊。以上是準備工作的第一步。

第二:啟用你的GCM服務。

在GoogleApi控制台頁面中,選中“Services”項,開啟“Google Cloud Messaging for Android”項中的開關並接受協議,啟用你帳號下的GCM服務。

第三:獲得API Key

還是在控制台頁面,選中“API Access”。點擊“Create New Server Key”,在接下來的介面中直接點“Create”,將會產生一個Api Key,這個Api Key將用來驗證發送方。

第四,你的電腦需要具有GCM服務所必須的一些包。這些包可以在Android SDK Manager中下載安裝,更新的包名叫Google Cloud Messaging for Android,在Extras展開項中。安裝完後,在sdk所在目錄\extras\google\gcm中,在這裡你會看到gcm的發送、接收等操作使用到的工具類和包都有在這裡面。

你可以用eclipse直接import這些項目,並匯入裡面的幾個包,基於這些類檔案,我們建立對它們的調用。以上,準備工作已經完畢。下面我們開始講講怎麼使用。(註:準備工作中,如果安卓裝置沒有Google Play Services包,還需要另外增加第5步,自己去下載Googleplay的服務包並安裝到手機/平板中)

需要注意的是,GMC的方式並沒有嚴格的用戶端和服務端的,只要求接收訊息的是安卓應用,而發送訊息的一方可以是任意程式。可以在你自己搭建的伺服器裡,可以是同一個安卓應用裡,也可以只是一個main函數。不過需要使用到的類和環境就要分別搭建好了。

使用GCMRegistrar和Sender這兩個類可以分別實現用戶端的註冊和發送訊息的功能。這兩個類就在我們剛才下載的gcm服務包中。(在Googleplay服務包google-play-services.jar包中,有一個GoogleCloudMessaging的類,也可以提供註冊用戶端和發送訊息的方法。不過看了官方文檔,和前一種方式差不多。這裡先不講這種方法了。)

 


以上完成了開始的準備工作。接下來講代碼的實現:

 


先講用戶端註冊服務。首先要在AndroidManifest.xml檔案裡面添加3個GCM/C2DM的許可權和必要的網路訪問等許可權。完整的檔案在後面給出。

 


然後建立一個名為GCMIntentService的android服務,並且繼承GCMBaseIntentService這個抽象類別並實現裡面的幾個方法,記得在設定檔裡面要申明service。尤其要注意的是,這個service一定要命名為GCMIntentService,並且放到應用程式套件名下。因為GCM的機制會預設使用到這個服務,並且沒有提供可以設定為其它服務代替它的方法。

GCMIntentService類:


[java]
public class GCMIntentService extends GCMBaseIntentService { 
    public static final String SENDERID = "812216982441"; 
     
    public GCMIntentService(){ 
        super(SENDERID); 
    } 
 
    @Override 
    protected void onError(Context arg0, String arg1) { 
        Log.v("GCMIntentService", "onError錯誤"); 
    } 
 
    @Override 
    protected void onMessage(Context arg0, Intent arg1) { 
        Log.v("GCMIntentService", "收到新訊息:"+arg1.getStringExtra("mine")); 
        final String info = arg1.getStringExtra("mine"); 
        Handler handler = new Handler(Looper.getMainLooper()); 
        handler.post(new Runnable() { 
             
            @Override 
            public void run() { 
                Toast.makeText(getBaseContext(), "收到新訊息:"+info, Toast.LENGTH_LONG).show(); 
            } 
        }); 
    } 
 
    @Override 
    protected void onRegistered(Context arg0, String arg1) { 
        Log.v("GCMIntentService", "onRegistered註冊完成"); 
    } 
 
    @Override 
    protected void onUnregistered(Context arg0, String arg1) { 
        Log.v("GCMIntentService", "onUnregistered登出註冊"); 
    } 
 

public class GCMIntentService extends GCMBaseIntentService {
 public static final String SENDERID = "812216982441";
 
 public GCMIntentService(){
  super(SENDERID);
 }

 @Override
 protected void onError(Context arg0, String arg1) {
  Log.v("GCMIntentService", "onError錯誤");
 }

 @Override
 protected void onMessage(Context arg0, Intent arg1) {
  Log.v("GCMIntentService", "收到新訊息:"+arg1.getStringExtra("mine"));
  final String info = arg1.getStringExtra("mine");
  Handler handler = new Handler(Looper.getMainLooper());
  handler.post(new Runnable() {
   
   @Override
   public void run() {
    Toast.makeText(getBaseContext(), "收到新訊息:"+info, Toast.LENGTH_LONG).show();
   }
  });
 }

 @Override
 protected void onRegistered(Context arg0, String arg1) {
  Log.v("GCMIntentService", "onRegistered註冊完成");
 }

 @Override
 protected void onUnregistered(Context arg0, String arg1) {
  Log.v("GCMIntentService", "onUnregistered登出註冊");
 }

}
這幾個方法是結合了GCM的機制的,注意不要誤解成了它們是安卓的service的。

onError:在註冊用戶端或者解除註冊出錯時調用。
onMessage:用戶端收到訊息時調用。

onRegistered:註冊完成。

onUnregistered:解除註冊完成。

“常量”SENDERID是前面在控制台頁面建立項目時得到的那個值。

建好服務類後就可以開始註冊了。以下是註冊的程式碼片段,直接在Activit的onCreate方法裡執行就可以。


[java] view plaincopyprint?protected void onCreate(Bundle savedInstanceState) { 
        super.onCreate(savedInstanceState); 
        setContentView(R.layout.activity_main); 
         
        GCMRegistrar.checkDevice(this); 
        GCMRegistrar.checkManifest(this); 
        final String regId = GCMRegistrar.getRegistrationId(this); 
        if (regId.equals("")) { 
          GCMRegistrar.register(this, GCMIntentService.SENDERID); 
          Log.v(TAG, "新裝置:"+GCMRegistrar.isRegistered(this)+GCMRegistrar.getRegistrationId(this)); 
        } else { 
          Log.v(TAG, "Already registered"); 
        } 
        //點擊後解除註冊,不接收訊息  
        Button btn = (Button) findViewById(R.id.unregist_btn); 
        btn.setOnClickListener(new OnClickListener() { 
             
            @Override 
            public void onClick(View v) { 
                GCMRegistrar.unregister(getBaseContext()); 
            } 
        }); 
         
    } 

protected void onCreate(Bundle savedInstanceState) {
  super.onCreate(savedInstanceState);
  setContentView(R.layout.activity_main);
  
  GCMRegistrar.checkDevice(this);
  GCMRegistrar.checkManifest(this);
  final String regId = GCMRegistrar.getRegistrationId(this);
  if (regId.equals("")) {
    GCMRegistrar.register(this, GCMIntentService.SENDERID);
    Log.v(TAG, "新裝置:"+GCMRegistrar.isRegistered(this)+GCMRegistrar.getRegistrationId(this));
  } else {
    Log.v(TAG, "Already registered");
  }
  //點擊後解除註冊,不接收訊息
  Button btn = (Button) findViewById(R.id.unregist_btn);
  btn.setOnClickListener(new OnClickListener() {
   
   @Override
   public void onClick(View v) {
    GCMRegistrar.unregister(getBaseContext());
   }
  });
  
 }
checkDevice()檢查系統版本和是否裝有google service frame,否則拋出異常。(GCM服務需要安裝有Google服務包,且系統版本2.2及以上的才支援)

checkManifest()檢查AndroidManifest.xml檔案是否有配置有必須的許可權,和檢測廣播接收器是否有正確的許可權和過濾器,是否可以正常接收廣播。否則拋出異常。


register()真正開始註冊一個GCM服務,它會啟動一個action名為com.google.android.c2dm.intent.REGISTER的服務。注意這個才是真正的GCM服務,而前面我們自己建立的那個其實並不是GCM服務,只是GCM整個服務機制裡面為我們提供的一個業務上的回調而已。

完整的AndroidManifest.xml檔案:


[html] view plaincopyprint?<?xml version="1.0" encoding="utf-8"?> 
<manifest 
    xmlns:android="http://schemas.android.com/apk/res/android" 
    package="com.ives.androidgcmclient" 
    android:versionCode="1" 
    android:versionName="1.0"> 
    <uses-sdk 
        android:minSdkVersion="8" 
        android:targetSdkVersion="15"/> 
    <permission 
        android:name="com.ives.androidgcmclient.permission.C2D_MESSAGE" 
        android:protectionLevel="signature"/> 
    <uses-permission 
        android:name="com.ives.androidgcmclient.permission.C2D_MESSAGE"/> 
    <uses-permission 
        android:name="com.google.android.c2dm.permission.RECEIVE"/> 
    <uses-permission 
        android:name="android.permission.INTERNET"/> 
    <uses-permission 
        android:name="android.permission.GET_ACCOUNTS"/> 
    <uses-permission 
        android:name="android.permission.WAKE_LOCK"/> 
    <uses-permission 
        android:name="android.permission.CHANGE_NETWORK_STATE"> 
    </uses-permission> 
    <uses-permission 
        android:name="android.permission.CHANGE_WIFI_STATE"> 
    </uses-permission> 
    <uses-permission 
        android:name="android.permission.ACCESS_NETWORK_STATE"> 
    </uses-permission> 
    <uses-permission 
        android:name="android.permission.ACCESS_WIFI_STATE"/> 
    <application 
        android:allowBackup="true" 
        android:icon="@drawable/ic_launcher" 
        android:label="@string/app_name" 
        android:theme="@style/AppTheme"> 
        <activity 
            android:name="com.ives.androidgcmclient.MainActivity" 
            android:label="@string/app_name"> 
            <intent-filter> 
                <action 
                    android:name="android.intent.action.MAIN"/> 
 
                <category 
                    android:name="android.intent.category.LAUNCHER"/> 
            </intent-filter> 
        </activity> 
 
        <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.ives.androidgcmclient"/> 
            </intent-filter> 
        </receiver> 
        <service 
            android:name=".GCMIntentService"/> 
    </application> 
 
</manifest> 

<?xml version="1.0" encoding="utf-8"?>
<manifest
 xmlns:android="http://schemas.android.com/apk/res/android"
 package="com.ives.androidgcmclient"
 android:versionCode="1"
 android:versionName="1.0">
 <uses-sdk
  android:minSdkVersion="8"
  android:targetSdkVersion="15"/>
 <permission
  android:name="com.ives.androidgcmclient.permission.C2D_MESSAGE"
  android:protectionLevel="signature"/>
 <uses-permission
  android:name="com.ives.androidgcmclient.permission.C2D_MESSAGE"/>
 <uses-permission
  android:name="com.google.android.c2dm.permission.RECEIVE"/>
 <uses-permission
  android:name="android.permission.INTERNET"/>
 <uses-permission
  android:name="android.permission.GET_ACCOUNTS"/>
 <uses-permission
  android:name="android.permission.WAKE_LOCK"/>
 <uses-permission
  android:name="android.permission.CHANGE_NETWORK_STATE">
 </uses-permission>
 <uses-permission
  android:name="android.permission.CHANGE_WIFI_STATE">
 </uses-permission>
 <uses-permission
  android:name="android.permission.ACCESS_NETWORK_STATE">
 </uses-permission>
 <uses-permission
  android:name="android.permission.ACCESS_WIFI_STATE"/>
 <application
  android:allowBackup="true"
  android:icon="@drawable/ic_launcher"
  android:label="@string/app_name"
  android:theme="@style/AppTheme">
  <activity
   android:name="com.ives.androidgcmclient.MainActivity"
   android:label="@string/app_name">
   <intent-filter>
    <action
     android:name="android.intent.action.MAIN"/>

    <category
     android:name="android.intent.category.LAUNCHER"/>
   </intent-filter>
  </activity>

  <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.ives.androidgcmclient"/>
   </intent-filter>
  </receiver>
  <service
   android:name=".GCMIntentService"/>
 </application>

</manifest>

相關文章

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.