La notifica supera i vecchi extra di intenti


134

sto creando una notifica all'interno di un BroadcastReceiver tramite questo codice:

String ns = Context.NOTIFICATION_SERVICE;
        NotificationManager mNotificationManager = (NotificationManager) context.getSystemService(ns);
        int icon = R.drawable.ic_stat_notification;
        CharSequence tickerText = "New Notification";
        long when = System.currentTimeMillis();

        Notification notification = new Notification(icon, tickerText, when);
        notification.defaults |= Notification.DEFAULT_VIBRATE;
        long[] vibrate = {0,100,200,200,200,200};
        notification.vibrate = vibrate;
        notification.flags |= Notification.FLAG_AUTO_CANCEL;

        CharSequence contentTitle = "Title";
        CharSequence contentText = "Text";
        Intent notificationIntent = new Intent(context, NotificationActivity.class);
        notificationIntent.putExtra(Global.INTENT_EXTRA_FOO_ID, foo_id);
PendingIntent contentIntent = PendingIntent.getActivity(context, 0, notificationIntent, 0);

        notification.setLatestEventInfo(context, contentTitle, contentText, contentIntent);

        int mynotification_id = 1;

        mNotificationManager.notify(mynotification_id, notification);

Quando faccio clic sulla notifica, si apre NotificationActivity e all'interno dell'Attività posso recuperare foo_id dal pacchetto Intent (es. 1)

Tuttavia, se viene attivata un'altra notifica e faccio clic di nuovo su di essa, l'attività riceve comunque il valore "vecchio" (1) dal pacchetto di intenti. Ho provato a cancellare il pacchetto con clear (), ma sto ricevendo lo stesso effetto. Penso che sth sia sbagliato con il mio codice ..


per favore, puoi dirmi come si ottengono i dati dalle intenzioni in sospeso
user49557

rendersi conto che stava inviando vecchi extra, mi ha reso più facile il mio triaging.
Utsav Gupta,

Risposte:


268

Stai inviando lo stesso codice di richiesta per il tuo intens in sospeso. Cambia questo:

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

Per:

PendingIntent contentIntent = PendingIntent.getActivity(context, UNIQUE_INT_PER_CALL, notificationIntent, 0);

gli intenti non vengono creati se si inviano gli stessi parametri. Sono riutilizzati.


1
quindi UNIQUE_INT_PER_CALL è un numero intero che devo fornire? o è una variabile statica dichiarata da qualche parte?
BrianM,

23
android gotcha # 147 - quindi uno Intentche ha diversi extra (via putExtra) sono considerati uguali e riutilizzati perché non ho fornito un ID univoco a qualche chiamata di intenti in sospeso - terribile api
wal

sai cosa, ero così incurante.
Sto

3
Questo è stato incredibilmente utile per me, solo un suggerimento per gli altri, è probabile che tu stia costruendo la tua notifica con lo stesso metodo, e quindi puoi semplicemente impostare l'id per il nuovo intento in sospeso sullo stesso di quello che stai per utilizzare per l'ID univoco delle notifiche!
James McNee,

1
@IncrediApp, è lo stesso con PendingIntent.getBroadcast (); ?
Shruti,

139

In alternativa, puoi utilizzare il seguente codice per generare il tuo PendingIntent:

PendingIntent contentIntent = PendingIntent.getActivity(context, 0, notificationIntent, PendingIntent.FLAG_UPDATE_CURRENT);

Dal documento per PendingIntent.FLAG_UPDATE_CURRENT:

Se il PendingIntent descritto esiste già, conservalo ma sostituisci i suoi dati extra con ciò che è in questo nuovo Intento. Questo può essere usato se stai creando intenti in cui cambiano solo gli extra e non ti importa che qualsiasi entità che ha ricevuto il tuo PendingIntent precedente sarà in grado di avviarlo con i tuoi nuovi extra anche se non gli sono stati esplicitamente dati.


Grazie ... perfettamente funzionante per questo flag che è aggiunto "PendingIntent.FLAG_UPDATE_CURRENT" :)
Najib Ahmed Puthawala

1
Ha funzionato per me, utilizzando l'intento in sospeso per trasferire lo stato dall'impostazione di un allarme al ricevitore di trasmissione.
William T. Mallard,

Vorrei solo sapere cosa facevano davvero queste bandiere prima di inviare notifiche ai miei utenti (!) Sono contento che questo risolva i miei guai ...
James Andrew

42

Stai passando lo stesso ID. In questo tipo di situazione, crea un ID unico da questo momento:

int iUniqueId = (int) (System.currentTimeMillis() & 0xfffffff);

E per dirla in questo modo:

PendingIntent contentIntent = PendingIntent.getActivity(getApplicationContext(),iUniqueId, intentForNotification, 0);

3
perché non usare new Random (). nextInt ()
exloong il

@hderanga cosa fa l'aggiunta di "& 0xfffffff" all'int sopra?
AJW,

3
@AJW System.currentTimeMillis()restituisce un valore long, mentre il requestIdparametro di PendingIntent.getActivity()accetta un int. 0xffffffffè una maschera di bit. Sebbene ci sia un po 'di più, la semplice spiegazione è che fare `long & 0xffffffff' fornisce i 32 bit più bassi dal long e scarta i 32 bit più alti, lasciandoti essenzialmente con un int a 32 bit. Questo è meglio che semplicemente lanciare su un int perché non confonde il bit del segno (se lanci un long che è più grande di un int in un int il bit del segno traboccerà e potresti finire con un valore negativo )
Jordan Bondo,

8

Per chiunque cerchi l'approccio migliore dopo molto tempo, è necessario passare PendingIntent.FLAG_UPDATE_CURRENT come ultimo argomento come mostrato di seguito

PendingIntent contentIntent = PendingIntent.getActivity(context, 0, notificationIntent, PendingIntent.FLAG_UPDATE_CURRENT);

non è nemmeno necessario fornire un nuovo ID unico.

Devi farlo per la prossima volta e non per la prima volta


1
Non funziona, sono arrivato perché è quello che stavo facendo.
Brill Pappin,

Devi farlo per le prossime volte non per la prima volta, funzionerà.
Dolce

0

Il tuo codice di richiesta è 0 per tutta la notifica. Modifica la seguente riga:

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

Con:

PendingIntent contentIntent = PendingIntent.getActivity(context, new Random().nextInt(), notificationIntent, 0);

1
C'è qualche vantaggio nell'usare "new Random (). NextInt ()" anziché "System.currentTimeMillis ()"?
AJW,

l'utilizzo di random può facilmente rigenerare nuovamente lo stesso valore intero in caso di incidente, causando così il superamento di un bug molto difficile da trovare.
Sam,

@AJW c'era nel mio caso. Ho creato 2 notifiche diverse esattamente nello stesso millisecondo, quindi una di esse ha avuto degli extra sbagliati.
artman,

0

Volevo solo aggiungere un'altra opzione

 PendingIntent.getBroadcast(context, 0, intent, PendingIntent.FLAG_ONE_SHOT | PendingIntent.FLAG_IMMUTABLE);
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.