2010-06-27 7 views
32

Questa domanda in qualche modo si riferisce alla domanda quando stavo cercando di get the extras back in startActivityForResult ma ora devo affrontare un'altra sfida.Perché PendingIntent non restituisce la mia configurazione Extra personalizzata per l'intenzione?

Mi sono abbonato per ricevere ProximityAlerts e ho esplicitamente costruito l'intento per includere alcuni extra. Ma quando ho ricevuto il servizio gli extra non ci sono.

Dopo le risposte qui è il codice di lavoro:

Intent intent = new Intent(this, PlacesProximityHandlerService.class); 
intent.setAction("PlacesProximityHandlerService"); 
intent.putExtra("lat", objPlace.getLat()); 
intent.putExtra("lon", objPlace.getLon()); 
intent.putExtra("error_m", objPlace.getError()+ALERT_RANGE_IN_METERS); 
PendingIntent sender=PendingIntent.getService(this, 0, intent, 0); 
LocationUtils.addProximity(this, objPlace.getLat(), objPlace.getLon(),objPlace.getError()+ALERT_RANGE_IN_METERS, -1, sender); 

La documentazione dice param PendingIntent to be sent for each location update

risposta

40

Per alcuni motivi non specificati, gli extra verranno consegnati solo se è stata impostata un'azione, ad esempio setAction ("pippo"). Ciò a cui CommonsWare fa riferimento si applica solo quando si ottengono istanze PendingIntent, se non è stato impostato FLAG_ONE_SHOT. Questo può essere risolto dall'argomento requestCode in PendingIntent.get ... metodi factory. Anche se la documentazione dice che non è attualmente utilizzata, in realtà prende in considerazione quando si distingue PendingIntents.

Nel tuo caso, non è necessario impostare nient'altro che una stringa di azione fittizia. LocationManagerService riutilizza il PendingIntent che hai sottoscritto per gli avvisi di prossimità e aggiunge un flag solo se il telefono è entrato o uscito dal range di allarme.

+0

ho provato questo e non ha funzionato. Ho impostato prima un'azione sul mio intento e poi gli extra e dopo ho quindi creato un intento in sospeso che spara un ricevitore di trasmissione che lo spara utilizzando un gestore di allarmi – jonney

21

Se si dispone di più eccezionale PendingIntents, è necessario fare in modo che il sottostante Intents differiscono in più rispetto ai loro extra. In caso contrario, Android continuerà a riutilizzare il primo PendingIntent che hai creato per il tuo primo Intent, utilizzando i primi extra di Intent per tutto il tempo.

Ad esempio, è possibile aggiungere un'azione unica via setAction() - che non cambierà la vostra Intent di routing (dal momento che si sta specificando il componente), ma renderà il vostro Intents diverso.

+0

Sono riuscito a farlo funzionare anche con setAction. Nel mio caso ho creato una stringa univoca per ogni chiamata setAction. – drogon

+0

Che dire di PendingIntent.FLAG_ONE_SHOT? Pensavo che questo risolvesse il problema. – Sotti

+0

@Sotti: 'FLAG_ONE_SHOT' dice che il' PendingIntent' può essere eseguito una sola volta. Ora, idealmente, ciò significherebbe * anche * che un tentativo di creare un nuovo 'PendingIntent' su un equivalente' Intent' restituirebbe un distinto 'PendingIntent' ... e potrebbe. Tuttavia, non si tratta di un comportamento documentato, quindi sono riluttante a raccomandare "FLAG_ONE_SHOT". Ora, la risposta accettata su questa domanda dice che funziona, ed è stato svalutato un bel po ', quindi forse è sicuro. Personalmente, dato il track record di Google, tendo ad essere un po 'prudente nei casi limite come questo. – CommonsWare

1

La chiave è quello di impostare gli extra e l'azione unico nel intento prima chiamare

PendingIntent sender=PendingIntent.getService(this, 0, intent, 0); 

se si impostano gli extra ed azione in l'intento dopo chiamare quanto sopra, non lo farà lavoro. Questo sarà non lavoro:

Intent intent; 
PendingIntent sender=PendingIntent.getService(this, 0, 
    intent=new Intent(this, PlacesProximityHandlerService.class), 0); 

intent.setAction("PlacesProximityHandlerService"); 
intent.putExtra("lat", objPlace.getLat()); 
+0

Si prega di rivedere il codice. – Richard

7

Ho avuto questo problema e la soluzione che ho trovato è stato abbastanza semplice, anche se non riesco a spiegare perché ha funzionato.

Inizialmente il mio intento in attesa si presentava così:

 notificationIntent = new Intent(ctx, FragmentTabsPager.class); 
    notificationIntent.setData(Uri.parse("content://com.sbs.mobile.workorder.WorkOrder/notes/")); 
    notificationIntent.putExtra("NOTIFICATION", true); 
    notificationIntent.putExtra(WorkOrder.WorkOrderColumns.WORKORDERID, submessage); 

Quando si crea l'intento di questo tipo, sarebbe passato nessun extra quando la notifica è stato cliccato, la mappa extra sarebbe vuoto nell'attività di ricezione. Ho fatto la seguente modifica alla linea di inizializzazione del notificationIntent:

 notificationIntent = new Intent().setClass(ctx, FragmentTabsPager.class); 

Ora gli extra sono popolati nell'attività di ricezione. Ancora una volta, non posso spiegare perché funzioni, ma ha risolto il mio problema.

+1

ho provato questo per disperazione, e sorprendentemente ha funzionato ... guardando il codice, non sembra esserci alcuna ragione per cui farlo in questo modo sarebbe diverso. sospiro. – handler

2

Nessuna delle risposte ha funzionato per me.L'impostazione dell'azione su una stringa specifica funziona per la prima volta ma se si utilizza la stessa notifica con diversi extra in un secondo momento, non funzionerebbe. Ho sostituito la stringa per il metodo setAction con uno generato in modo casuale uno e funziona senza problemi:

intent.setAction(new Random().nextInt(50) + "_action"); 
  • Se si pensa che si potrebbe utilizzare la notifica molto (come per il download di file diversi) e poi passare un numero maggiore a nextInt()
Problemi correlati