PendingIntentで使用される「requestCode」は何ですか?


110

バックグラウンド:

AlarmManager経由のアラームにPendingIntentを使用しています。

問題:

最初は、以前のものをキャンセルするために、アラームを開始する前に使用した正確なrequestCodeを提供する必要があると思いました。

しかし、キャンセルAPIが言うように、私は間違っていることがわかりました。

インテントが一致するアラームを削除します。(filterEquals(Intent)で定義されているように)Intentがこのアラームと一致する任意のタイプのアラームはキャンセルされます。

filterEquals」を見て、ドキュメントは言う:

インテント解決(フィルタリング)の目的で、2つのインテントが同じかどうかを判断します。つまり、アクション、データ、タイプ、クラス、およびカテゴリーが同じである場合です。これは、インテントに含まれる追加データを比較しません。

「requestCode」が何のためにあるのかわかりません...

質問:

「requestCode」は何に使用されますか?

同じ「requestCode」で複数のアラームを作成するとどうなりますか?それらは互いに上書きしますか?


同じrequestCodeを使用すると、同じPendingIntentを取得します
pskink

3
PendingIntent.getBroadcast()の場合、requestCodeは明らかにAndroidによって無視されます。API 22以降、保留中のインテントが一意になるわけではありません。getActivity()の場合(おそらくgetService()の場合はテストしていません)。stackoverflow.com/a/33203752/2301224
ベイカー

@ベイカーこれはバグだと思いませんか?バグの場合は、ここに記述してください:code.google.com/p/android/issues/list
android developer

1
まあ、実際には、ドキュメントがrequestiCodeのusagaを指定します: If you truly need multiple distinct PendingIntent objects active at the same time (such as to use as two notifications that are both shown at the same time), then you will need to ensure there is something that is different about them to associate them with different PendingIntents. This may be any of the Intent attributes considered by Intent#filterEquals(Intent), or different request code integers supplied.
EIR

@Eirそうですね、それでは、requestCodeを使用する意味は何ですか?どこで使用できますか?
Android開発者

回答:


77
  1. requestCode 後で同じ保留中のインテントインスタンスを取得するために使用されます(キャンセルなど)。
  2. はい、私の推測では、アラームが互いに上書きされると思います。リクエストコードは一意にしておきます。

5
アラームの意図が非常に異なる場合でも(たとえば、サービスAとサービスBの場合など)、requestCodeを一意に設定する必要がありますか?また、ドキュメントにそれについて何も記載されていないのはなぜですか?requestCodeに関係なく、特定のタイプのすべてのアラームを削除することは可能ですか?
Android開発者、

1
いいえ、異なるインテントには必要ありません。そして、なぜドキュメンテーションがそれについて何も述べていないのかは分かりませんが、繰り返しのアラームを設定するとき、そして同じ意図を使用するときにこれを学びました。
Minhaj Arfin 14

2
私はPendingIntentについて話していました。startActivityForResultは通常のインテントを使用します。
Android開発者

2
「プロキシアクティビティを使用したPendingIntentを含むstartActivityForResult」の目的は何ですか?例を挙げることができますか?
Android開発者

3
同意する; PendingIntentとAlarmManagerのドキュメントは完全にsh!tです-プログラムでアラームを一覧表示することができないという事実によってさらに悪化します。
誰かどこか

32

@Minhaj Arfinの回答に追加したいだけです

1-requestCodeは後で同じ保留中のインテントを取得するために使用されます(キャンセルなど)

2-はい、PendingIntentで指定したのと同じレシーバーをインテントに指定する限り、それらはオーバーライドされます

例:

Intent startIntent1 = new Intent(context, AlarmReceiverFirst.class);
PendingIntent pendingIntent1 = PendingIntent.getBroadcast(context, 0, startIntent1, 0);

Intent startIntent2 = new Intent(context, AlarmReceiverSecond.class);
PendingIntent pendingIntent2 = PendingIntent.getBroadcast(context, 0, startIntent2, 0);

上記の例から、レシーバーが異なるため(AlarmReceiverFirstとAlarmReceiverSecond)、それら互いにオーバーライドしません。

Intent startIntent2 = new Intent(context, AlarmReceiverSecond.class);
PendingIntent pendingIntent2 = PendingIntent.getBroadcast(context, 0, startIntent2, 0);

Intent startIntent3 = new Intent(context, AlarmReceiverSecond.class);
PendingIntent pendingIntent3 = PendingIntent.getBroadcast(context, 0, startIntent3, 0);

上記の例では、レシーバーが同じであるため、それら互いにオーバーライドします(AlarmReceiverSecond)。


Intent startIntent4 = new Intent(context、AlarmReceiverSecond.class); PendingIntent pendingIntent4 = PendingIntent.getService(context、0、startIntent4、0); じゃあ大丈夫?つまり、getBroadcast()ではなくgetService()を呼び出しているため、このオーバーライドは行われませんか?
Jenix 2016年

別の質問をして申し訳ありませんが、stackoverflowでは1行のコードなしで質問を書くことができないため。私は上記のちょうどあなたのコード例のようにそこに0を置くために使用されるが、私はまた、多くの人が代わりに0のいくつかの特定のオプション値を入れた見た
Jenix

