■クライアント側の実装
C2DMと対して変わらない。sender IDがメールアドレスでなくなったのは嬉しい。
gcm.jar
SDK/extras/google/の中からgcm.jarをlibsディレクトリの中にコピーする。プロジェクトをrefreshすれば現行のADTは勝手に組み込む。
manifest.xml
Android 2.2以降でないとダメなので以下のようにminSdkVersionを8とする。
<uses-sdk android:minSdkVersion="8" android:targetSdkVersion="15"/>
permissionを追加する。
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.WAKE_LOCK"/>
<uses-permission android:name="com.google.android.c2dm.permission.RECEIVE"/>
<uses-permission android:name="android.permission.GET_ACCOUNTS" />
アプリケーションがGCMを受け取るために以下の記述を付加する。
<permission
android:name="org.sample.permission.C2D_MESSAGE"
android:protectionLevel="signature" />
<uses-permission android:name="org.sample.permission.C2D_MESSAGE" />
receiverを追加する。
<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="org.sample" />
</intent-filter>
</receiver>
GCMIntentService
GCMBaseIntentServiceを継承したクラスを作る。
public class GCMIntentService extends GCMBaseIntentService {
/**
* 登録トークンを受け取った時に実行される。{@inheritDoc}
*/
@Override
public void onRegistered(Context context, String registration) {
if (BuildConfig.DEBUG) Log.d("onRegistered", "registration id:" + registration);
SharedPreferences preferences = PreferenceManager.getDefaultSharedPreferences(context);
Editor editor = preferences.edit();
editor.putString(Constants.KEY_C2DM_REGISTRATION, registration);
editor.commit();
}
/**
* デバイスが登録解除した時に実行される。{@inheritDoc}
*/
@Override
protected void onUnregistered(Context arg0, String arg1) {
}
/**
* クラウドメッセージが受信した時に実行される。{@inheritDoc}
*/
@Override
protected void onMessage(Context context, Intent intent) {
if (BuildConfig.DEBUG) Log.d("onMessage", "onMessage:" + intent.getExtras().toString());
setNotification(context);
}
/**
* 登録エラーの時に実行される。
*/
@Override
public void onError(Context context, String errorId) {
if (BuildConfig.DEBUG) Log.d("onError", "onError:" + errorId);
}
@Override
protected boolean onRecoverableError(Context context, String errorId) {
if (BuildConfig.DEBUG) Log.d("onError", "onError:" + errorId);
return super.onRecoverableError(context, errorId);
}
private void setNotification(Context context) {
NotificationManager notificationManager = (NotificationManager) context.getSystemService(Context.NOTIFICATION_SERVICE);
Notification notification = new Notification(
R.drawable.ic_notification,
"受信しましたよ",
System.currentTimeMillis()
);
Intent intent = new Intent(context, HelloActivity.class);
PendingIntent pendingIntent = PendingIntent.getActivity(
context,
100,
intent,
Intent.FLAG_ACTIVITY_NEW_TASK
);
notification.setLatestEventInfo(
context,
"タイトル",
"内容",
pendingIntent
);
notificationManager.notify(0, notification);// 適当なIDを指定する
}
}
manifestファイルに以下の記述を追加する。
<service android:name=".GCMIntentService"/>
onCreateとかonResumeとかに以下の記述を付加する。
GCMRegistrar.checkDevice(this);
GCMRegistrar.checkManifest(this);
final String regId = GCMRegistrar.getRegistrationId(this);
if (regId.equals("")) {
GCMRegistrar.register(this, "your sender id");
}
else {
Log.v("onResume", "Already registered");
}
■サーバー側の実装
node-gcmを使う。ToothlessGear / node-gcmとh2soft / node-gcmのどちらでも問題ないがnodeのバージョンの関係で今回は前者を使う。後者の方がコールバック関数のerrorの引数がnodeっぽくて良いと思われる。
var gcm = require('node-gcm');
var sender = new gcm.Sender('YOUR_API_KEY');
var registrationIds = ['device_registration_id'];
var message = new gcm.Message();
message.addData('content', 'text');
message.collapseKey = 'hogehoge';
message.delayWhileIdle = true;
message.timeToLive = 3;
sender.send(message, registrationIds, 3, function (result) {
console.log(result);
});