web-dev-qa-db-fra.com

Comment envoyer des paramètres d'un clic de notification à une activité?

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

J'ai un service qui crée une notification. Lorsque l'utilisateur clique sur la notification, je souhaite ouvrir mon activité principale avec certains paramètres spéciaux. Par exemple, un identifiant d'élément, afin que mon activité puisse charger et présenter une vue détaillée d'élément. Plus spécifiquement, je télécharge un fichier et, lorsque le fichier est téléchargé, je souhaite que la notification ait une intention telle que, lorsque l'utilisateur clique dessus, il ouvre mon activité dans un mode spécial. J'ai essayé d'utiliser putExtra dans mon intention, mais je n'arrive pas à l'extraire et je pense donc que je me trompe.

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 d'extraire 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’inscris jamais rien dans mon journal.

Btw ... la onCreate n'est exécutée qu'au début de mon activité. Si mon activité est déjà commencée, je souhaite également collecter les extras et présenter mon activité en fonction de l'item_id que je reçois.

Des idées?

184
Vidar Vestnes

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

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

  1. Ajoutez le drapeau FLAG_ACTIVITY_SINGLE_TOP à l’intention lors du lancement de l’activité, puis dans la classe d’activité implémenter le gestionnaire d’événements onNewIntent (Intent Intent) afin Ce n’est pas la même chose que d’appeler getIntent (), cela retournera toujours la première intention qui a lancé votre activité.

  2. Identique au numéro un, mais au lieu d’ajouter un indicateur à l’intention, vous devez ajouter "singleTop" dans votre activité AndroidManifest.xml.

Si vous utilisez des extras d'intention, rappelez-vous d'appeler PendingIntent.getActivity() avec l'indicateur PendingIntent.FLAG_UPDATE_CURRENT, sinon les mêmes extras seront réutilisés pour chaque notification.

225
Lucas S.

J'ai eu le problème similaire mon application affiche des notifications de message . Quand il y a plusieurs notifications et en cliquant sur chaque notification, il affiche ce détail de la notification dans une activité de message de vue. J'ai résolu le problème de la réception des mêmes paramètres supplémentaires dans l'intention de voir le message.

Voici le code qui a corrigé ce code pour la création de la notification Intention.

 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 afficher l'activité du message.

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


}
87

Peut-être un peu tard, mais: Au lieu de ceci:

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 ceci:

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

Rencontrez le même problème ici .. Je résous le problème en utilisant un code de demande différent, utilise le même identifiant que notification, lors de la création de PendingIntent mais je ne sais toujours pas pourquoi cela devrait être fait.

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

Après avoir lu certaines listes de courrier électronique et d'autres forums, j'ai constaté que l'astuce semble 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 cela doit être fait, cela a quelque chose à voir avec l'intention de ne pas être identifié que par ses extras ...

13
Vidar Vestnes

J'ai tout essayé mais rien n'a fonctionné.

a finalement trouvé la solution suivante.

1- dans manifeste ajouter pour l'activité Android: launchMode = "singleTop"

2- tout en faisant en sorte que l'intention en attente soit comme suit, utilisez bundle au lieu d'utiliser directement intent.putString () ou intent.putInt ()

                    Intent notificationIntent = new Intent(getApplicationContext(), CourseActivity.class);

                    Bundle bundle = new Bundle();
                    bundle.putString(Constants.EXAM_ID,String.valueOf(lectureDownloadStatus.getExamId()));
                    bundle.putInt(Constants.COURSE_ID,(int)lectureDownloadStatus.getCourseId());
                    bundle.putString(Constants.IMAGE_URL,lectureDownloadStatus.getImageUrl());

                    notificationIntent.putExtras(bundle);

                    notificationIntent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP |
                            Intent.FLAG_ACTIVITY_SINGLE_TOP);
                    PendingIntent contentIntent = PendingIntent.getActivity(getApplicationContext(),
                            new Random().nextInt(), notificationIntent,
                            PendingIntent.FLAG_UPDATE_CURRENT); 
9
Dheeraj Sachan

AndroidManifest.xml

Inclure launchMode = "singleTop"

<activity Android:name=".MessagesDetailsActivity"
        Android:launchMode="singleTop"
        Android:excludeFromRecents="true"
        />

