首先先说说自己遇到的问题: 利用gcm实现android手机应用的推送,在利用gcm库进行注册的时候无法返回注册id,regsiterID为“”,而且打印显示一直停留在requiring wakelock。无法正常显示注册成功和获得注册ID。
解决这个问题先说下gcm,gcm是google最近新推出的推送服务,他的前身是C2DM,C2DM之前存在很多问题,所以google文档上相关的内容已经换成gcm所以要实现gcm可以先浏览下google文档的gcm部分。
然后说下如何实现一个简单的gcm推送demo。
首先要获得gcm的服务你要先到google api项目里面注册一个用户然后创建一个属于自己的工程。目的是要让你在gcm里面相当于有一个账户,便于你跟google gcm进行交互。
注册和创建的方法很简单,如果你第一次注册,可以到https://code.google.com/apis/console进行注册,注册成功后会进入一个节目,你只需要创建一个项目,创建完成后会提供给你一个number这个number就是你之后要用的senderID。
接下来就是获得你所需要的APIkey,具体操作时进入api acces 里面点击创建一个server就可以了,它会返回给你一个相应的apikey,注意别点android key,因为你要的是一个服务器类型的服务。
接着就是开启你的gcm服务,找到services栏目,找到Google Cloud Messaging for Android。选择on就打开了。好了到这里的在google 项目端就结束了。
接下来开始写你的app的客户端。客户端的内容包括,你要写一个注册函数和一个服务类。写之前你要先添加相应的一些权限和广播,服务。具体做法很多网上都有。
<?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>
这是相应的权限设置。好了我们注意一下最后service部分的内容看是name = .GCMIntentService,是点。这就是我一开始就提到的问题出现的关键地方。
写注册函数你只需要在你启动程序的时候进行注册就好了。
- 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");
- }
- }
其中sendID就是你注册google用户后提供的number。
如果你发现里面提示gcmRegister类没有相应的文件,是因为你要添加相应gcm库,这个库从哪里来呢,你要到sdkmanager的extras里面添加Google Cloud Messaging for Android,添加完后你会在你的sdk的在sdk所在目录extras\google\gcm\gcm-client\dist里面找到gcm.jar把这个加入你的项目的libs里面,然后添加为你的build path。这样就能用gcm相应的类了。
客户端还要写一个类是服务类他继承自GCMBaseIntentService
- 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注销注册");
- }
- }
到这里如果你是随便创建的一个android项目然后添加的代码,一般客户端可以成功注册,但是如果你是想要把这个功能合成到你的项目里面,有可能会出现一开始我所提的问题。这个主要原因是我们GCMIntentService这个类。下面说下要注意的。首先你的这个类的名字不能换成别的。其次你这个类要放在你默认包下,就是说你不能添加到其他包目录下。具体原因查的不是很详细,可能是因为gcm中把路径默认设置在了默认包里面,如果你放到其他包就会无法启动这个服务。到这里基本上你的客户端就可以简单实现注册了。
服务端推荐个原创作者的http://blog.csdn.net/wzg_1987/article/details/9148023博客,也很简单。这个基本能完成一个推送的简单实现,要更完善的功能,需要我们自己去添加。