219 votes

Comment envoyer les paramètres d'une notification-clic à une activité ?

Je peux trouver un moyen d'envoyer des paramètres à mon activité depuis ma notification.

J'ai un service qui crée une notification. Lorsque l'utilisateur clique sur la notification, je veux ouvrir mon activité principale avec certains paramètres spéciaux. Par exemple, un identifiant d'article, afin que mon activité puisse charger et présenter une vue détaillée de l'article. Plus précisément, je suis en train de télécharger un fichier, et lorsque le fichier est téléchargé, je veux que la notification ait une intention qui, lorsqu'on clique dessus, ouvre mon activité dans un mode spécial. J'ai essayé d'utiliser putExtra sur mon intention, mais je n'arrive pas à l'extraire, donc je pense que je m'y prends mal.

Code de mon service qui crée la Notification :

        // construct the Notification object.
     final Notification notif = new Notification(R.drawable.icon, tickerText, System.currentTimeMillis());

    final RemoteViews contentView = new RemoteViews(context.getPackageName(), R.layout.custom_notification_layout);
    contentView.setImageViewResource(R.id.image, R.drawable.icon);
    contentView.setTextViewText(R.id.text, tickerText);
    contentView.setProgressBar(R.id.progress,100,0, false);
    notif.contentView = contentView;        

    Intent notificationIntent = new Intent(context, Main.class);
    notificationIntent.putExtra("item_id", "1001"); // <-- HERE I PUT THE EXTRA VALUE
    PendingIntent contentIntent = PendingIntent.getActivity(context, 0, notificationIntent, 0);
    notif.contentIntent = contentIntent;

    nm.notify(id, notif);

Code de mon activité qui tente de récupérer le paramètre supplémentaire de la notification :

 public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);

    setContentView(R.layout.main);

    Bundle extras = getIntent().getExtras();
    if(extras != null){
        Log.i( "dd","Extra:" + extras.getString("item_id") );
    }

Les extras sont toujours nuls et je n'obtiens jamais rien dans mon journal.

Btw... le onCreate n'est exécuté que lorsque mon activité commence, si mon activité est déjà commencée, je veux aussi collecter les extras et présenter mon activité en fonction de l'item_id que je reçois.

Des idées ?

252voto

Lucas S. Points 5703

Jetez un coup d'œil à ce guide ( création d'une notification ) et aux échantillons ApiDemos "StatusBarNotifications" et "NotificationDisplay".

Pour gérer si l'activité est déjà en cours, vous avez deux possibilités :

  1. Ajouter FLAG_ACTIVITY_SINGLE_TOP à l'Intent lors du lancement de l'activité, puis dans la classe de l'activité, implémenter l'indicateur onNewIntent(Intent intent) de cette façon, vous pouvez accéder à la nouvelle intention qui a été appelée pour l'activité (ce qui n'est pas la même chose que d'appeler simplement getIntent(), cela renverra toujours la première intention qui a lancé votre activité.

  2. Idem que le numéro un, mais au lieu d'ajouter un drapeau à l'intention, vous devez ajouter "singleTop" dans votre activité AndroidManifest.xml.

Si vous utilisez des extras d'intention, n'oubliez pas d'appeler PendingIntent.getActivity() avec le drapeau PendingIntent.FLAG_UPDATE_CURRENT sinon les mêmes extras seront réutilisés pour chaque notification.

98 votes

Et pour répondre à la question de l'utilisateur sur le fait que les extras sont nuls : Vous devez appeler PendingIntent.getActivity() avec le drapeau PendingIntent.FLAG_UPDATE_CURRENT sinon les mêmes extras seront réutilisés pour chaque notification.

2 votes

Vous avez sauvé ma journée mais pourquoi le transfert de données simples comme celles-ci est si compliqué dans Android.

9 votes

Si vous devez avoir des notifications différentes, assurez-vous d'utiliser des ID de demande différents lorsque vous appelez PendingIntent.getActivity() en plus de fixer FLAG_ACTIVITY_SINGLE_TOP sur le Intent y FLAG_UPDATE_CURRENT sur le PendingIntent . Voir stackoverflow.com/questions/7370324/

