PendingIntent sendet keine Intent-Extras

127

Mein MainActicity beginnt RefreshServicemit einem, Intentder ein booleanExtra genannt hat isNextWeek.

Mein RefreshServicemacht ein, Notificationdas mein startet, MainActivitywenn der Benutzer darauf klickt.

das sieht so aus:

    Log.d("Refresh", "RefreshService got: isNextWeek: " + String.valueOf(isNextWeek));

    Intent notificationIntent = new Intent(this, MainActivity.class);
    notificationIntent.putExtra(MainActivity.IS_NEXT_WEEK, isNextWeek);

    Log.d("Refresh", "RefreshService put in Intent: isNextWeek: " + String.valueOf(notificationIntent.getBooleanExtra(MainActivity.IS_NEXT_WEEK,false)));
    pendingIntent = PendingIntent.getActivity(this, 0, notificationIntent, 0);

    builder = new NotificationCompat.Builder(this).setContentTitle("Title").setContentText("ContentText").setSmallIcon(R.drawable.ic_notification).setContentIntent(pendingIntent);
    notification = builder.build();
    // Hide the notification after its selected
    notification.flags |= Notification.FLAG_AUTO_CANCEL;
    notificationManager.notify(NOTIFICATION_REFRESH, notification);

Wie Sie sehen können, notificationIntentsollte das das booleanExtra haben, IS_NEXT_WEEKdessen Wert in isNextWeekdas eingegeben wird PendingIntent.

Wenn ich jetzt darauf Notificationklicke, bekomme ich immer den falseWert vonisNextWeek

Auf diese Weise erhalte ich den Wert in MainActivity:

    isNextWeek = getIntent().getBooleanExtra(IS_NEXT_WEEK, false);

Log:

08-04 00:19:32.500  13367-13367/de.MayerhoferSimon.Vertretungsplan D/Refresh: MainActivity sent: isNextWeek: true
08-04 00:19:32.510  13367-13573/de.MayerhoferSimon.Vertretungsplan D/Refresh: RefreshService got: isNextWeek: true
08-04 00:19:32.510  13367-13573/de.MayerhoferSimon.Vertretungsplan D/Refresh: RefreshService put in Intent: isNextWeek: true
08-04 00:19:41.990  13367-13367/de.MayerhoferSimon.Vertretungsplan D/Refresh: MainActivity.onCreate got: isNextWeek: false

Wenn ich das direkt MainActivitymit einem Intentmit dem "sNextValue" wie folgt beginne:

    Intent i = new Intent(this, MainActivity.class);
    i.putExtra(IS_NEXT_WEEK, isNextWeek);
    finish();
    startActivity(i);

alles funktioniert gut und ich bekomme truewann isNextWeekist true.

Was mache ich falsch, dass es immer einen falseWert gibt?

AKTUALISIEREN

Dies löst das Problem: https://stackoverflow.com/a/18049676/2180161

Zitat:

Mein Verdacht ist, dass, da sich in der Absicht nur die Extras ändern, die PendingIntent.getActivity(...)Factory-Methode einfach die alte Absicht als Optimierung wiederverwendet.

Versuchen Sie in RefreshService:

PendingIntent pendingIntent = PendingIntent.getActivity(this, 0, notificationIntent, PendingIntent.FLAG_CANCEL_CURRENT);

Sehen:

http://developer.android.com/reference/android/app/PendingIntent.html#FLAG_CANCEL_CURRENT

UPDATE 2

Siehe Antwort unten, warum es besser ist, zu verwenden PendingIntent.FLAG_UPDATE_CURRENT.

maysi
quelle
2
PendingIntent.FLAG_CANCEL_CURRENT hat für mich gearbeitet, danke
Pelanes
1
hat mir viele Stunden Arbeit erspart. korrekte Antwort!
TharakaNirmana
Sie haben die Frage und die Lösung: D großartig. Ich denke, Sie sollten es als Antwort auf die Fragen hinzufügen. + 10s ist besser als + 5s;)
Muhammed Refaat
Verweis auf diese Lösung: stackoverflow.com/questions/1198558/…
M.Noman
Das FLAG_UPDATE_CURRENT hat in meinem Fall nicht ausgereicht, da das gleiche PendingIntent von meinem Widget wiederverwendet wurde. Am Ende habe ich FLAG_ONE_SHOT für die Aktion verwendet, die selten auftritt, und das Widget PendingIntent intakt gelassen.
Eir

