偷得浮生半桶水(半日闲), 好记性不如抄下来(烂笔头). 信息爆炸的时代, 学习是一项持续的工作.
全部博文(1748)
分类: Android平台
2013-10-27 10:42:09
此文描述了如何使用GCM提供的辅助库(客户端和服务器)来编写一个Android应用程序和服务器端的逻辑。
要创建一个谷歌API项目:
注:如果您已经有项目,你看到的第一页将是仪表板页面。从那里你可以通过打开项目的下拉菜单(左上角),并选择Other>Create一个新的项目。
注意#project:后面的值:(示例中的4815162342)。这是你的项目ID,并且后面会用作GCM发件人的ID。
为了启用GCM服务:
为了获取一个API密钥:
2. 点击Create new Server key。会出现以下页面:
3. 点击 Create:
请注意在这个示例中API key 的值(YourKeyWillBeShownHere),它稍后会被用到。
注:如果你想换掉这个密钥,请点击Generate new key。一个新的密钥就会创建,而之前的密钥在未来24内仍然有效。如果你想让之前的密钥立即失效(例如:你认为它已经被破解了),请点击Delete key。
在执行下面章节描述的步骤之前,请确保已经安装好辅助库(参考:客户端和服务器)。打开Android SDK Manager,安装Extras > Google Cloud Messaging for Android Library。这会在YOUR_SDK_ROOT/extras/google/目录下创建一个gcm文件夹,gcm文件夹下包含:gcm-client,gcm-demo-appengine, gcm-demo-client, gcm-demo-server, and gcm-server子目录。
注:SDK Manager版本要求r20以上,之前的版本发现不了GCM库。所以先打开eclipse升级ADT。
此章节描述了用GCM编写Android程序的步骤。
在编写程序之前,请先拷贝SDK目录下gcm-client/dist目录下的gcm.jar文件到程序的classpath。
1. GCM需要Android2.2或更高版本,所以如果你的程序不依赖GCM就无法正常工作,那么请在AndroidManifest文件中添加以下内容,“xx”处替换为最新的目标SDK版本号:
<uses-sdkandroid:minSdkVersion="8"android:targetSdkVersion="xx"/>
2. 声明并使用一个自定义的权限以此来确保只有这个程序可以接收你的GCM消息:
<permissionandroid:name="my_app_package.permission.C2D_MESSAGE"android:protectionLevel="signature"/><uses-permissionandroid:name="my_app_package.permission.C2D_MESSAGE"/>
这个权限必须称作:my_app_package.permission.C2D_MESSAG(程序包名.permission.C2D_MESSAG,程序包名就是在manifest文件中定义包名),不然将不能正常运行。
注:如果你的程序针对的是4.1或更高版本的系统(即,minSdkVersion 16),那么就不需要这个权限。
3. 添加权限接收GCM消息:
<uses-permissionandroid:name="com.google.android.c2dm.permission.RECEIVE"/>
4. 添加以下广播接收器:
<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="my_app_package"/> intent-filter> receiver>
这个Broadcast receiver负责处理2个从GCM发来的Intent(com.google.android.c2dm.intent.RECEIVE和com.google.android.c2dm.intent.REGISTRATION),并且要在manifest文件中定义(而非通过编码实现)。因此,这些Intent甚至可以在程序未运行的情况下被接收到。通过设置com.google.android.c2dm.permission.SEND权限,可以确保这些Intent只能通过GCM系统框架发送到这个receiver(普通程序是没有权限发出这些Intent的)。
注意在category标签里的android:name必须替换成你程序的包名(如果程序是针对16或更高的minSdkVersion的平台那么就不需要有category这个标签了)。
5. 添加以下Intent服务:
<service android:name=".GCMIntentService"/>
在下一步中,这个Intent服务会被GCMBroadcastReceiver(由GCM库提供)调用。它必须称作my_app_package.GCMIntentService,除非你用重写了GCMBroadcastRecevier方法的子类来作为此服务的名字。
下面来实现my_app_package.GCMIntentService类,重写下面的几个回调方法(这些方法会被GCMBroadcastReceiver调用):
注: 上面的方法运行在Intent服务的线程里,因此可以自由访问网络而不会阻塞UI线程。
在你程序的主activity里添加下面的导入语句:
import com.google.android.gcm.GCMRegistrar;
|
在onCreate()方法里添加下面的代码:
GCMRegistrar.checkDevice(this);
GCMRegistrar.checkManifest(this);
final String regId = GCMRegistrar.getRegistrationId(this);
if (regId.equals("")) {
GCMRegistrar.register(this, SENDER_ID);
} else {
Log.v(TAG, "Already registered");
}
|
checkDevice()方法用来验证设备是否支持GCM,如果不支持会抛出异常(例如,模拟器就不包含Google APIs)。相似地,checkManifest()方法来验证程序的manifest包含了在开始编写Android程序中所有符合要求的描述(这个方法只有你在开发程序的时候需要;一旦这个程序准备发布的时候,你就可以把它移除掉)。
一旦这些健康检查做完了,就可以调用GCMRegsistrar.register()通过传送注册GCM时得到的SENDER_ID来注册设备了。但是由于GCMRegistrar单例保持跟踪所有收到的注册Intent的注册ID,所以可以先调用GCMRegistrar.getRegistrationId()方法检查此设备是否已经注册。
注:可能设备已经成功注册到GCM,但是没有成功发送注册ID到你的服务器,这种情况你应当重试。请查看高级主题来了解处理这种情况的更多详情。
编写服务器程序请做如下准备:
import com.google.android.gcm.server.*;
Sender sender = new Sender(myApiKey);
Message message = new Message.Builder().build();
MulticastResult result = sender.send(message, devices, 5);
|
上面的代码段实现了如下工作:
现在就需要解析响应结果并对如下情况采取适当的措施:
这有一个代码段来处理这两种情况:
if (result.getMessageId() != null) {
String canonicalRegId = result.getCanonicalRegistrationId();
if (canonicalRegId != null) {
// same device has more than on registration ID: update database
}
} else {
String error = result.getErrorCodeName();
if (error.equals(Constants.ERROR_NOT_REGISTERED)) {
// application has been removed from device - unregister database
}
}
|