1
@Jenix uou AlarmReceiverSecond.classはインテントで使用し、次にを使用しますPendingIntent.getService()。ので、それは、動作しませんAlarmReceiverSecond.classですBroadcastReceiver、ではないService
HendraWD

1
フラグについては、設定できるプロパティであり、指定したフラグに従ってPendingIntentの動作を行います。0はすべてのフラグがオフであることを意味します
HendraWD 2016年

ああ、私は愚かだった。世界で何を考えていたのか……PendingIntentについて少し混乱し、あなたの答えは本当に役に立ちました。そして、私はそれをより明確にしたかっただけでしたが、私の質問は最初は何の意味もないことに気づきました。ありがとう!
Jenix 2016年

2

私の場合、2つの異なるインテントで同じアクティビティを開きたいので、トレイに2つ以上のFCMSが存在する場合、それらのいずれかが他を開かないだけなので、保留中のインテントのリクエストコードを変更すると、機能しました。

 PendingIntent pendingIntent =
                            PendingIntent.getActivity(this, **Some unique id for all GCMS** /* Request code */, intent,
                                    PendingIntent.FLAG_ONE_SHOT);

私の場合、コードをさらに確認する必要はありませんでした。どちらの場合に保留中のインテントインスタンスが必要になるかを教えてください。質問変更要求コードに関して、正しい画面に移動するのに役立ちましたが、これが正しい方法であるかどうかわかりません。私にとって、トレイに複数のFCMがあったときにのみエラーが発生しました
JSONParser

では、必要がない場合は、なぜ別の要求コードを設定するのでしょうか。
Android開発者

はい、詳細に説明します。アクティビティAがありました。これは、通知からインテントを介してIDを渡し、そのIDのネットワークリクエストを作成して特定の質問を取得する質問を表示するためのものです。通知トレイに複数の通知があり、それらのいずれかをクリックすると、保留中のインテントリクエストコードが機能する一意の値に変更された後、最初のGCMにあった質問のIDが表示されます。私は今、明確にしたいと思います。さらに議論が必要な場合は、そこにいます。また、もっと学びたいと思います。ありがとう
JSONParser

ああ、そうでなければそれはまったく機能しなかったでしょう、そうですか?混乱については申し訳ありません。この質問はずっと前に尋ねられましたが、よく覚えていません...
Android開発者

1

requestCodeウィジェットを使用するとき、それがアプリに深刻な問題を引き起こす重要なことの1つです。requestCode同じである場合、ウィジェットは電話の再起動後に機能しません。つまり、ウィジェットのにpendingIndent設定するにremoteViewsは、一意のrequestCodeを設定する必要があります。通常は、番号を伴うwidgetIdです。


0

実際、ドキュメントにはリクエストコードの用途が明確に記載されています。

同時にアクティブな複数の異なるPendingIntentオブジェクトが本当に必要な場合(両方が同時に表示される2つの通知として使用するなど)、それらを異なるものに関連付けるには、それらに異なるものがあることを確認する必要があります。 PendingIntents。これは、Intent#filterEquals(Intent)によって考慮される任意のIntent属性、またはgetActivity(Context、int、Intent、int)、getActivities(Context、int、Intent []、int)、getBroadcast( Context、int、Intent、int)、またはgetService(Context、int、Intent、int)。

それはまだはっきりしていないようですので、説明させてください:

PendingIntentオブジェクトを使用する場合は、オブジェクトをインスタンス化するだけではありません。むしろ、あなたが使用してシステムから1つ取得するPendingIntent静的メソッド(getActivitygetBroadcastgetServiceなど)。システムは一連のPendingIntentインスタンスを保持し、インスタンスを提供します。どちらを使用するかは、これらのゲッターメソッドに渡す入力パラメーターによって異なります。これらの入力パラメーターは次のとおりですContext。つまり、インテントのターゲットレシーバー、Intent使用する、requestCodeおよびflagsです。同じContext、同じrequestCode、同じインテント(filterEquals別のインテントを持つインテントを意味する)を渡すと、同じPendingIntentオブジェクトが取得されます。ポイントは、システムはPendingIntentできるだけ少ないオブジェクトを必要とするため、既存のオブジェクトを可能な限り再利用する傾向があることです。

たとえば、2つの異なる日付の2つのカレンダー通知があるとします。それらの1つをクリックすると、その通知の対応する日付までアプリを開くことができます。そのシナリオでは、同じContextターゲットがあり、Intent渡すオブジェクトはEXTRA_DATA(オープンする必要がある日付を指定する)のみが異なります。あなたが同じを提供した場合はrequestCode取得するときにPendingIntentオブジェクトを、あなたは同じとなってしまいますPendingIntentオブジェクト。そのため、2番目の通知を作成するときに、古いIntentオブジェクトを新しいEXTRA_DATAに置き換え、最終的に同じ日付を指す2つの通知を生成します。

PendingIntentこのシナリオのように2つの異なるオブジェクトが必要なrequestCode場合は、PendingIntentオブジェクトを取得するときに別のオブジェクトを指定する必要があります。


ただし、前述したように、アラームをキャンセルするには、requestCodeだけを使用することはできません。それは何の意味もありません。それらを区別するために追加のデータを配置する必要があります。覚えていませんが、同じrequestCodeを複数のアラームに使用することもできます。
Android開発者

@androiddeveloper先ほど言ったことが正しくありません。それを試してみてください。
EIR
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.