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の端末保存の実装を
行ってアプリ実装編を完結したいと思います。