Die Benachrichtigung besteht aus alten Absichts-Extras

134

Ich erstelle eine Benachrichtigung in einem BroadcastReceiver über diesen Code:

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

Wenn ich auf die Benachrichtigung klicke, wird die Benachrichtigungsaktivität geöffnet und innerhalb der Aktivität kann ich die foo_id aus dem Intent-Bundle abrufen (z. B. 1).

Wenn jedoch eine weitere Benachrichtigung ausgelöst wird und ich erneut darauf klicke, erhält die Aktivität immer noch den "alten" Wert (1) vom Intent-Bundle. Ich habe versucht, das Bundle mit clear () zu löschen, erhalte aber den gleichen Effekt. Ich denke, dass etw mit meinem Code falsch ist.

BrianM
quelle
Bitte können Sie mir sagen, wie Sie die Daten aus anstehenden Absichten erhalten
user49557
zu erkennen, dass es alte Extras schickte, erleichterte mein Triaging.
Utsav Gupta

Antworten:

267

Sie senden denselben Anforderungscode für Ihre ausstehende Intensität. Ändere das:

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

Zu:

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

Absichten werden nicht erstellt, wenn Sie dieselben Parameter senden. Sie werden wiederverwendet.

IncrediApp
quelle
1
Also ist UNIQUE_INT_PER_CALL eine Ganzzahl, die ich angeben muss? oder ist das eine statische Variable, die irgendwo deklariert ist?
BrianM
23
android gotcha # 147 - so Intentdass ein , der verschiedene Extras (via putExtra) hat, als gleich angesehen und wiederverwendet werden, weil ich keine eindeutige ID für einen ausstehenden Absichtsanruf angegeben habe - schreckliche API
Wal
Weißt du was? Ich war so nachlässig. Ich denke nur, wie könnte es 0 in einem Block bleiben (in meinem Fall) :(
Exigente05
3
Dies war unglaublich nützlich für mich, nur ein Tipp für andere. Es ist wahrscheinlich, dass Sie Ihre Benachrichtigung auf dieselbe Weise erstellen. Daher können Sie die ID für die neue ausstehende Absicht einfach auf die gleiche festlegen, die Sie möchten Verwenden Sie für die Benachrichtigungen eindeutige ID!
James McNee
1
@IncrediApp, ist es dasselbe mit PendingIntent.getBroadcast (); ?
Shruti
138

Alternativ können Sie den folgenden Code verwenden, um Ihren PendingIntent zu generieren:

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

Aus dem Dokument für PendingIntent.FLAG_UPDATE_CURRENT:

Wenn der beschriebene PendingIntent bereits vorhanden ist, behalten Sie ihn bei, ersetzen Sie jedoch seine zusätzlichen Daten durch die Daten in diesem neuen Intent. Dies kann verwendet werden, wenn Sie Absichten erstellen, bei denen sich nur die Extras ändern, und es egal ist, dass Entitäten, die Ihr vorheriges PendingIntent erhalten haben, es mit Ihren neuen Extras starten können, auch wenn sie nicht explizit angegeben werden.

ChristophK
quelle
Danke ... perfekt für diese Flagge, die "PendingIntent.FLAG_UPDATE_CURRENT" hinzufügt :)
Najib Ahmed Puthawala
1
Arbeitete für mich mit der ausstehenden Absicht, den Status von der Einstellung eines Alarms auf den Rundfunkempfänger zu übertragen.
William T. Mallard
Ich wünschte nur, ich wüsste, was diese Flags wirklich taten, bevor ich Benachrichtigungen an meine Benutzer verschickte (!). Ich bin froh, dass dies meine
James Andrew
42

Sie übergeben dieselbe ID. Erstellen Sie in einer solchen Situation aus dieser Zeit eine eindeutige ID:

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

Und sagen Sie es so:

PendingIntent contentIntent = PendingIntent.getActivity(getApplicationContext(),iUniqueId, intentForNotification, 0);
hderanga
quelle
3
warum nicht neues Random () verwenden. nextInt ()
exloong
@hderanga Was macht das Hinzufügen von "& 0xfffffff" zum obigen Int?
AJW
3
@AJW System.currentTimeMillis()gibt eine lange zurück, während der requestIdParameter von PendingIntent.getActivity()ein int nimmt. 0xffffffffist eine Bitmaske. Es steckt zwar noch ein bisschen mehr dahinter, aber die einfache Erklärung ist, dass "long & 0xffffffff" die niedrigsten 32-Bit-Werte aus den Long-Werten ergibt und die höchsten 32-Bit-Werte verwirft, sodass Sie im Wesentlichen einen 32-Bit-Int erhalten. Dies ist besser als das einfache Umwandeln in ein Int, da es das Vorzeichenbit nicht durcheinander bringt (wenn Sie ein Long, das größer als ein Int ist, in ein Int umwandeln, läuft das Vorzeichenbit über und Sie erhalten möglicherweise einen negativen Wert )
Jordan Bondo
8

Für alle, die nach langer Zeit nach dem besten Ansatz suchen, müssen Sie PendingIntent.FLAG_UPDATE_CURRENT als letztes Argument übergeben, wie unten gezeigt

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

Sie müssen nicht einmal eine neue eindeutige ID angeben.

Sie müssen dies für das nächste Mal nicht zum ersten Mal tun

Sanft
quelle
1
Das funktioniert nicht, ich bin hierher gekommen, weil ich das getan habe.
Brill Pappin
Sie müssen dies für das nächste Mal nicht zum ersten Mal tun, es wird funktionieren.
Gentle
0

Ihr Anforderungscode ist 0 für alle Benachrichtigungen. Ändern Sie die folgende Zeile:

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

Mit:

PendingIntent contentIntent = PendingIntent.getActivity(context, new Random().nextInt(), notificationIntent, 0);
Faisal Shaikh
quelle
1
Hat die Verwendung von "new Random (). NextInt ()" anstelle von "System.currentTimeMillis ()" einen Vorteil?
AJW
Die Verwendung von random kann bei einem Unfall leicht den gleichen ganzzahligen Wert erneut generieren, was zu einem sehr schwer zu findenden Fehler bei der Übergabe alter Absichten führt.
Sam
@AJW gab es in meinem Fall. Ich habe 2 verschiedene Benachrichtigungen in genau derselben Millisekunde erstellt, sodass eine von ihnen falsche Extras erhalten hat.
Artman
0

Ich wollte nur eine weitere Option hinzufügen

 PendingIntent.getBroadcast(context, 0, intent, PendingIntent.FLAG_ONE_SHOT | PendingIntent.FLAG_IMMUTABLE);
Pellucid
quelle