Antworten:

29

Die Verwendung von PendingIntent.FLAG_CANCEL_CURRENT ist aufgrund der ineffizienten Speichernutzung keine gute Lösung. Verwenden Sie stattdessen PendingIntent.FLAG_UPDATE_CURRENT .

Verwenden Sie auch Intent.FLAG_ACTIVITY_SINGLE_TOP (die Aktivität wird nicht gestartet, wenn sie bereits oben im Verlaufsstapel ausgeführt wird).

Intent resultIntent = new Intent(this, FragmentPagerSupportActivity.class).
                    addFlags(Intent.FLAG_ACTIVITY_SINGLE_TOP);  
resultIntent.putExtra(FragmentPagerSupportActivity.PAGE_NUMBER_KEY, pageNumber);

PendingIntent resultPendingIntent =
                PendingIntent.getActivity(
                        this,
                        0,
                        resultIntent,
                        PendingIntent.FLAG_UPDATE_CURRENT
                );

Dann:

@Override
    protected void onCreate(Bundle savedInstanceState) {
        try {
            super.onCreate(savedInstanceState);

            int startPageNumber;
            if ( savedInstanceState != null)
            {
                startPageNumber = savedInstanceState.getInt(PAGE_NUMBER_KEY);
//so on

Es sollte jetzt funktionieren.


Wenn Sie immer noch kein erwartetes Verhalten haben, versuchen Sie, die void onNewIntent(Intent intent)Ereignisbehandlungsroutine zu implementieren . Auf diese Weise können Sie auf die neue Absicht zugreifen, die für die Aktivität aufgerufen wurde (was nicht mit dem Aufruf von getIntent () identisch ist). Dies gibt immer die erste Absicht zurück, die gestartet wurde Ihre Aktivität.

@Override
protected void onNewIntent(Intent intent) {
    int startPageNumber;

    if (intent != null) {
        startPageNumber = intent.getExtras().getInt(PAGE_NUMBER_KEY);
    } else {
        startPageNumber = 0;
    }
}
Yuliia Ashomok
quelle
21

Ich denke, Sie müssen das aktualisieren, Intentwenn Sie ein neues erhalten, indem Sie onNewIntent(Intent)Ihre Aktivität überschreiben . Fügen Sie Ihrer Aktivität Folgendes hinzu:

@Override
public void onNewIntent(Intent newIntent) {
    this.setIntent(newIntent);

    // Now getIntent() returns the updated Intent
    isNextWeek = getIntent().getBooleanExtra(IS_NEXT_WEEK, false);        
}

Bearbeiten:

Dies ist nur erforderlich, wenn Ihre Aktivität bereits gestartet wurde, als die Absicht empfangen wurde. Wenn Ihre Aktivität durch die Absicht gestartet (und nicht nur wieder aufgenommen) wird, liegt das Problem an einer anderen Stelle und mein Vorschlag kann es möglicherweise nicht beheben.

Vikram
quelle
Dies wird auch angezeigt, wenn die Aktivität geschlossen und anschließend mit der Benachrichtigung geöffnet wird.
Mai
3

Der folgende Code sollte funktionieren: -

int icon = R.drawable.icon;
String message = "hello";
long when = System.currentTimeMillis();
NotificationManager notificationManager = (NotificationManager) context.getSystemService(Context.NOTIFICATION_SERVICE);
Notification notification = new Notification(icon, message, when);

Intent notificationIntent = new Intent(context, MainActivity.class);
notificationIntent.putExtra("isNexWeek", true);
notificationIntent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP | Intent.FLAG_ACTIVITY_SINGLE_TOP);
PendingIntent pIntent = PendingIntent.getActivity(context, 0, notificationIntent, 0);
notification.setLatestEventInfo(context, title, message, pIntent);
notification.flags |= Notification.FLAG_AUTO_CANCEL;
notificationManager.notify(0, notification);

In MainActivity onCreate:

if (getIntent().getExtras() != null && getIntent().getExtras().containsKey("isNextWeek")) {
        boolean isNextWeek = getIntent().getExtras().getBoolean("isNextWeek");
}
Haris ur Rehman
quelle
new Notification(icon, message, when);ist veraltet
maysi
Wie auch immer, ohne CLEAR_TOP?
Richard