SMSReceiver.Java

Définir les drapeaux pour Intent et PendingIntent

Intent intent = new Intent(context, MessagesDetailsActivity.class);
    intent.putExtra("smsMsg", smsObject.getMsg());
    intent.putExtra("smsAddress", smsObject.getAddress());
    intent.setFlags(Intent.FLAG_ACTIVITY_SINGLE_TOP | Intent.FLAG_ACTIVITY_CLEAR_TOP);

    PendingIntent contentIntent = PendingIntent.getActivity(context, notification_id, intent, PendingIntent.FLAG_UPDATE_CURRENT);

MessageDetailsActivity.Java

onResume () - est appelé à chaque fois, charge les extras.

Intent intent = getIntent();
    String extraAddress = intent.getStringExtra("smsAddress");
    String extraBody = intent.getStringExtra("smsMsg");

J'espère que ça aide, il était basé sur d'autres réponses ici sur stackoverflow, mais c'est la plus récente qui a fonctionné pour moi.

2
Miguel Jesus

C'est facile, c'est ma solution en utilisant des objets!

Mon POJO

public class Person implements Serializable{

    private String name;
    private int age;

    //get & set

}

Notification de méthode

  Person person = new Person();
  person.setName("david hackro");
  person.setAge(10);

    Intent notificationIntent = new Intent(this, Person.class);
    notificationIntent.putExtra("person",person);
    notificationIntent.setFlags(Intent.FLAG_ACTIVITY_SINGLE_TOP | Intent.FLAG_ACTIVITY_CLEAR_TOP);

NotificationCompat.Builder builder = new NotificationCompat.Builder(this)
                .setSmallIcon(R.mipmap.notification_icon)
                .setAutoCancel(true)
                .setColor(getResources().getColor(R.color.ColorTipografiaAdeudos))
                .setPriority(2)
                .setLargeIcon(bm)
                .setTicker(fotomulta.getTitle())
                .setContentText(fotomulta.getMessage())
                .setContentIntent(PendingIntent.getActivity(this, 0, notificationIntent, PendingIntent.FLAG_UPDATE_CURRENT))
                .setWhen(System.currentTimeMillis())
                .setContentTitle(fotomulta.getTicketText())
                .setDefaults(Notification.DEFAULT_ALL);

Nouvelle activité

 private Person person;

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_notification_Push);
    person = (Person) getIntent().getSerializableExtra("person");
}

Bonne chance!!

2
David Hackro

Après avoir fait quelques recherches, j'ai obtenu la solution du guide du développeur Android 

PendingIntent contentIntent ;
Intent intent = new Intent(this,TestActivity.class);
intent.putExtra("extra","Test");
TaskStackBuilder stackBuilder = TaskStackBuilder.create(this);

stackBuilder.addParentStack(ArticleDetailedActivity.class);

contentIntent = stackBuilder.getPendingIntent(0,PendingIntent.FLAG_UPDATE_CURRENT);

Pour obtenir une valeur supplémentaire d'intention dans la classe d'activité de test, vous devez écrire le code suivant:

 Intent intent = getIntent();
 String extra = intent.getStringExtra("extra") ;
1
mohit

pour l'utilisation des services PendingIntent.FLAG_UPDATE_CURRENT

pour moi travail.

0
Ali Bagheri

Si tu utilises 

Android:taskAffinity="myApp.widget.notify.activity"
Android:excludeFromRecents="true"

dans votre fichier AndroidManifest.xml pour que l'activité soit lancée, vous devez utiliser les éléments suivants dans votre intention:

Intent notificationClick = new Intent(context, NotifyActivity.class);
    Bundle bdl = new Bundle();
    bdl.putSerializable(NotifyActivity.Bundle_myItem, myItem);
    notificationClick.putExtras(bdl);
    notificationClick.setData(Uri.parse(notificationClick.toUri(Intent.URI_INTENT_SCHEME) + myItem.getId()));
    notificationClick.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TASK | Intent.FLAG_ACTIVITY_NEW_TASK);  // schließt tasks der app und startet einen seperaten neuen

    TaskStackBuilder stackBuilder = TaskStackBuilder.create(context);
    stackBuilder.addParentStack(NotifyActivity.class);
    stackBuilder.addNextIntent(notificationClick);

    PendingIntent notificationPendingIntent = stackBuilder.getPendingIntent(0, PendingIntent.FLAG_UPDATE_CURRENT);
    mBuilder.setContentIntent(notificationPendingIntent);