102voto

J'ai eu le même problème : mon application affiche des notifications de messages. Lorsqu'il y a plusieurs notifications et que l'on clique sur chacune d'elles, le détail de la notification s'affiche dans une activité de visualisation des messages. J'ai résolu le problème des mêmes paramètres supplémentaires qui sont reçus dans l'intention du message de vue.

Voici le code qui a permis de résoudre ce problème. Code pour la création de l'Intent de notification.

 Intent notificationIntent = new Intent(getApplicationContext(), viewmessage.class);
    notificationIntent.putExtra("NotificationMessage", notificationMessage);
    notificationIntent.addFlags(Intent.FLAG_ACTIVITY_SINGLE_TOP | Intent.FLAG_ACTIVITY_CLEAR_TOP);
    PendingIntent pendingNotificationIntent = PendingIntent.getActivity(getApplicationContext(),notificationIndex,notificationIntent,PendingIntent.FLAG_UPDATE_CURRENT);
    notification.flags |= Notification.FLAG_AUTO_CANCEL;
    notification.setLatestEventInfo(getApplicationContext(), notificationTitle, notificationMessage, pendingNotificationIntent);

Code pour l'activité de visualisation des messages.

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

    onNewIntent(getIntent());
}

@Override
public void onNewIntent(Intent intent){
    Bundle extras = intent.getExtras();
    if(extras != null){
        if(extras.containsKey("NotificationMessage"))
        {
            setContentView(R.layout.viewmain);
            // extract the extra-data in the Notification
            String msg = extras.getString("NotificationMessage");
            txtView = (TextView) findViewById(R.id.txtMessage);
            txtView.setText(msg);
        }
    }

}

32voto

pinaise Points 161

Peut-être un peu tard, mais : au lieu de ça :

public void onNewIntent(Intent intent){
    Bundle extras = intent.getExtras();
    Log.i( "dbg","onNewIntent");

    if(extras != null){
        Log.i( "dbg", "Extra6 bool: "+ extras.containsKey("net.dbg.android.fjol"));
        Log.i( "dbg", "Extra6 val : "+ extras.getString("net.dbg.android.fjol"));

    }
    mTabsController.setActiveTab(TabsController.TAB_DOWNLOADS);
}

Utilisez ça :

Bundle extras = getIntent().getExtras();
if(extras !=null) {
    String value = extras.getString("keyName");
}

23 votes

Il est peut-être tard pour l'OP, mais il n'est jamais tard pour les autres sur Internet :)

20voto

jamchen Points 71

Je rencontre le même problème ici. Je l'ai résolu en utilisant un code de demande différent, en utilisant le même identifiant que la notification, tout en créant PendingIntent. Mais je ne sais toujours pas pourquoi cela doit être fait.

PendingIntent contentIntent = PendingIntent.getActivity(context, **id**, notificationIntent, 0);
notif.contentIntent = contentIntent;
nm.notify(**id**, notif);

0 votes

Tu as fait ma journée !!!

16voto

Vidar Vestnes Points 14317

Après avoir lu quelques listes d'adresses électroniques et d'autres forums, j'ai découvert que l'astuce consiste à ajouter des données uniques à l'intention.

comme ça :

   Intent notificationIntent = new Intent(Main.this, Main.class);
   notificationIntent.putExtra("sport_id", "sport"+id);
   notificationIntent.putExtra("game_url", "gameURL"+id);

   notificationIntent.setData((Uri.parse("foobar://"+SystemClock.elapsedRealtime()))); 

Je ne comprends pas pourquoi il faut faire ça, ça a quelque chose à voir avec le fait que l'intention ne peut pas être identifiée seulement par ses extras...

8 votes

Anroid réutilise les intentions, l'action de l'intention et le code de la requête la rendent unique, mais pas les données supplémentaires. Vous devez donc définir un identifiant de requête unique ou utiliser des actions d'intention différentes.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X