返回
顶部

修改密码

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

+1

-1

收藏

+1

-1

点赞0

评论0

点击“Create project”按键后,将引导你创建第一个项目。如果之前有创建项目,将不会看到这个提示,你看到的会是一个面板。点击左上角的下拉菜单,选择“Other projects”-"Create",将会引导你创建一个项目,你的浏览器地址将会形如:https://code.google.com/apis/consol…

 
点击“Create project”按键后,将引导你创建第一个项目。如果之前有创建项目,将不会看到这个提示,你看到的会是一个面板。点击左上角的下拉菜单,选择“Other projects”-"Create",将会引导你创建一个项目,你的浏览器地址将会形如:https://code.google.com/apis/console/#project:812216982441。注意#project:后面的数字812216982441,这将会在后面的GCM服务中作为标识号,用于客户端向谷歌服务器注册。以上是准备工作的第一步。

第二:激活你的GCM服务。

在谷歌Api控制台页面中,选中“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步,自己去下载谷歌play的服务包并安装到手机/平板中)

需要注意的是,GMC的方式并没有严格的客户端和服务端的,只要求接收消息的是安卓应用,而发送消息的一方可以是任意程序。可以在你自己搭建的服务器里,可以是同一个安卓应用里,也可以只是一个main函数。不过需要使用到的类和环境就要分别搭建好了。

使用GCMRegistrar和Sender这两个类可以分别实现客户端的注册和发送消息的功能。这两个类就在我们刚才下载的gcm服务包中。(在谷歌play服务包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服务需要安装有谷歌服务包,且系统版本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>

扫一扫在手机打开

评论
已有0条评论
0/150
提交
热门评论
相关推荐
Android C2DM学习 - 云端推送
  • 消息推送
  • 2022-05-20 18:31
  • 4 0 0
+1
Android C2DM学习 - 客户端开发
  • 消息推送
  • 2022-05-20 18:31
  • 8 0 0
+1
Android C2DM学习 - 服务器端开发
  • 消息推送
  • 2022-05-20 18:31
  • 2 0 0
+1
解析php做推送服务端实现ios消息推送
  • 消息推送
  • 2022-05-20 18:31
  • 4 0 0
+1
今日要闻
换一批
热点排行