Per cosa viene utilizzato "requestCode" su PendingIntent?


110

Sfondo:

Sto usando PendingIntent per gli allarmi tramite AlarmManager.

Il problema:

All'inizio ho pensato che per cancellare i precedenti, dovevo fornire l'esatto requestCode che ho usato prima per far partire l'allarme.

Ma poi ho scoperto che mi sbagliavo, come dice l' API di cancellazione :

Rimuovi tutti gli allarmi con un intento corrispondente. Qualsiasi allarme, di qualsiasi tipo, il cui Intent corrisponde a questo (come definito da filterEquals (Intent)), verrà annullato.

guardando " filterEquals ", la documentazione dice:

Determina se due intenti sono uguali ai fini della risoluzione dell'intento (filtraggio). Cioè, se la loro azione, i dati, il tipo, la classe e le categorie sono gli stessi. Questo non confronta i dati aggiuntivi inclusi negli intenti.

quindi non capisco a cosa serva "requestCode" ...

La domanda:

A cosa serve "requestCode"?

Cosa succede se creo più allarmi con lo stesso "requestCode"? si sovrascrivono a vicenda?


se usi lo stesso codice di richiesta otterrai lo stesso PendingIntent
pskink

3
Per PendingIntent.getBroadcast (), requestCode viene apparentemente ignorato da Android. A partire dall'API 22, non renderà unico il tuo intento in sospeso. Funziona per getActivity () (e forse getService () ma non l'ho testato). stackoverflow.com/a/33203752/2301224
Baker

@Baker Non è considerato un bug? Se si tratta di un bug, dovresti scriverne qui: code.google.com/p/android/issues/list
sviluppatore Android

1
Bene, in realtà, la documentazione specifica l'usaga del 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 Right, quindi qual è il punto nell'usare requestCode? Dove può essere utilizzato?
sviluppatore Android

Risposte:


