Wofür wird "requestCode" in PendingIntent verwendet?

110

Hintergrund:

Ich verwende PendingIntent für Alarme über AlarmManager.

Das Problem:

Zuerst dachte ich, um vorherige abzubrechen, muss ich den genauen requestCode angeben, den ich zuvor zum Starten des Alarms verwendet habe.

Aber dann habe ich herausgefunden, dass ich falsch lag, wie die Stornierungs-API sagt:

Entfernen Sie alle Alarme mit einer passenden Absicht. Jeder Alarm jeglicher Art, dessen Absicht mit dieser übereinstimmt (wie durch filterEquals (Absicht) definiert), wird abgebrochen.

In der Dokumentation zu " filterEquals " heißt es:

Stellen Sie fest, ob zwei Absichten zum Zwecke der Absichtsauflösung (Filterung) gleich sind. Das heißt, wenn Aktion, Daten, Typ, Klasse und Kategorien identisch sind. Dadurch werden keine zusätzlichen Daten verglichen, die in den Absichten enthalten sind.

Ich verstehe also nicht, wofür der "requestCode" ist ...

Die Frage:

Wofür wird "requestCode" verwendet?

Was ist, wenn ich mehrere Alarme mit demselben "requestCode" erstelle? überschreiben sie sich gegenseitig?

Android-Entwickler
quelle
Wenn Sie denselben requestCode verwenden, erhalten Sie denselben PendingIntent
pskink
3
Bei PendingIntent.getBroadcast () wird requestCode von Android anscheinend ignoriert. Ab API 22 wird Ihre ausstehende Absicht nicht mehr eindeutig. Funktioniert für getActivity () (und möglicherweise getService (), aber ich habe es nicht getestet). stackoverflow.com/a/33203752/2301224
Baker
@ Baker Wird das nicht als Fehler angesehen? Wenn es ein Fehler ist, sollten Sie hier darüber schreiben: code.google.com/p/android/issues/list
Android-Entwickler
1
Nun, tatsächlich spezifiziert die Dokumentation die Verwendung des requestiCode: 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 Richtig, was bringt es also, den requestCode zu verwenden? Wo kann es verwendet werden?
Android-Entwickler

Antworten:

77
  1. requestCode wird verwendet, um dieselbe ausstehende Absichtsinstanz später abzurufen (zum Abbrechen usw.).
  2. Ja, ich vermute, die Alarme überschreiben sich gegenseitig. Ich würde die Anforderungscodes eindeutig halten.
Minhaj Arfin
quelle
5
Ist es erforderlich, den requestCode eindeutig festzulegen, auch wenn die Absichten der Alarme sehr unterschiedlich sind (z. B. eine für Service A und eine für Service B)? Wie kommt es, dass die Dokumentation nichts darüber aussagt? Ist es möglich, alle Alarme eines bestimmten Typs zu entfernen, unabhängig vom requestCode?
Android-Entwickler
1
Nein, es ist nicht für verschiedene Absichten notwendig. Und ich weiß nicht, warum die Dokumentation nichts darüber aussagt, aber ich habe dies gelernt, als ich wiederholte Alarme eingestellt habe und auch wenn ich dieselbe Absicht verwendet habe.
Minhaj Arfin
2
Ich habe über PendingIntent gesprochen. startActivityForResult verwendet eine normale Absicht.
Android-Entwickler
2
Was ist der Zweck von "startActivityForResult mit PendingIntent unter Verwendung einer Proxy-Aktivität"? Kannst du ein Beispiel geben?
Android-Entwickler
3
Genau; Die Dokumentation für PendingIntent und AlarmManager ist total schlecht, da Alarme nicht programmgesteuert aufgelistet werden können.
Jemand irgendwo
32

Ich möchte nur die Antwort von @Minhaj Arfin hinzufügen

1- requestCode wird verwendet, um später dieselbe ausstehende Absicht zu erhalten (zum Abbrechen usw.)

2- Ja, sie werden überschrieben, solange Sie denselben Empfänger für Ihre Absicht angeben, den Sie in Ihrem PendingIntent angegeben haben

Beispiel:

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);

