¿Cómo enviar parámetros de una notificación-clic a una actividad?


Puedo encontrar una manera de enviar parámetros a mi actividad desde mi notificación.

Tengo un servicio que crea una notificación. Cuando el usuario hace clic en la notificación, quiero abrir mi actividad principal con algunos parámetros especiales. Por ejemplo, un id de elemento, para que mi actividad pueda cargar y presentar una vista de detalle de elemento especial. Más específicamente, estoy descargando un archivo, y cuando se descarga el archivo quiero que la notificación tenga una intent que cuando se hace clic, abre mi actividad en un modo especial. Me he tratado de usar putExtra en mi intención, pero parece que no puedo extraerlo, así que creo que lo estoy haciendo mal.

Código de mi servicio que crea la Notificación:

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

Código de mi actividad que intenta obtener el parámetro extra de la notificación:

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

Los extras siempre son null y nunca consigo nada en mi registro.

Por cierto... el onCreate solo se ejecuta cuando comienza mi actividad, si mi actividad ya está iniciada también quiero recoger los extras y presentar mi actividad según el item_id que recibo.

¿Alguna idea?

Author: Robert, 2009-07-29

12 answers

Echa un vistazo a esta guía ( creando una notificación) y a las muestras ApiDemos "StatusBarNotifications" y "NotificationDisplay".

Para gestionar si la actividad ya se está ejecutando tienes dos formas:

  1. Agregar FLAG_ACTIVITY_SINGLE_TOP flag a la Intent al iniciar la actividad, y luego en la clase activity implement onNewIntent (Intent intent) event handler, de esa manera puede acceder a la nueva intent que activity (que no es lo mismo que llamar a getIntent(), esto siempre devolverá la primera Intent que lanzó tu actividad.

  2. Igual que el número uno, pero en lugar de agregar una bandera a la Intent debes agregar "singleTop" en tu actividad AndroidManifest.XML.

Si utilizas intent extras, recuerda llamar a PendingIntent.getActivity() con la bandera PendingIntent.FLAG_UPDATE_CURRENT, de lo contrario los mismos extras serán reutilizados para cada notificación.

 221
Author: Lucas S.,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2013-10-01 09:33:47

Tuve el problema similar mi aplicación muestra notificaciones de mensajes. Cuando hay varias notificaciones y hace clic en cada notificación, se muestra el detalle de la notificación en una actividad de mensaje de vista. Resolví el problema de los mismos parámetros adicionales que se reciben en la intención del mensaje de vista.

Aquí está el código que arregló esto. Código para crear la Intent de notificación.

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

Código para la actividad del mensaje de vista.

@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
Author: Muhammad Yousaf Sulahria,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2016-09-22 08:43:26

Tal vez un poco tarde, pero: en lugar de esto:

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

Bundle extras = getIntent().getExtras();
if(extras !=null) {
    String value = extras.getString("keyName");
}
 24
Author: pinaise,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2010-12-08 23:36:06

Encuentro el mismo problema aquí. Lo resuelvo usando un código de solicitud diferente, uso el mismo id que la notificación, al crear PendingIntent. pero todavía no sé por qué se debe hacer esto.

PendingIntent contentIntent = PendingIntent.getActivity(context, **id**, notificationIntent, 0);
notif.contentIntent = contentIntent;
nm.notify(**id**, notif);
 18
Author: jamchen,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2011-01-26 13:57:23

Después de leer algunas listas de correo electrónico y otros foros, descubrí que el truco parece agregar datos únicos som a la intención.

Así:

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

No entiendo por qué hay que hacer esto, Tiene algo que ver con la intención que no se puede identificar solo por sus extras...

 13
Author: Vidar Vestnes,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2009-08-10 21:21:27

Lo intenté todo pero nada funcionó.

Finalmente se le ocurrió la siguiente solución.

1-en el manifiesto añadir para la actividad android: launchMode = "singleTop"

2 - al hacer la intent pendiente haga lo siguiente, use bundle en lugar de usar la intent directamente.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); 
 9
Author: Dheeraj Sachan,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2015-04-01 12:56:51

AndroidManifest.xml

Include launchMode = "singleTop"

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

SMSReceiver.java

Establecer las banderas para la Intent y 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() - se llama cada vez, carga los extras.

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

Espero que ayude, se basó en otras respuestas aquí en stackoverflow, pero esta es la más actualizada que funcionó para mí.

 2
Author: Miguel Jesus,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2016-04-26 14:06:33

Es fácil, esta es mi solución usando objetos!

Mi POJO

public class Person implements Serializable{

    private String name;
    private int age;

    //get & set

}

Notificación del método

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

Nueva Actividad

 private Person person;

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

Buena Suerte!!

 2
Author: David Hackro,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2016-05-02 15:34:23

Después de hacer una búsqueda, obtuve la solución de la guía para desarrolladores de 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);

Para obtener un valor adicional de Intent en la clase de actividad de prueba, debe escribir el siguiente código:

 Intent intent = getIntent();
 String extra = intent.getStringExtra("extra") ;
 1
Author: mohit,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2016-05-20 12:40:56

Si usa

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

En tu AndroidManifest.archivo xml para que se inicie la Actividad, debe usar lo siguiente en su intent:

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 es establecer datos únicos, por ejemplo, usando un id único como:

notificationClick.setData(Uri.parse(notificationClick.toUri(Intent.URI_INTENT_SCHEME) + myItem.getId()));
 0
Author: Scrounger,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2016-10-13 08:12:22

Para Servicios use PendingIntent.FLAG_UPDATE_CURRENT

Para mi trabajo.

 0
Author: Ali Bagheri,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2017-03-23 16:33:19

Utilice como PendingIntent mientras muestra la notificación que se resolverá.

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

Añade PendingIntent.FLAG_UPDATE_CURRENT como último campo.

 0
Author: M.Noman,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2017-11-07 11:11:22