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が実装されているものしかないとは限らないわけで、仕様としては分からんでもない。どっかに書かれてるのかもしれないけど見つけられなかった。
このへんは AlarmManager#set のリファレンスをみて そういうことか ととりあえず納得しました。