Android GCM消息推送
注:中国大陆体验不好,不建议在中国大陆使用
1.创建Google API项目:
登陆Google控制台:https://code.google.com/apis/console/,如果你还没创建过项目,页面会提示:
如果您已经有项目,你看到的第一页将是仪表板页面。从那里你可以通过打开项目的下拉菜单(左上角),并选择Other>Create一个新的项目。
注:创建项目是提示要输入第三方服务器ip,可以不输入直接创建。
创建完了之后要记住上面的Project ID,也就是下面代码中要使用到的SENDER_ID。
2.开启GCM服务:
在谷歌API的控制页面的主页中,选择Services。
在右侧找到:Google Cloud Messaging forAndroid, 设置按钮的状态值为ON。
在服务条款页面中接受这些条款。
3.获得Server API密钥(服务器或者测试的时候要用到):
在谷歌API的控制页面的主页中,选择API Access。选择Create new Server key,记住API key。
4.安装GCM库:
打开SDK Manager,如果你的SDK Manager在Revision 20以下请下载更新后在安装GCM库。安装 Extras > Google Cloud Messaging for Android Library,如果没看到这一选项,下方的show中有一个为"Obsolete"的CheckBox,勾选上即有。它会创建一个YOUR_SDK_ROOT/extras/google/ 文件夹。
5.写客服端代码
注:运行着需要使用GCM的android程序的手机. 这必须是一个2.2的Android设备,安装Google Play Store, 如果设备运行Android版本低于4.0.4它必须至少有一个登录谷歌账户。或者运行具有谷歌api 的Android 2.2虚拟机。
前提:从 YOUR_SDK_ROOT/extras/google/gcm/gcm-client/dist/中拷贝gcm.jar到你的项目下面,另外,android模拟器必须拥有Google Apis,如在创建模拟器时Target选中带有Google APIs(Google Inc.)字眼的。
AndroidManifest.xml(注意拼写的正确性以及顺序)
package="com.huangri.sendmsg.gcmclient" > android:allowBackup="true" android:icon="@drawable/ic_launcher" android:label="@string/app_name" android:theme="@style/AppTheme" > android:name=".GcmClientActivity" android:label="@string/app_name" > android:name="com.google.android.gcm.GCMBroadcastReceiver" android:permission="com.google.android.c2dm.permission.SEND" >
GCMIntentService.java(名字不可改动,否则会获取不到设备注册ID,并且要继承GCMBaseIntentService)
package com.huangri.sendmsg.gcmclient;
import android.app.Notification;
import android.app.NotificationManager;
import android.app.PendingIntent;
import android.content.Context;
import android.content.Intent;
import android.os.Handler;
import android.os.Looper;
import android.util.Log;
import android.widget.Toast;
import com.google.android.gcm.GCMBaseIntentService;
import com.google.android.gcm.GCMRegistrar;
/**
* Created by HUANGRI on 11/27/2014.
*/
public class GCMIntentService extends GCMBaseIntentService {
private final String TAG = "GCMIntentService";
public static final String SENDER_ID = "314810456832";
//SENDER_ID就是上面说到的Project ID
public GCMIntentService() {
super(SENDER_ID);
}
//当设备试图注册或注销时,但是GCM服务器无效时。GCM库会使用应急方案重试操作,除非这个方式被重写并返回false。
//这个方法是可选的并且只有当你想显示信息给用户或想取消重试操作的时候才会被重写。
@Override
protected boolean onRecoverableError(Context context, String errorId) {
return super.onRecoverableError(context, errorId);
}
//当你的服务器发送了一个消息到GCM后会被调用,并且GCM会把这个消息传送到相应的设备。
//如果这个消息包含有效负载数据,它们的内容会作为Intent的extras被传送。
@Override
protected void onMessage(Context context, Intent intent) {
Log.e(TAG, "messageFrom = " + intent.getStringExtra("messageFrom"));
Log.e(TAG, "message = " + intent.getStringExtra("msg"));
final String info = intent.getStringExtra("msg");
NotificationManager notificationManager = (NotificationManager)context.getSystemService(Context.NOTIFICATION_SERVICE);
Notification notification = new Notification(R.drawable.ic_launcher, "Notification", System.currentTimeMillis());
Intent intent_action = new Intent(context, GcmClientActivity.class);
PendingIntent pendingIntent = PendingIntent.getActivity(context, 0, intent_action, 0);
notification.setLatestEventInfo(context, "GCM Message", "You have a message!: " + info, pendingIntent);
notification.flags = Notification.FLAG_AUTO_CANCEL;
notification.defaults = Notification.DEFAULT_SOUND;
notificationManager.notify(0, notification);
}
//当设备试图注册或注销时,但是GCM返回错误时此方法会被调用。通常此方法就是分析错误并修复问题而不会做别的事情。
@Override
protected void onError(Context context, String s) {
Log.e(TAG, "onError():error occurred");
}
//收到注册Intent后此方法会被调用,GCM分配的注册ID会做为参数传递到设备/应用程序对。
//通常,你应该发送regid到你的服务器,这样服务器就可以根据这个regid发消息到设备上。
@Override
protected void onRegistered(Context context, String s) {
Log.e(TAG, "onRegistered():registered already");
}
//当设备从GCM注销时会被调用。通常你应该发送regid到服务器,这样就可以注销这个设备了。
@Override
protected void onUnregistered(Context context, String s) {
Log.e(TAG, "onUnregistered():unregister occurred");
}
}
GcmClientActivity.java
package com.huangri.sendmsg.gcmclient;
import android.support.v7.app.ActionBarActivity;
import android.os.Bundle;
import android.util.Log;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
import android.widget.Button;
import android.widget.TextView;
import com.google.android.gcm.GCMRegistrar;
public class GcmClientActivity extends ActionBarActivity {
private final String TAG = "GcmClientActivity";
private TextView message_content;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_gcm_client);
message_content = (TextView)findViewById(R.id.message_receiver);
//检查设备和AndroidManifest是否支持GCM
GCMRegistrar.checkDevice(this);
GCMRegistrar.checkManifest(this);
//启动前先获得设备ID,判断设备是否注册过
final String regId = GCMRegistrar.getRegistrationId(this);
if ("".equals(regId)) {
//注册register(Context context, String SENDER_ID)
GCMRegistrar.register(this, GCMIntentService.SENDER_ID);
Log.i(TAG, "First registered,isRegistered = " + GCMRegistrar.isRegistered(this) + ", ID = " + GCMRegistrar.getRegistrationId(this));
message_content.setText("First registered,isRegistered = " + GCMRegistrar.isRegistered(this) + ", ID = " + GCMRegistrar.getRegistrationId(this));
} else {
GCMRegistrar.setRegisteredOnServer(this, true);
Log.i(TAG, "Already registered!");
Log.i(TAG, "registerID = " + GCMRegistrar.getRegistrationId(this));
message_content.setText("Already registered!\n" + "registerID = " + GCMRegistrar.getRegistrationId(this));
}
Button btn_unregister = (Button)findViewById(R.id.unregister);
btn_unregister.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
//向服务器注销设备ID
GCMRegistrar.unregister(getBaseContext());
message_content.setText("unregister");
}
});
//下面的是ActionBar的方法,与本文无关
@Override
public boolean onCreateOptionsMenu(Menu menu) {
// Inflate the menu; this adds items to the action bar if it is present.
getMenuInflater().inflate(R.menu.gcm_client, menu);
return true;
}
@Override
public boolean onOptionsItemSelected(MenuItem item) {
int id = item.getItemId();
if (id == R.id.action_settings) {
return true;
}
return super.onOptionsItemSelected(item);
}
}
6.测试:
这里就不写服务器代码,自己网上早去,测试可以使用ChromePoster插件(安装步骤:打开谷歌浏览器==>工具==>扩展程序==>查找ChromePoster插件并安装)
点击右侧的P按钮,
分别输入:
URL: https://android.googleapis.com/gcm/send
Header:
Name: Authorization Value: key=你的API key 点击Add/Change
Name:Content-Type Value: application/json forJSON; application/x-www-form-urlencoded;charset=UTF-8for plain text 点击Add/Change
Content Body:
{ "data": {
/////////这里为发送的消息,以键值方式传送,填入时去掉这一行//////////
"键": "值" }, "registration_ids": ["你的设备的注册ID"] }
最后点击POST就可以看到测试结果了。