97 Stimmen

PendingIntent funktioniert bei der ersten Meldung korrekt, bei den übrigen Meldungen jedoch nicht

  protected void displayNotification(String response) {
    Intent intent = new Intent(context, testActivity.class);
    PendingIntent pendingIntent = PendingIntent.getActivity(context, 0, intent, Intent.FLAG_ACTIVITY_NEW_TASK);

    Notification notification = new Notification(R.drawable.icon, "Upload Started", System.currentTimeMillis());
    notification.setLatestEventInfo(context, "Upload", response, pendingIntent);

    nManager.notify((int)System.currentTimeMillis(), notification);
}

Diese Funktion wird mehrere Male aufgerufen. Ich möchte für jede notification um testActivity zu starten, wenn sie angeklickt wird. Leider wird testActivity nur durch die erste Benachrichtigung gestartet. Wenn Sie auf die anderen klicken, wird das Benachrichtigungsfenster minimiert.

Zusätzliche Informationen: Funktion displayNotification() ist in einer Klasse namens UploadManager . Context wird übergeben an UploadManager von der activity die instanziiert. Funktion displayNotification() wird mehrfach von einer Funktion aufgerufen, die sich ebenfalls im UploadManager befindet und in einem AsyncTask .

Edit 1: Ich habe vergessen zu erwähnen, dass ich die String-Antwort in Intent intent als extra .

  protected void displayNotification(String response) {
    Intent intent = new Intent(context, testActivity.class);
    intent.putExtra("response", response);
    PendingIntent pendingIntent = PendingIntent.getActivity(context, 0, intent, PendingIntent.FLAG_UPDATE_CURRENT);

Dies macht einen großen Unterschied, da ich die zusätzliche "Antwort" benötige, um die String-Antwort bei der Erstellung der Benachrichtigung wiederzugeben. Stattdessen wird mit PendingIntent.FLAG_UPDATE_CURRENT Der Zusatz "Antwort" gibt an, wie die String-Antwort beim letzten Aufruf von displayNotification() .

Ich weiß, warum das so ist, denn ich habe die Dokumentation zu FLAG_UPDATE_CURRENT . Ich bin mir jedoch nicht sicher, wie man das Problem im Moment umgehen kann.

140voto

ognian Punkte 11406

Verwenden Sie nicht Intent.FLAG_ACTIVITY_NEW_TASK für PendingIntent.getActivity, verwenden Sie FLAG_ONE_SHOT stattdessen


Aus den Kommentaren kopiert:

Legen Sie dann eine Dummy-Aktion für den Intent fest, andernfalls werden Extras weggelassen. Zum Beispiel

intent.setAction(Long.toString(System.currentTimeMillis()))

67voto

ViliusK Punkte 10839

Hatte zu kämpfen mit RemoteViews und mehrere verschiedene Intents für jede Button auf HomeScreen Widget. Funktioniert, wenn diese hinzugefügt:

1. intent.setAction(Long.toString(System.currentTimeMillis()));

2. PendingIntent.FLAG_UPDATE_CURRENT

        PackageManager pm = context.getPackageManager();

        Intent intent = new Intent(context, MyOwnActivity.class);
        intent.putExtra("foo_bar_extra_key", "foo_bar_extra_value");
        intent.setAction(Long.toString(System.currentTimeMillis()));
        PendingIntent pendingIntent = PendingIntent.getActivity(context, 0,
                intent, PendingIntent.FLAG_UPDATE_CURRENT);
        RemoteViews views = new RemoteViews(context.getPackageName(),
                R.layout.widget_layout);
        views.setOnClickPendingIntent(my_button_r_id_received_in_parameter, pendingIntent);

50voto

ObjectiveTruth Punkte 878

Set Action hat das Problem für mich gelöst. Hier ist mein Verständnis der Situation:


Ich habe mehrere Widgets, denen jeweils ein PendingIntent zugeordnet ist. Wann immer eines aktualisiert wurde, wurden alle aktualisiert. Die Flags sind da, um zu beschreiben, was mit PendingIntents passiert, die genau gleich sind.

Die Beschreibung von FLAG_UPDATE_CURRENT liest sich jetzt viel besser:

Wenn derselbe PendingIntent, den Sie erstellen, bereits existiert, aktualisieren Sie alle alten PendingIntents auf den neuen PendingIntent, den Sie erstellen.

Die Definition von "genau dasselbe" bezieht sich auf den gesamten PendingIntent, ausgenommen die Extras. Also auch wenn Sie verschiedene Extras auf jeder Absicht haben (für mich war ich die appWidgetId hinzufügen) dann zu Android, sie sind die gleichen.

Durch Hinzufügen von .setAction mit einer eindeutigen Dummy-Zeichenkette wird das Betriebssystem informiert. Diese sind völlig unterschiedlich und aktualisieren nichts. Am Ende hier ist meine Implementierung, die funktioniert, wie ich wollte, wo jedes Widget hat seine eigene Konfiguration Intent beigefügt:

Intent configureIntent = new Intent(context, ActivityPreferences.class);

configureIntent.putExtra(AppWidgetManager.EXTRA_APPWIDGET_ID, appWidgetId);

configureIntent.setAction("dummy_unique_action_identifyer" + appWidgetId);

PendingIntent pendingIntent = PendingIntent.getActivity(context, 0, configureIntent,
    PendingIntent.FLAG_UPDATE_CURRENT);

UPDATE


Eine noch bessere Lösung, wenn Sie mit Sendungen arbeiten. Eindeutige PendingIntents werden auch durch eindeutige Anfragecodes definiert. Hier ist meine Lösung:

//Weee, magic number, just want it to be positive nextInt(int r) means between 0 and r
int dummyuniqueInt = new Random().nextInt(543254); 
PendingIntent pendingClearScreenIntent = PendingIntent.getBroadcast(context, 
    dummyuniqueInt, clearScreenIntent, PendingIntent.FLAG_UPDATE_CURRENT);

23voto

steliosf Punkte 3211

Ich sehe Antworten, aber keine Erklärungen. Außerdem geht keine der Antworten auf alle möglichen Lösungen ein, also werde ich versuchen, das klarzustellen.

Dokumentation:

Wenn Sie wirklich mehrere unterschiedliche PendingIntent-Objekte gleichzeitig benötigen (z. B. als zwei Benachrichtigungen, die beide gleichzeitig angezeigt werden), dann müssen Sie sicherstellen, dass sie sich in irgendeiner Weise unterscheiden, um sie mit unterschiedlichen PendingIntents zu verknüpfen. Dies kann eines der Intent-Attribute sein, die von Intent.filterEquals berücksichtigt werden, oder unterschiedliche Anforderungscode-Integer, die an getActivity(Context, int, Intent, int), getActivities(Context, int, Intent[], int), getBroadcast(Context, int, Intent, int) oder getService(Context, int, Intent, int) übergeben werden.

Die Ursache des Problems:

Sie erstellen 2 Benachrichtigungen mit 2 anhängigen Intentionen. Jede ausstehende Absicht ist mit einer Absicht verbunden:

Intent intent = new Intent(context, testActivity.class);

Diese 2 Absichten sind jedoch gleichwertig, d.h. wenn Ihre 2. Benachrichtigung eintrifft, wird die erste Absicht gestartet.

Lösung:

Sie müssen jede Absicht einzigartig machen, so dass keine anhängigen Absichten jemals gleich sein werden. Wie macht man die Absichten einzigartig? Nicht durch die Extras, die Sie mit putExtra() . Auch wenn die Extras unterschiedlich sind, können die Absichten dennoch gleich sein. Um jede Absicht eindeutig zu machen, müssen Sie einen eindeutigen Wert für die Absichtsaktion, die Daten, den Typ, die Klasse, die Kategorie oder den Anfragecode festlegen: (jeder dieser Werte ist geeignet)

  • Aktion: intent.setAction(...)
  • Daten: intent.setData(...)
  • Typ: intent.setType(...)
  • Klasse: intent.setClass(...)
  • Kategorie: intent.addCategory(...)
  • Anfragecode: PendingIntent.getActivity(context, YOUR_UNIQUE_CODE, intent, Intent.FLAG_ONE_SHOT);

Hinweis : Das Festlegen eines eindeutigen Anforderungscodes könnte schwierig sein, da Sie einen int benötigen, während System.currentTimeMillis() gibt long zurück, was bedeutet, dass einige Ziffern entfernt werden. Daher würde ich empfehlen, entweder mit der Kategorie ou le Aktion und die Einstellung einer eindeutigen Zeichenfolge.

13voto

mbauer14 Punkte 1187

Ich hatte das gleiche Problem und konnte es beheben, indem ich die Flagge in eine andere änderte:

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

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X