2010-06-29 9 views
57

Pochi giorni fa stavo faticando a trovare un modo per usare intenti personalizzati per i miei allarmi. Anche se ho avuto una risposta chiara, devo personalizzare gli Intenti sulla base di qualche ID univoco, ad es. setAction() hanno ancora alcuni problemi.Android continua a memorizzare nella cache i miei intenti Extra, come dichiarare un intento in sospeso che mantiene gli extra freschi?

definisco un PendingIntent in questo modo:

Intent intent = new Intent(this, viewContactQuick.class); 
intent.setAction("newmessage"+objContact.getId());//unique per contact 
intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK).addFlags(Intent.FLAG_ACTIVITY_SINGLE_TOP); 
intent.putExtra("id", Long.parseLong(objContact.getId())); 
intent.putExtra("results", result.toArray()); 

PendingIntent contentIntent = PendingIntent.getActivity(context, 0, intent, 0); 

allora questo è utilizzato da un gestore di notifica

NotificationManager mNotificationManager = (NotificationManager) context.getSystemService(ns); 
// first try to clear any active notification with this contact ID 
mNotificationManager.cancel(Integer.parseInt(objContact.getId())); 

// then raise a new notification for this contact ID 
mNotificationManager.notify(Integer.parseInt(objContact.getId()), notification); 

Questo funziona in questo modo:

  • applicazione crea un messaggio per un contatto
  • un intento è fornito con h l'id di contatto e dettagli sul messaggio
  • notifica è sollevata con il messaggio
  • actiones utente sulla notifica e l'applicazione visualizza il messaggio passato dalla intento

Il problema

Questo può accadere più di una volta per un contatto. E quando viene generato il secondo messaggio, la notifica viene sollevata bene (il messaggio va bene lì) ma l'intento quando l'utente esegue la notifica utilizza vecchi dati, quindi viene passato il messaggio precedente e non il nuovo messaggio.

Quindi in qualche modo l'intento è di memorizzare nella cache e riutilizzare gli extra precedenti. Come posso renderlo unico per contatto e per azione?

+0

C'è un modo per cancellare tutti gli IntentExcached memorizzati nella cache? Suppongo di averlo corretto ora, ma gli Intenti nella cache più vecchi rimangono ... – OneWorld

+0

Un problema simile può sorgere a seconda dei flag dell'Intento o della modalità di avvio di un'attività.In questo caso, dovrai controllare [Activity :: onNewIntent] (http://j.mp/ieXMCA), perché Activity :: getIntent restituirà l'intento ORIGINAL di Activity, non il nuovo intent con l'azione/gli extra aggiornati /eccetera. – brack

risposta

89

Se solo uno dei tuoi PendingIntents per questo contatto sarà in sospeso in qualsiasi momento o se si desidera utilizzare sempre l'ultimo set di extra, utilizzare FLAG_UPDATE_CURRENT quando si crea lo PendingIntent.

Se più di uno specifico PendingIntent specifico del contatto è in una sola volta e devono disporre di extra separati, è necessario aggiungere un conteggio o un timestamp o qualcosa del genere per distinguerli.

intent.setAction("actionstring" + System.currentTimeMillis()); 

UPDATE

Inoltre, il secondo parametro leggermente documentato getActivity() e parenti su PendingIntent apparentemente può essere utilizzato per creare distinte PendingIntent oggetti per lo stesso sottostante Intent, se non sono mai provato questo

+1

Ho finito per aggiungere un timestamp all'azione. – Pentium10

+7

uomo, hai tutte le risposte –

+1

fantastico! ho usato il mio attuale ID widget per separarli (consentendo anche un certo livello di memorizzazione nella cache). – DavidG

29

Io di solito specificare requestCode unica per evitare che i miei PendingIntents di ignorare l'altro:

PendingIntent pending = PendingIntent.getService(context, unique_id, intent, 0); 

E nel tuo caso sono d'accordo con CommonsWare basta bandiera FLAG_UPDATE_CURRENT. I nuovi extra sostituiranno i vecchi valori.

+4

Questa è la vera soluzione – ognian

+1

Questo non è sufficiente per mantenere i tuoi PendingIntent sono in collisione tra loro. È necessario utilizzare anche PendingIntent.FLAG_UPDATE_CURRENT –

+0

e generare un unique_id qui è una buona soluzione 'int unique_id = (int) System.currentTimeMillis();' –