La notificación pasa Extras de intención anteriores

134

Estoy creando una notificación dentro de un BroadcastReceiver a través de este código:

String ns = Context.NOTIFICATION_SERVICE;
        NotificationManager mNotificationManager = (NotificationManager) context.getSystemService(ns);
        int icon = R.drawable.ic_stat_notification;
        CharSequence tickerText = "New Notification";
        long when = System.currentTimeMillis();

        Notification notification = new Notification(icon, tickerText, when);
        notification.defaults |= Notification.DEFAULT_VIBRATE;
        long[] vibrate = {0,100,200,200,200,200};
        notification.vibrate = vibrate;
        notification.flags |= Notification.FLAG_AUTO_CANCEL;

        CharSequence contentTitle = "Title";
        CharSequence contentText = "Text";
        Intent notificationIntent = new Intent(context, NotificationActivity.class);
        notificationIntent.putExtra(Global.INTENT_EXTRA_FOO_ID, foo_id);
PendingIntent contentIntent = PendingIntent.getActivity(context, 0, notificationIntent, 0);

        notification.setLatestEventInfo(context, contentTitle, contentText, contentIntent);

        int mynotification_id = 1;

        mNotificationManager.notify(mynotification_id, notification);

Cuando hago clic en la notificación, se abre NotificationActivity y dentro de la Actividad puedo recuperar el foo_id del Intent-Bundle (por ejemplo, 1)

Sin embargo, si se activa otra notificación y hago clic en ella nuevamente, la actividad aún recibe el valor "antiguo" (1) del paquete de intención. Intenté borrar el paquete con clear (), pero recibo el mismo efecto. Creo que algo está mal con mi código ...

BrianM
fuente
por favor, ¿puede decirme cómo obtiene los datos de la intención pendiente
user49557
darse cuenta de que estaba enviando viejos extras, hizo que mi viaje fuera más fácil.
Utsav Gupta

Respuestas:

268

Está enviando el mismo código de solicitud para su intensidad pendiente. Cambia esto:

PendingIntent contentIntent = PendingIntent.getActivity(context, 0, notificationIntent, 0);

A:

PendingIntent contentIntent = PendingIntent.getActivity(context, UNIQUE_INT_PER_CALL, notificationIntent, 0);

no se crean intenciones si envía los mismos parámetros. Son reutilizados.

IncrediApp
fuente
1
Entonces, ¿UNIQUE_INT_PER_CALL es un número entero que debo proporcionar? o es esta una variable estática declarada en alguna parte?
BrianM
23
androide Problema nº 147 - por lo que una Intentque tiene diferentes extras (a través putExtra) se consideran la misma y reutilizada porque yo no presentar una identificación única para algunos llaman la intención pendientes - terribles api
Wal
sabes qué, fui tan descuidado. Solo pensando cómo podría permanecer 0 en un bloque (en mi caso) :(
Exigente05
3
Esto fue increíblemente útil para mí, solo un consejo para otros, es probable que esté construyendo su notificación con el mismo método, por lo que puede configurar la identificación para la nueva intención pendiente de la misma que va a utilizar para las notificaciones id único!
James McNee
1
@IncrediApp, ¿es lo mismo con PendingIntent.getBroadcast (); ?
Shruti
139

Alternativamente, puede usar el siguiente código para generar su PendingIntent:

PendingIntent contentIntent = PendingIntent.getActivity(context, 0, notificationIntent, PendingIntent.FLAG_UPDATE_CURRENT);

Del documento para PendingIntent.FLAG_UPDATE_CURRENT:

Si el PendingIntent descrito ya existe, guárdelo pero reemplace sus datos adicionales con lo que está en este nuevo Intento. Esto se puede usar si está creando intentos en los que solo cambian los extras, y no le importa que las entidades que recibieron su PendingIntent anterior puedan lanzarlo con sus nuevos extras, incluso si no se les dan explícitamente.

ChristophK
fuente
Gracias ... funciona perfectamente para esta bandera que se agrega "PendingIntent.FLAG_UPDATE_CURRENT" :)
Najib Ahmed Puthawala
1
Funcionó para mí, usando la intención pendiente de transferir el estado de configurar una alarma al receptor de transmisión.
William T. Mallard
Solo desearía saber qué hicieron realmente estas banderas antes de enviar notificaciones a mis usuarios (!) Me alegra que esto resuelva mis problemas ...
James Andrew
42

Estás pasando la misma identificación. En este tipo de situación, cree una identificación única en un momento como este:

int iUniqueId = (int) (System.currentTimeMillis() & 0xfffffff);

Y ponlo así:

PendingIntent contentIntent = PendingIntent.getActivity(getApplicationContext(),iUniqueId, intentForNotification, 0);
hderanga
fuente
3
¿por qué no usar new Random (). nextInt ()
exloong
@hderanga, ¿qué agrega "& 0xfffffff" al int anterior?
AJW
3
@AJW System.currentTimeMillis()devuelve un largo, mientras que el requestIdparámetro de PendingIntent.getActivity()toma un int. 0xffffffffEs una máscara de bits. Si bien hay un poco más, la explicación simple es que hacer 'long & 0xffffffff' da los 32 bits más bajos del largo y descarta los 32 bits más altos, dejándolo esencialmente con un int de 32 bits. Esto es mejor que simplemente enviar a un int porque no arruinará el bit de signo (si lanza un largo que es más grande que un int a un int, el bit de signo se desbordará y potencialmente terminará con un valor negativo )
Jordan Bondo
8

Para cualquiera que busque el mejor enfoque después de mucho tiempo, debe pasar el PendingIntent.FLAG_UPDATE_CURRENT como último argumento, como se muestra a continuación.

PendingIntent contentIntent = PendingIntent.getActivity(context, 0, notificationIntent, PendingIntent.FLAG_UPDATE_CURRENT);

ni siquiera necesita proporcionar una nueva identificación única.

Debe hacer esto para la próxima vez en adelante, no por primera vez

Amable
fuente
1
Eso no funciona, llegué aquí porque eso es lo que estaba haciendo.
Brill Pappin
Debe hacer esto para las próximas veces, no por primera vez, funcionará.
Suave
0

Su código de solicitud es 0 para todas las notificaciones. Cambiar la siguiente línea:

PendingIntent contentIntent = PendingIntent.getActivity(context, 0, notificationIntent, 0);

Con:

PendingIntent contentIntent = PendingIntent.getActivity(context, new Random().nextInt(), notificationIntent, 0);
Faisal Shaikh
fuente
1
¿Hay algún beneficio al usar "new Random (). NextInt ()" en lugar de "System.currentTimeMillis ()"?
AJW
el uso aleatorio puede regenerar fácilmente el mismo valor entero nuevamente en un accidente, causando así un error muy difícil de encontrar de pasados ​​intentos.
Sam
@AJW había en mi caso. Creé 2 notificaciones diferentes exactamente en el mismo milisegundo, por lo que una de ellas recibió extras adicionales incorrectos.
artman
0

Solo quería agregar otra opción

 PendingIntent.getBroadcast(context, 0, intent, PendingIntent.FLAG_ONE_SHOT | PendingIntent.FLAG_IMMUTABLE);
pelucida
fuente