(メモ)NotificationのPendingIntentをFLAG_ACTIVITY_SINGLE_TOPで投げる時の挙動

NotificationにPendingIntentを投げる時、

intent.setFlags(Intent.FLAG_ACTIVITY_SINGLE_TOP);

のようにフラグを付けることで既存のActivityに対してIntentを投げることが出来る。
受け取り側のActivityは(onCreateではなく)

protected void onNewIntent(Intent intent)

を適切にオーバーライドしてIntentを受け取る。
1つのアプリが複数の種類のIntentを持つ場合、notifyの第一引数(int id)によって区別される。
PendingIntentを更新したい時はPendingIntent.getActivityの第4引数(int flags)にPendingIntent.FLAG_UPDATE_CURRENTを設定すると同じidの通知を上書き出来る。


ところがPendingIntentの「同一性」はnotifyとは別の基準で行われており、具体的に言うと他の情報が全く同じでputExtraだけが違うPendingIntentを作ると情報が混ざってしまう。

intent1.putExtra("id", 1);
PendingIntent pending1 = PendingIntent.getActivity(... //intent1をセット
Notification notif1...//notif1にpending1をセット
notif_manager.notify(1, notif1);
intent2.putExtra("id", 2);
PendingIntent pending2 = PendingIntent.getActivity(... //intent2をセット
Notification notif2...//notif1にpending2をセット
notif_manager.notify(2, notif2);

こうすると、通知ID1と2の通知が作られて2つの通知が表示されるが、pending1とpending2は同じものとみなされてpending1の情報は2で上書きされてしまう。このため、通知1も2もpending2が起動されてしまう。
なんだそりゃ。
解決法。
putExtra以外で区別できる情報を付けてやる。
具体的にはIntentにsetDataで異なる(IDを含むダミーの)Uriをセットしてやると区別してくれるようになる。
同一性チェックにExtraも使っていると思っていたので結構はまってしまった。
考えてみればここには様々なObjectが入る、つまりequalsが実装されているものしかないとは限らないわけで、仕様としては分からんでもない。どっかに書かれてるのかもしれないけど見つけられなかった。

“(メモ)NotificationのPendingIntentをFLAG_ACTIVITY_SINGLE_TOPで投げる時の挙動” への1件の返信

  1. このへんは AlarmManager#set のリファレンスをみて そういうことか ととりあえず納得しました。

コメントを残す

メールアドレスが公開されることはありません。 * が付いている欄は必須項目です