Come inviare parametri da una notifica-clic a un'attività?


206

Posso trovare un modo per inviare parametri alla mia attività dalla mia notifica.

Ho un servizio che crea una notifica. Quando l'utente fa clic sulla notifica, desidero aprire la mia attività principale con alcuni parametri speciali. Ad esempio un ID articolo, in modo che la mia attività possa caricare e presentare una vista di dettaglio dell'articolo speciale. Più specifico, sto scaricando un file e quando il file viene scaricato voglio che la notifica abbia l'intenzione che quando si fa clic si apre la mia attività in una modalità speciale. Ho provato a usare putExtrail mio intento, ma non riesco a estrarlo, quindi penso che sto sbagliando.

Codice dal mio servizio che crea la notifica:

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

Codice dalla mia attività che tenta di recuperare il parametro aggiuntivo dalla notifica:

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

Gli extra sono sempre nulli e non inserisco mai nulla nel mio registro.

Tra ... il onCreate viene eseguito solo quando inizia la mia attività, se la mia attività è già iniziata voglio anche raccogliere gli extra e presentare la mia attività in base all'elemento_id che ricevo.

Qualche idea?

Risposte:


241

Dai un'occhiata a questa guida ( creazione di una notifica ) e agli esempi ApiDemos "StatusBarNotifications" e "NotificationDisplay".

Per gestire se l'attività è già in esecuzione, hai due modi:

  1. Aggiungi il flag FLAG_ACTIVITY_SINGLE_TOP all'Intent all'avvio dell'attività, quindi nella classe di attività implementa il gestore di eventi NewIntent (Intent intent) , in questo modo puoi accedere al nuovo intento chiamato per l'attività (che non è lo stesso che chiamare getIntent (), questo restituirà sempre il primo Intento che ha avviato la tua attività.

  2. Come il numero uno, ma invece di aggiungere un flag all'intento devi aggiungere "singleTop" nella tua attività AndroidManifest.xml.

Se usi extra intenti, ricorda di chiamare PendingIntent.getActivity()con il flag PendingIntent.FLAG_UPDATE_CURRENT, altrimenti gli stessi extra verranno riutilizzati per ogni notifica.


95
e per rispondere alla domanda dell'utente sul fatto che gli extra sono nulli: devi chiamare PendingIntent.getActivity()con il flag PendingIntent.FLAG_UPDATE_CURRENT, altrimenti gli stessi extra verranno riutilizzati per ogni notifica.
Matthias,

2
mi hai salvato la giornata, ma perché trasferire dati semplici come questo è così complicato in Android
Argomento illegale

8
Se si devono avere notifiche diverse, assicurarsi di utilizzare ID di richiesta diversi quando si chiama PendingIntent.getActivity()oltre all'impostazione FLAG_ACTIVITY_SINGLE_TOPsu Intente FLAG_UPDATE_CURRENTsu PendingIntent. Vedi stackoverflow.com/questions/7370324/…
schnatterer

101

Ho avuto il problema simile la mia applicazione visualizza le notifiche dei messaggi. Quando ci sono più notifiche e facendo clic su ciascuna notifica, vengono visualizzati i dettagli della notifica in un'attività di visualizzazione messaggio. Ho risolto il problema con gli stessi parametri extra che si stanno ricevendo nell'intento del messaggio di visualizzazione.

Ecco il codice che ha risolto questo problema. Codice per la creazione dell'intento di notifica.

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

Codice per visualizzare l'attività dei messaggi.

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


}

29

Forse un po 'in ritardo, ma: invece di questo:

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

Usa questo:

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

20
Forse in ritardo per l'OP, ma non è mai tardi per gli altri su Internet :)
espinchi il

19

Incontra lo stesso problema qui. Lo risolvo utilizzando un codice di richiesta diverso, utilizzo lo stesso ID di notifica durante la creazione di PendingIntent. ma ancora non so perché questo dovrebbe essere fatto.

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

14

Dopo aver letto alcune liste di e-mail e altri forum, ho scoperto che il trucco sembra aggiungere alcuni dati unici all'intento.

come questo:

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

Non capisco perché questo debba essere fatto, ha qualcosa a che fare con l'intento non può essere identificato solo dai suoi extra ...


8
Anroid riutilizza gli intenti, l'azione di intenti e il codice di richiesta lo rendono unico, ma non i dati extra. Quindi è necessario impostare un ID richiesta univoco o utilizzare azioni di intenti diverse.
Bachi,

10

Ho provato di tutto ma niente ha funzionato.

alla fine è arrivata la seguente soluzione.

1- in manifest add per l'attività android: launchMode = "singleTop"

2- mentre si effettua l'intento in sospeso, attenersi alla seguente procedura, utilizzare bundle anziché utilizzare direttamente intent.putString () o 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); 

3
Per me funziona. È necessario utilizzare un valore requestCode e un flag PendingIntent.FLAG_UPDATE_CURRENT diversi.
phuongle

4

AndroidManifest.xml

Includi launchMode = "singleTop"

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

SMSReceiver.java

Impostare i flag per Intent e 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 () - viene chiamato ogni volta, carica gli extra.

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

Spero che sia d'aiuto, era basato su altre risposte qui su StackOverflow, ma questo è il più aggiornato che ha funzionato per me.


3

È facile, questa è la mia soluzione usando gli oggetti!

Il mio POJO

public class Person implements Serializable{

    private String name;
    private int age;

    //get & set

}

Notifica del metodo

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

Nuova attività

 private Person person;

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

In bocca al lupo!!


3

Dopo aver fatto qualche ricerca, ho ottenuto la soluzione dalla guida per gli sviluppatori 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);

Per ottenere un valore aggiuntivo Intent nella classe Attività test è necessario scrivere il codice seguente:

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

3
A cosa serve stackBuilder?
AlexioVay

1

Nell'implementazione della notifica, utilizzare un codice come questo:

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

Per ottenere valori aggiuntivi Intent in ExampleActivity, utilizzare il seguente codice:

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

NOTA MOLTO IMPORTANTE: il metodo Intent :: putExtra () è sovraccarico. Per ottenere la chiave aggiuntiva, è necessario utilizzare il metodo Intent :: get [Type] Extra () .

Nota: NOTIFICATION_ID e NOTIFICATION_CHANNEL_ID sono costanti dichiarate in ExampleActivity


1

Buongiorno, anche io posso dire di aver provato tutto quanto menzionato in questi post e qualche altro altrove. Il problema n. 1 per me era che il nuovo Intento aveva sempre un fascio nullo. Il mio problema era concentrarsi troppo sui dettagli di "ho incluso .this o .that". La mia soluzione consisteva nel fare un passo indietro rispetto ai dettagli e osservare la struttura generale della notifica. Quando l'ho fatto sono riuscito a posizionare le parti chiave del codice nella sequenza corretta. Quindi, se hai problemi simili, controlla:

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

2a. Bundle bundle = new Bundle();

// Mi piace specificare molto meglio il tipo di dati. ad esempio 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());

Con questa sequenza ottengo un pacchetto valido.


0

Se usi

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

nel tuo file AndroidManifest.xml per l'avvio dell'attività, devi utilizzare quanto segue nel tuo intento:

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

È importante impostare dati univoci, ad esempio utilizzando un ID univoco come:

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

0

per uso dei servizi PendingIntent.FLAG_UPDATE_CURRENT

per me lavoro.


0

Si prega di utilizzare come PendingIntent mentre si mostra la notifica di quanto verrà risolto.

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

Aggiungi PendingIntent.FLAG_UPDATE_CURRENT come ultimo campo.

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.