Il est important de définir des données uniques, par exemple. en utilisant un identifiant unique comme:

notificationClick.setData(Uri.parse(notificationClick.toUri(Intent.URI_INTENT_SCHEME) + myItem.getId()));
0
Scrounger

Dans votre implémentation de notification, utilisez un code comme celui-ci:

NotificationCompat.Builder nBuilder = new NotificationCompat.Builder(this, NOTIFICATION_CHANNEL_ID);
...
Intent intent = new Intent(this, ExampleActivity.class);
intent.putExtra("EXTRA_KEY", "value");

PendingIntent pendingIntent = PendingIntent.getActivity(this, 0, intent, PendingIntent.FLAG_UPDATE_CURRENT);
nBuilder.setContentIntent(pendingIntent);
...

Pour obtenir des valeurs supplémentaires d'intention dans ExampleActivity, utilisez le code suivant:

...
Intent intent = getIntent();
if(intent!=null) {
    String extraKey = intent.getStringExtra("EXTRA_KEY");
}
...

NOTE TRÈS IMPORTANTE: la méthode Intent :: putExtra () est surchargée. Pour obtenir la clé supplémentaire, vous devez utiliser la méthode Intent :: get [Type] Extra ().

Remarque: NOTIFICATION_ID et NOTIFICATION_CHANNEL_ID sont des constantes déclarées dans ExampleActivity

0
Carlos Espinoza

G'day, je peux aussi dire que j'ai tout essayé, et quelques autres d'ailleurs. Le problème n ° 1 pour moi était que le nouvel Intent avait toujours un bundle nul. Mon problème était de me focaliser trop sur les détails de "ai-je inclus .cet ou .that". Ma solution consistait à prendre du recul par rapport aux détails et à examiner la structure globale de la notification. Lorsque j’ai fait cela, j’ai réussi à placer les parties clés du code dans le bon ordre. Donc, si vous rencontrez des problèmes similaires, vérifiez:

1. Intent notificationIntent = new Intent(MainActivity.this, NotificationActivity.class);

2a. Bundle bundle = new Bundle();

// J'aime beaucoup mieux spécifier le type de données. par exemple, bundle.putInt

2b. notificationIntent.putExtras(bundle);
3. PendingIntent contentIntent = PendingIntent.getActivity(MainActivity.this, WIZARD_NOTIFICATION_ID, notificationIntent,
                    PendingIntent.FLAG_UPDATE_CURRENT);
notificationIntent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP | Intent.FLAG_ACTIVITY_SINGLE_TOP);
4. NotificationManagerCompat notificationManager = NotificationManagerCompat.from(this);
5.          NotificationCompat.Builder nBuilder =
                    new NotificationCompat.Builder(this)
                            .setSmallIcon(R.drawable.ic_notify)
                            .setContentTitle(title)
                            .setContentText(content)
                            .setContentIntent(contentIntent)
                            .setDefaults(Notification.DEFAULT_SOUND | Notification.DEFAULT_VIBRATE)
                            .setAutoCancel(false)//false is standard. true == automatically removes the notification when the user taps it.
                            .setColor(getResources().getColor(R.color.colorPrimary))
                            .setCategory(Notification.CATEGORY_REMINDER)
                            .setPriority(Notification.PRIORITY_HIGH)
                            .setVisibility(NotificationCompat.VISIBILITY_PUBLIC);
            notificationManager.notify(WIZARD_NOTIFICATION_ID, nBuilder.build());

Avec cette séquence je reçois un paquet valide.

0
Peter Suter

S'il vous plaît utiliser comme PendingIntent tout en montrant la notification qu'il sera résolu.

PendingIntent intent = PendingIntent.getActivity (this, 0, NotificationIntent, PendingIntent.FLAG_UPDATE_CURRENT);

Ajoutez PendingIntent.FLAG_UPDATE_CURRENT comme dernier champ.

0
M.Noman