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.