¿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?
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:
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.
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.
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);
}
}
}
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");
}
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);
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...
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);
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í.
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!!
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") ;
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()));
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.
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.
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