Im obigen Beispiel überschreiben sie sich nicht, da der Empfänger unterschiedlich ist (AlarmReceiverFirst und 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);

Von obigen Beispiel sie werden sich gegenseitig zu überschreiben, da der Empfänger gleich ist (AlarmReceiverSecond)

HendraWD
quelle
Intent startIntent4 = new Intent (Kontext, AlarmReceiverSecond.class); PendingIntent pendingIntent4 = PendingIntent.getService (Kontext, 0, startIntent4, 0); wäre dann okay Ich meine, wird dies nicht überschrieben, weil getService () anstelle von getBroadcast () aufgerufen wird?
Jenix
Es tut mir leid, eine andere Frage zu stellen, aber da ich mit dem Stackoverflow keine Frage ohne eine einzige Codezeile schreiben kann. Hat das letzte Argument von PendingIntents Methoden wie getBroadcast () nicht etwas mit Überschreiben zu tun? Ich habe dort 0 gesetzt, genau wie Ihr Beispielcode oben, aber ich habe auch gesehen, dass viele Leute einen bestimmten Optionswert anstelle von 0
eingegeben haben
1
@Jenix uou AlarmReceiverSecond.classauf die Absicht verwenden und dann verwenden PendingIntent.getService(). Es wird nicht funktionieren, da AlarmReceiverSecond.classes ein BroadcastReceiver, keinService
HendraWD
1
Bei Flags können Sie Eigenschaften festlegen, die das Verhalten Ihres PendingIntent an die von Ihnen angegebenen Flags anpassen. 0 bedeutet, dass alle Flaggen ausgeschaltet sind
HendraWD
Ah, ich war dumm, haha. Was in aller Welt habe ich gedacht? Ich war ein bisschen verwirrt über PendingIntent und deine Antwort war wirklich hilfreich. Und ich wollte es nur klarer machen, aber jetzt wurde mir klar, dass meine Frage zunächst keinen Sinn ergab. Vielen Dank!
Jenix
2

In meinem Fall möchte ich dieselbe Aktivität mit zwei verschiedenen Absichten öffnen. Wenn also zwei oder mehr FCMS in der Taskleiste vorhanden sind, öffnet einer von ihnen nur den anderen, nicht, also habe ich die Anforderungscodes für ausstehende Absichten geändert, dann hat es funktioniert.

 PendingIntent pendingIntent =
                            PendingIntent.getActivity(this, **Some unique id for all GCMS** /* Request code */, intent,
                                    PendingIntent.FLAG_ONE_SHOT);
JSONParser
quelle
Es war nicht nötig, den Code für meinen Fall weiter zu überprüfen. Können Sie sagen, in welchem ​​Fall die Instanz für ausstehende Absichten erforderlich sein wird? In Bezug auf das Ändern von Fragen hat mir der Anforderungscode geholfen, zum richtigen Bildschirm zu gelangen. Ich weiß nicht, ob dies der richtige Weg ist, und für mich trat ein Fehler nur auf, wenn mehrere FCMs in der Ablage vorhanden waren
JSONParser
Warum also einen anderen Anforderungscode festlegen, wenn Sie ihn nicht benötigen?
Android-Entwickler
ok, ich werde im Detail erklären, ich hatte einige AKTIVITÄT A, es soll Fragen zeigen, ich werde die ID von Benachrichtigungen durch Absicht übergeben und dann eine Netzwerkanforderung für diese ID machen und die bestimmte Frage abrufen, also was geschah das, als dort Befinden sich mehr als 1 Benachrichtigungen in der Benachrichtigungsleiste, und dann klicke ich auf eine der Benachrichtigungen. Ich erhalte die ID der Frage, die sich im ersten GCM befand, nachdem ich den ausstehenden Absichtsanforderungscode in einen eindeutigen Wert geändert habe. Ich hoffe, ich habe jetzt klargestellt, wenn weitere Diskussionen erforderlich sind, bin ich dort, ich möchte auch mehr erfahren, danke
JSONParser
Oh, du meintest, dass es sonst überhaupt nicht funktioniert hätte, oder? Entschuldigung für die Verwirrung. Diese Frage wurde vor langer Zeit gestellt und ich erinnere mich überhaupt nicht gut daran ...
Android-Entwickler
1

