PendingIntent n'envoie pas de suppléments d'intention

127

Mon MainActicity commence RefreshServicepar un Intentqui a un booleanextra appelé isNextWeek.

My RefreshServicecrée un Notificationqui démarre my MainActivitylorsque l'utilisateur clique dessus.

cela ressemble à ceci:

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

Comme vous pouvez le voir, le notificationIntentdevrait avoir le booleansupplément IS_NEXT_WEEKdont la valeur isNextWeekest placée dans le fichier PendingIntent.

Quand je clique maintenant, Notificationje reçois toujours falsecomme valeur deisNextWeek

C'est ainsi que j'obtiens la valeur dans MainActivity:

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

Journal:

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

Quand je démarre directement le MainActivityavec un Intentavec le "sNextValue" comme ceci:

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

tout fonctionne bien et je reçois truequand isNextWeekest true.

Qu'est-ce que je fais de mal qu'il y ait toujours une falsevaleur?

METTRE À JOUR

cela résout le problème: https://stackoverflow.com/a/18049676/2180161

Citation:

Je soupçonne que, puisque la seule chose qui change dans l'intention est les extras, la PendingIntent.getActivity(...)méthode d'usine consiste simplement à réutiliser l'ancienne intention comme une optimisation.

Dans RefreshService, essayez:

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

Voir:

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

MISE À JOUR 2

Voir la réponse ci-dessous pourquoi il est préférable d'utiliser PendingIntent.FLAG_UPDATE_CURRENT.

maysi
la source
2
PendingIntent.FLAG_CANCEL_CURRENT a travaillé pour moi, merci
Pelanes
1
m'a sauvé de nombreuses heures de travail. bonne réponse!
TharakaNirmana
vous avez la question et la solution: D super. Je pense que vous devriez l'ajouter comme réponse aux questions. + 10s vaut mieux que + 5s;)
Muhammed Refaat
En référence à cette solution: stackoverflow.com/questions/1198558/…
M.Noman
Le FLAG_UPDATE_CURRENT ne suffisait pas dans mon cas, puisque le même PendingIntent a été réutilisé par mon widget. J'ai fini par utiliser FLAG_ONE_SHOT pour l'action qui se produit rarement et j'ai laissé le widget PendingIntent intact.
Eir

Réponses:

30

L'utilisation de PendingIntent.FLAG_CANCEL_CURRENT n'est pas une bonne solution en raison d'une utilisation inefficace de la mémoire. Utilisez plutôt PendingIntent.FLAG_UPDATE_CURRENT .

Utilisez également Intent.FLAG_ACTIVITY_SINGLE_TOP (l'activité ne sera pas lancée si elle est déjà en cours d'exécution en haut de la pile d'historique).

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

Ensuite:

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

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

Cela devrait fonctionner maintenant.


Si vous n'avez toujours pas de comportement attendu, essayez d'implémenter le void onNewIntent(Intent intent)gestionnaire d'événements, de cette façon vous pouvez accéder au nouvel intent qui a été appelé pour l'activité (ce qui n'est pas la même chose que d'appeler simplement getIntent (), cela retournera toujours le premier Intent qui a été lancé votre activité.

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

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

Je pense que vous devez mettre à jour le Intentlorsque vous en recevez un nouveau en remplaçant onNewIntent(Intent)votre activité. Ajoutez ce qui suit à votre activité:

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

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

Éditer:

Cela n'est nécessaire que si votre activité a déjà été démarrée lorsque l'intention est reçue. Si votre activité est démarrée (et pas simplement reprise) par l'intention, alors le problème est ailleurs et ma suggestion ne peut pas le résoudre.

Vikram
la source
cela apparaît également si l'activité est fermée et ensuite ouverte avec la notification.
maysi
3

Le code suivant devrait fonctionner: -

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

Dans MainActivity onCreate:

if (getIntent().getExtras() != null && getIntent().getExtras().containsKey("isNextWeek")) {
        boolean isNextWeek = getIntent().getExtras().getBoolean("isNextWeek");
}
Haris ur Rehman
la source
new Notification(icon, message, when);est obsolète
maysi
Quoi qu'il en soit pour le faire sans CLEAR_TOP?
Richard