PendingIntent nie wysyła dodatków Intent

127

Moi MainActicity zaczyna RefreshServicez Intentktórym ma booleanEXTRA nazwie isNextWeek.

My RefreshServicetworzy, Notificationktóry zaczyna mój, MainActivitygdy użytkownik go kliknie.

wygląda to tak:

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

Jak widać, notificationIntentpowinien mieć booleandodatek, IS_NEXT_WEEKktórego wartość isNextWeekjest umieszczana w PendingIntent.

Kiedy klikam teraz Notification, zawsze otrzymuję falsewartośćisNextWeek

W ten sposób otrzymuję wartość w 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

Kiedy bezpośrednio zaczynam od MainActivitya Intentz ìsNextValue` w ten sposób:

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

wszystko działa dobrze i dostaję, truekiedy isNextWeekjest true.

Co mam zrobić źle, że zawsze jest jakaś falsewartość?

AKTUALIZACJA

to rozwiązuje problem: https://stackoverflow.com/a/18049676/2180161

Zacytować:

Podejrzewam, że ponieważ jedyną rzeczą zmieniającą się w Intencji są dodatki, PendingIntent.getActivity(...)metoda fabryczna polega po prostu na ponownym wykorzystaniu starej intencji jako optymalizacji.

W RefreshService spróbuj:

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

Widzieć:

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

AKTUALIZACJA 2

Zobacz odpowiedź poniżej, dlaczego lepiej jest używać PendingIntent.FLAG_UPDATE_CURRENT.

maysi
źródło
2
PendingIntent.FLAG_CANCEL_CURRENT pracował dla mnie, dzięki
Pelanes
1
zaoszczędził mi wiele godzin pracy. poprawna odpowiedź!
TharakaNirmana
masz pytanie i rozwiązanie: D super. Myślę, że powinieneś dodać to jako odpowiedź na pytania. + 10s jest lepsze niż + 5s;)
Muhammed Refaat
Odniesienie do tego rozwiązania: stackoverflow.com/questions/1198558/ ...
M.Noman
FLAG_UPDATE_CURRENT nie wystarczyło w moim przypadku, ponieważ ten sam PendingIntent został ponownie użyty przez mój widżet. Skończyło się na użyciu FLAG_ONE_SHOT do akcji, która występuje rzadko, i pozostawiłem widget PendingIntent nietknięty.
Eir

Odpowiedzi:

29

Używanie PendingIntent.FLAG_CANCEL_CURRENT nie jest dobrym rozwiązaniem z powodu nieefektywnego wykorzystania pamięci. Zamiast tego użyj PendingIntent.FLAG_UPDATE_CURRENT .

Użyj również Intent.FLAG_ACTIVITY_SINGLE_TOP (działanie nie zostanie uruchomione, jeśli jest już uruchomione na szczycie stosu historii).

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

Następnie:

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

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

Teraz powinno działać.


Jeśli nadal nie spodziewasz się zachowania, spróbuj zaimplementować void onNewIntent(Intent intent)procedurę obsługi zdarzeń, aby uzyskać dostęp do nowej intencji, która została wywołana dla działania (co nie jest tym samym, co samo wywołanie metody getIntent (), zawsze zwróci to pierwszą intencję, która została uruchomiona Twoja aktywność.

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

    if (intent != null) {
        startPageNumber = intent.getExtras().getInt(PAGE_NUMBER_KEY);
    } else {
        startPageNumber = 0;
    }
}
Yuliia Ashomok
źródło
21

Myślę, że musisz zaktualizować, Intentkiedy otrzymasz nowy, nadpisując onNewIntent(Intent)w swojej aktywności. Dodaj następujące elementy do swojej aktywności:

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

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

Edytować:

Jest to potrzebne tylko wtedy, gdy Twoja aktywność została już rozpoczęta w momencie odebrania intencji. Jeśli Twoja aktywność została rozpoczęta (a nie tylko wznowiona) przez zamiar, problem występuje gdzie indziej i moja sugestia może go nie naprawić.

Vikram
źródło
pojawia się również wtedy, gdy działanie jest zamknięte, a następnie otwarte z powiadomieniem.
maysi
3

Poniższy kod powinien działać: -

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

W MainActivity onCreate:

if (getIntent().getExtras() != null && getIntent().getExtras().containsKey("isNextWeek")) {
        boolean isNextWeek = getIntent().getExtras().getBoolean("isNextWeek");
}
Haris ur Rehman
źródło
new Notification(icon, message, when);jest przestarzałe
maysi
Zresztą zrobić to bez CLEAR_TOP?
Richard