77
  1. requestCode viene utilizzato per recuperare la stessa istanza di intento in sospeso in un secondo momento (per l'annullamento, ecc.).
  2. Sì, la mia ipotesi è che gli allarmi si sovrascriveranno a vicenda. Manterrei i codici di richiesta unici.

5
è necessario impostare requestCode come univoco anche nel caso in cui gli intenti degli allarmi siano molto diversi (uno per il servizio A e uno per il servizio B, ad esempio)? Inoltre, come mai la documentazione non dice nulla al riguardo? È possibile rimuovere tutti gli allarmi di un certo tipo, qualunque sia il requestCode?
sviluppatore Android

1
No, non è necessario per intenti diversi. E non so perché la documentazione non dice nulla al riguardo, ma l'ho imparato impostando allarmi ripetuti e anche usando lo stesso intento.
Minhaj Arfin

2
Stavo parlando di PendingIntent. startActivityForResult utilizza un intento normale.
sviluppatore Android

2
qual è lo scopo di "startActivityForResult con PendingIntent utilizzando un'attività proxy"? Puoi fare un esempio?
sviluppatore Android

3
Sono d'accordo; la documentazione per PendingIntent e AlarmManager è totale, aggravata dal fatto che non è possibile elencare gli allarmi in modo programmatico.
Someone Somewhere

33

Voglio solo aggiungere alla risposta di @Minhaj Arfin

1- requestCode viene utilizzato per ottenere lo stesso intento in sospeso in seguito (per l'annullamento, ecc.)

2- Sì, verranno ignorati a condizione che tu specifichi lo stesso destinatario per il tuo intento che hai specificato nel tuo PendingIntent

esempio:

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

Dall'esempio sopra, non si sovrascriveranno l'un l'altro perché il ricevitore è diverso (AlarmReceiverFirst e 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);

Dall'esempio sopra, essi si sostituiscono reciprocamente, perché il ricevitore è stesso (AlarmReceiverSecond)


Intent startIntent4 = new Intent (context, AlarmReceiverSecond.class); PendingIntent pendingIntent4 = PendingIntent.getService (context, 0, startIntent4, 0); andrebbe bene allora? Voglio dire, questo non sovrascriverà perché chiama getService () invece di getBroadcast ()?
Jenix

Mi dispiace porre un'altra domanda ma poiché stackoverflow non mi consente di scrivere una domanda senza una singola riga di codice .. L'ultimo argomento dei metodi di PendingIntent come getBroadcast () non ha qualcosa a che fare con l'override? Ho usato per mettere 0 lì proprio come il tuo codice di esempio sopra, ma ho anche visto che molte persone stavano mettendo un valore di opzione specifico invece di 0.
Jenix

1
@Jenix uou uso AlarmReceiverSecond.classsull'intento e poi usa PendingIntent.getService(). Non funzionerà, poiché AlarmReceiverSecond.classè un BroadcastReceiver, non unService
HendraWD

1
Riguardo ai flag, sono le proprietà che puoi impostare che renderanno il comportamento del tuo PendingIntent secondo i flag che hai fornito. 0 significa tutte le bandiere spente
HendraWD

Ah, sono stato stupido haha ​​Cosa diavolo stavo pensando .. Ero un po 'confuso riguardo a PendingIntent e la tua risposta è stata davvero utile. E volevo solo renderlo più chiaro, ma ora ho capito che la mia domanda all'inizio non aveva alcun senso. Grazie!
Jenix

2

nel mio caso voglio aprire la stessa attività con due intenti diversi, quindi se due o più FCMS sono presenti nel vassoio, ognuno di essi aprirà solo l'altro no, quindi ho cambiato i codici delle richieste di intento in sospeso, quindi ha funzionato.

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

non c'era bisogno di controllare ulteriormente il codice per il mio caso, puoi dire nel qual caso sarà richiesta l'istanza di intento in sospeso. Per quanto riguarda la modifica della domanda, il codice di richiesta mi ha aiutato a passare alla schermata corretta, non so se è il modo corretto e per me l'errore si verificava solo quando più FCM erano presenti nel vassoio
JSONParser

Allora perché impostare un codice di richiesta diverso, se non ne hai bisogno?
sviluppatore Android

ok spiegherò in dettaglio, ho avuto qualche ATTIVITÀ A, ha lo scopo di mostrare domande passerò l'id dalle notifiche attraverso l'intento e quindi effettuerò una richiesta di rete per quell'ID e recupererò la domanda particolare, quindi cosa stava succedendo quando lì ci sono più di 1 notifiche nella barra delle notifiche e quindi faccio clic su una di esse e ottengo l'ID della domanda che era nel primo GCM, dopo aver modificato il codice di richiesta di intento in sospeso con un valore univoco che ha funzionato. Spero di averlo chiarito ora, se sono necessarie ulteriori discussioni ci sono, voglio anche saperne di più, grazie
JSONParser

Oh, volevi dire che altrimenti non avrebbe funzionato affatto, giusto? Scusa per la confusione. Questa domanda è stata posta molto tempo fa e non la ricordo affatto bene ...
sviluppatore Android

1

una cosa importante al riguardo requestCodecreerà seri problemi alla tua app quando utilizzi i widget. i widget non funzioneranno dopo il riavvio del telefono se requestCodesono gli stessi. ciò significa che il codice che pendingIndenthai impostato sul remoteViewstuo widget deve essere un requestCode univoco, solitamente il widgetId che accompagna un numero.


0

In realtà, la documentazione indica chiaramente a cosa serve il codice di richiesta:

Se hai davvero bisogno di più oggetti PendingIntent distinti attivi allo stesso tempo (ad esempio da usare come due notifiche che vengono mostrate entrambe contemporaneamente), allora dovrai assicurarti che ci sia qualcosa di diverso su di loro per associarli a PendingIntents. Questo può essere uno qualsiasi degli attributi Intent considerati da Intent # filterEquals (Intent) o diversi numeri interi del codice di richiesta forniti a getActivity (Context, int, Intent, int), getActivities (Context, int, Intent [], int), getBroadcast ( Context, int, Intent, int) o getService (Context, int, Intent, int).

Dal momento che sembra che non sia ancora così chiaro, provo a spiegare:

Quando vuoi usare un PendingIntentoggetto, non ne crei solo un'istanza. Piuttosto, si ottiene uno dal sistema utilizzando i PendingIntentmetodi statici ( getActivity, getBroadcast, getServiceecc). Il sistema mantiene un mucchio di istanze PendingIntent e te ne dà una. Quale ti dà, dipende dai parametri di input che passi a questi metodi getter. Questi parametri di input sono:, Contextovvero il destinatario di destinazione dell'intento, Intentda usare requestCodee flags. Quando passi lo stesso Context, lo stesso requestCodee lo stesso intento (ovvero un intento che filterEqualscon un altro intento), ottieni lo stesso PendingIntentoggetto. Il punto è che il sistema vuole avere il minor numero di PendingIntentoggetti possibile, quindi tende a riutilizzare quelli esistenti, il più possibile.

Ad esempio, hai due notifiche di calendario, per due date diverse. Quando fai clic su uno di essi, desideri che la tua app si apra alla data corrispondente della notifica. In quello scenario, hai la stessa Contextdestinazione e l' Intentoggetto che stai passando differisce solo in EXTRA_DATA (che specifica la data che dovrebbe essere aperta). Se fornisci lo stesso requestCodequando ottieni l' PendingIntentoggetto, finirai con lo stesso PendingIntentoggetto. Quindi, quando crei la seconda notifica, sostituirai il vecchio Intentoggetto con il nuovo EXTRA_DATA e finirai con due notifiche che puntano alla stessa data.

Se vuoi avere due PendingIntentoggetti diversi , come dovresti in questo scenario, dovresti specificarne uno diverso requestCodequando ottieni l' PendingIntentoggetto.


Ma come ho già detto, per cancellare gli allarmi, non puoi usare solo requestCode. Non significa niente per questo. Dovrai inserire dati extra per differenziarli. Non ricordo, ma penso che tu possa persino usare lo stesso requestCode per più allarmi.
sviluppatore Android

@androiddeveloper quello che hai appena detto non è corretto. Provalo.
Eir
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.