■クライアント側の実装
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); });