複数のActivityをスタックさせて通知する、Notifiationの通知から削除まで


プッシュ通知はアプリを起動してもらうための、良いソリューション。
通信しないアプリでも、たまに通知を(うざったくならない程度に)出してあげて、アプリを使ってもらいたいものです。
ここでは、通知を出すところから、アプリ側で削除するところまでの一連の流れについて、基本的な部分を抑えておきたいと思います。

通知を出す

手順

通知を出ときに必要なものは、IntentPendingIntentNotificationNotificationManagerの4つです。

ざっくりとした流れは、

  1. 通知をタップした時に実行したいActivityのIntent(A)を作る
  2. PendingIntent(B)に、Intent(A)を登録
  3. Notification(C)にPendingIntent(B)をContentIntentとして登録
  4. システムサービスからNotificationManager(D)を取得
  5. NotificationManager(D)からNotification(C)を通知する

こんな流れです。
これを、タイマーやカレンダーのレシーバーに置くなどすることで、通知することができるようになります。

簡単な実装例

通知の実装例
// 起動するIntentを作成
// フラグは、これまで実行していたアプリの画面遷移はクリアして新規でアプリを開始するという意味
Intent intent = new Intent(context, MyActivity.class);
intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK|Intent.FLAG_ACTIVITY_CLEAR_TASK);

// PendingIntentにIntentを登録
// 最後のフラグは、新しい通知が来た時に、内容を新しいもので更新するというフラグ(通知を追加しない)
PendingIntent pendingIntent = PendingIntent.getActivity(context, 0, intent, PendingIntent.FLAG_UPDATE_CURRENT);

// Notificationを作成(ここではAppCompatの方を使用)
NotificationCompat.Builder builder = new NotificationCompat.Builder(context);
builder.setContentIntent(pendingIntent);
builder.setTicker(/* お知らせのティッカー(通知バーに表示される)*/);
builder.setSmallIcon(/* 通知バーに表示するアイコン */);
builder.setContentTitle(/* 通知のタイトル */);
builder.setContentText(/* 通知領域で表示するメッセージ */);
builder.setLargeIcon(/* 通知領域で表示する大きいアイコン */);
builder.setDefaults(/*  */Notification.DEFAULT_LIGHTS | Notification.DEFAULT_VIBRATE | Notification.DEFAULT_SOUND); /* 通知のしかた設定 */
builder.setAutoCancel(true); /* 「通知を削除」で消せるようにする */

// NotificationManagerを取得
NotificationManager manager = (NotificationManager) context.getSystemService(Service.NOTIFICATION_SERVICE);

// NotificationManagerから、Notificationを通知
manager.notify(1, builder.build());

Activityをスタックさせて通知する

NotificationからActivityを起動した後、バックボタンを押すと、そのタスク(アプリ)は終了します。
できれば、そのままアプリに留まって欲しいですよね。
もしそのアプリが、ホーム画面 -> お知らせ画面という画面遷移を持っているならなおさら。
通知からお知らせ画面を起動し、バックボタンを押したら、ホーム画面に戻るはずです。
ここでは、Activityをスタックさせて、起動する方法を簡単に一つ紹介します。

実装例

上の実装例と異なるのは、Intentの配列をPendingIntentに渡しているところです。

Notification
// 起動するIntentを作成
Intent notificationIntent = new Intent(context, InformationActivity.class);
Intent homeIntent = new Intent(context, HomeActivity.class);
homeIntent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK|Intent.FLAG_ACTIVITY_CLEAR_TASK);

// Intentの配列を作成。スタックする順で記述
Intent[] intents = {homeIntent, notificationIntent};

// PendingIntentにIntentの配列を登録
PendingIntent contentIntent = PendingIntent.getActivities(context, 0, intents, PendingIntent.FLAG_UPDATE_CURRENT);

通知の削除

最後は、アプリから通知を削除する方法です。もちろん、通知をタップしたら通知は削除されます。
しかし、例えば、アプリ実行中に通知が届き、お知らせ画面に自ら見に行ったなどしたら、通知は削除されるのが気持ち良いですね。

実装例

通知にひとてま
// 通知するときに、タグを付けておくといいかも
// notify(String tag, int id, Notification notification)
manager.notify("MyApplication", 0, notification);
通知の削除
// 通知の削除
NotificationManager manager = (NotificationManager) getSystemService(NOTIFICATION_SERVICE);
// cancel(String tag, int id)
manager.cancel("myApplication", 0);

これで通知は完成!