androidでプッシュ通知の実装をテーマとして第4回目。
第3回でサポートライブラリをインポートしたり
AndroidManifestに必要なpermissionを追加したりと下ごしらえを済ませたので
今回はクライアントアプリの機能実装についてです。
プッシュ通知をGoogleCloudMessaging(GCM)サーバから受け取るために
クライアントアプリに必要な機能は大きく分けて次の四つです。
- 通知を受け取る
- 受け取ったメッセージを処理する
- レジストレーションIDの登録と端末保存
- (取得したレジストレーションIDのAppサーバへの送信)
1.通知を受け取るためにブロードキャストレシーバーを用意します。
2.具体的にはステータスバーにNotificationを出す、バイブレーションを鳴らす等、
メッセージを受け取ったら行う処理を実装しておかばければなりません。
バックグラウンドでこの処理を行うためのServiceを用意します。
3.GCMにセンダーIDを送ると、GCMが端末情報を登録すると同時に
レジストレーションIDを発行してくれるのでした。(第1回参照)
レジストレーションIDを元に通知の送付先を識別します。
このIDの取得機能を用意します。
4.プッシュ通知を送るには、メッセージ本文と送りたい先のレジストレーションIDを
AppサーバからGCMサーバに送信する必要があります。(これまた第1回参照)
よってAppサーバがレジストレーションIDを知っておかなければなりませんが、
IDのクライアントアプリ-APPサーバ間の送信は各々のアプリケーションの設計に依って実装してください。
ブロードキャストレシーバー
スリープ時でもBroadcastの処理を確実に実行できるように
レシーバーはサポートライブラリのWakefulBroadcastReceiverクラスを継承して実装します。
package jp.techpjin.samplepushnotification; import android.app.Activity; import android.content.ComponentName; import android.content.Context; import android.content.Intent; import android.support.v4.content.WakefulBroadcastReceiver; public class GcmBroadcastReceiver extends WakefulBroadcastReceiver { @Override public void onReceive(Context context, Intent intent) { //受け取ったインテントの処理をGcmIntentServiceで行う ComponentName comp = new ComponentName(context.getPackageName(), GcmIntentService.class.getName()); //サービスの起動。処理中スリープを制御 startWakefulService(context, (intent.setComponent(comp))); setResultCode(Activity.RESULT_OK); } }
通知を受信すると、GcmBroadcastReceiver#onReceive()が呼び出され、
GcmIntentServiceを起動します。
サービス
今回はメッセージを受け取ったらNotificationにより
ステータスバーに通知を表示する実装を行います。
package jp.techpjin.samplepushnotification; import android.app.IntentService; import android.app.NotificationManager; import android.app.PendingIntent; import android.content.Context; import android.content.Intent; import android.os.Bundle; import android.support.v4.app.NotificationCompat; import android.util.Log; import com.google.android.gms.gcm.GoogleCloudMessaging; public class GcmIntentService extends IntentService { public static final int NOTIFICATION_ID = 1; private NotificationManager notificationManager; private NotificationCompat.Builder builder; public GcmIntentService(String name) { super(name); } public GcmIntentService() { super("GcmIntentService"); } @Override protected void onHandleIntent(Intent intent) { Bundle extras = intent.getExtras(); GoogleCloudMessaging gcm = GoogleCloudMessaging.getInstance(this); String messageType = gcm.getMessageType(intent); if (!extras.isEmpty()) { if (GoogleCloudMessaging.MESSAGE_TYPE_SEND_ERROR.equals(messageType)) { Log.d("LOG","messageType(error): " + messageType + ",body:" + extras.toString()); } else if (GoogleCloudMessaging.MESSAGE_TYPE_DELETED.equals(messageType)) { Log.d("LOG","messageType(deleted): " + messageType + ",body:" + extras.toString()); } else if (GoogleCloudMessaging.MESSAGE_TYPE_MESSAGE.equals(messageType)) { Log.d("LOG", "messageType(message): " + messageType + ",body:" + extras.toString()); String message = extras.getString("message"); sendNotification(message); } } GcmBroadcastReceiver.completeWakefulIntent(intent); } private void sendNotification(String msg) { notificationManager = (NotificationManager) this.getSystemService(Context.NOTIFICATION_SERVICE); PendingIntent contentIntent = PendingIntent.getActivity(this, 0, new Intent(this, MainActivity.class), 0); builder = new NotificationCompat.Builder(this) .setContentTitle("GCM Notification") .setSmallIcon(R.drawable.app_icon) .setStyle(new NotificationCompat.BigTextStyle() .bigText(msg)) .setContentText(msg); builder.setContentIntent(contentIntent); notificationManager.notify(NOTIFICATION_ID, builder.build()); } }
onHandleIntentで具体的なメッセージ処理を実装します。
PendingIntentはintentを即時発行するのではなくタイミングを指定して発行できるintentのこと。
今回の例であれば、Notificationがクリックされたタイミングで発行されるintentになります。
(NotificationCompat.Builder#setContentIntentでNotificationがクリック
されたとき発行されるPendingIntentを設定している)
一連の処理が終わったらcompleteWakefulIntentを呼び出して
レシーバーによるwake lockを解放するのを忘れずに。
3つ目のレジストレーションIDの登録と端末保存まで一気にやってしまいたいところですが
記事が少々長くなるので今回は1と2を終えたこの辺りで。
次回
通知を受け取るレシーバーと受信メッセージの処理Serviceの実装を行いました。
次回はクライアントアプリからGCMへのレジストレーションIDの登録とIDの端末保存の実装を
行ってアプリ実装編を完結したいと思います。