Eine wichtige Sache requestCode, die Ihre App ernsthaft stören wird, ist die Verwendung von Widgets. Widgets funktionieren nach dem Neustart des Telefons nicht, wenn sie requestCodeidentisch sind. Das bedeutet, dass für das, was pendingIndentSie in remoteViewsIhrem Widget festgelegt haben, ein eindeutiger requestCode festgelegt werden muss, normalerweise die Widget-ID, die einer Nummer beiliegt.

Alireza Jamali
quelle
0

Tatsächlich wird in der Dokumentation klar angegeben, wofür der Anforderungscode verwendet wird:

Wenn Sie wirklich mehrere unterschiedliche PendingIntent-Objekte benötigen, die gleichzeitig aktiv sind (z. B. um zwei Benachrichtigungen zu verwenden, die beide gleichzeitig angezeigt werden), müssen Sie sicherstellen, dass sie etwas anderes haben, um sie mit verschiedenen zu verknüpfen PendingIntents. Dies kann eines der Intent-Attribute sein, die von Intent # filterEquals (Intent) berücksichtigt werden, oder verschiedene Anforderungscode-Ganzzahlen, die für getActivity (Context, int, Intent, int), getActivities (Context, int, Intent [], int), getBroadcast ( Context, int, Intent, int) oder getService (Context, int, Intent, int).

Da es immer noch nicht so klar zu sein scheint, möchte ich versuchen zu erklären:

Wenn Sie ein PendingIntentObjekt verwenden möchten, instanziieren Sie nicht nur eines. Vielmehr erhalten Sie eine aus dem System der Verwendung von PendingIntentstatischen Methoden ( getActivity, getBroadcast, getServiceusw.). Das System verwaltet eine Reihe von PendingIntent-Instanzen und gibt Ihnen eine. Welches es Ihnen gibt, hängt von den Eingabeparametern ab, die Sie an diese Getter-Methoden übergeben. Diese Eingabeparameter sind: Contextdh der Zielempfänger der Absicht, der Intentzu verwendende requestCodeund flags. Wenn Sie dieselbe Context, dieselbe requestCodeund dieselbe Absicht übergeben (was bedeutet, dass eine Absicht filterEqualsmit einer anderen Absicht vorliegt), erhalten Sie dasselbe PendingIntentObjekt. Der Punkt ist, dass das System so wenig PendingIntentObjekte wie möglich haben möchte , so dass es dazu neigt, die vorhandenen Objekte so weit wie möglich wiederzuverwenden.

Sie haben beispielsweise zwei Kalenderbenachrichtigungen für zwei verschiedene Daten. Wenn Sie auf eine davon klicken, soll Ihre App zum entsprechenden Datum dieser Benachrichtigung geöffnet werden. In diesem Szenario haben Sie dasselbe ContextZiel, und das IntentObjekt, das Sie übergeben, unterscheidet sich nur in EXTRA_DATA (das das Datum angibt, das geöffnet werden soll). Wenn Sie requestCodebeim Abrufen des PendingIntentObjekts dasselbe angeben , erhalten Sie dasselbe PendingIntentObjekt. Wenn Sie also die zweite Benachrichtigung erstellen, ersetzen Sie die alteIntent Objekt durch das neue EXTRA_DATA und erhalten zwei Benachrichtigungen, die auf dasselbe Datum verweisen.

Wenn Sie PendingIntentwie in diesem Szenario zwei verschiedene Objekte haben möchten, sollten Sie requestCodebeim Abrufen des PendingIntentObjekts ein anderes angeben .

Eir
quelle
Wie ich bereits erwähnt habe, können Sie zum Abbrechen von Alarmen nicht nur den requestCode verwenden. Es bedeutet nichts dafür. Sie müssen zusätzliche Daten eingeben, um zwischen ihnen zu unterscheiden. Ich erinnere mich nicht, aber ich denke, Sie können sogar denselben requestCode für mehrere Alarme verwenden.
Android-Entwickler
@androiddeveloper was du gerade gesagt hast ist falsch. Versuch es.
Eir