¿Es posible crear múltiples PendingIntents con el mismo requestCode y diferentes extras?

Estoy usando AlarmManager para progtwigr entre 1 y 35 alarmas (dependiendo de la entrada del usuario). Cuando el usuario solicita progtwigr nuevas alarmas, necesito cancelar las alarmas actuales, así que creo todas mis alarmas con el mismo código de solicitud, definido en una variable final .

 // clear remaining alarms Intent intentstop = new Intent(this, NDService.class); PendingIntent senderstop = PendingIntent.getService(this, NODIR_REQUESTCODE, intentstop, 0); am.cancel(senderstop); // loop through days if (sched_slider.getBooleanValue()) for (int day = 1; day < 8; day++) { if (day == 1 && sun.isChecked()) scheduleDay(day); if (day == 2 && mon.isChecked()) scheduleDay(day); if (day == 3 && tue.isChecked()) scheduleDay(day); if (day == 4 && wed.isChecked()) scheduleDay(day); if (day == 5 && thu.isChecked()) scheduleDay(day); if (day == 6 && fri.isChecked()) scheduleDay(day); if (day == 7 && sat.isChecked()) scheduleDay(day); } ... public void scheduleDay(int dayofweek) { Intent toolintent = new Intent(this, NDService.class); toolintent.putExtra("TOOL", "this value changes occasionally"); PendingIntent pi = PendingIntent.getService(this, NODIR_REQUESTCODE, toolintent, 0); calendar.set(Calendar.DAY_OF_WEEK, dayofweek); calendar.set(Calendar.HOUR_OF_DAY, hour); calendar.set(Calendar.MINUTE, minute); calendar.set(Calendar.SECOND, 0); am.setRepeating(AlarmManager.RTC, calendar.getTimeInMillis(), AlarmManager.INTERVAL_DAY * 7, pi); } 

Aquí, si el usuario tiene el sun (que es un CheckBox) marcado, progtwigrá una alarma para que se ejecute todos los domingos a la hour y los minute . Puede ver que cada alarma creada de esta manera tiene el mismo código de solicitud, pero la TOOL extra cambia algunas veces para cada alarma.

Sin embargo, en mis pruebas, cuando la alarma suena y mi Servicio se ejecuta, los extras del Intento ahora son null . Esta pregunta sugiere que usar PendingIntent.FLAG_CANCEL_CURRENT resolverá esto, pero ¿no cancelaría eso a los otros PendingIntents?

En breve:

¿Puede alguien explicar cómo funcionan los PendingIntents, en referencia a la creación de varios con el mismo requestCode y diferentes extras? ¿Qué banderas (si las hay) debería usar?

En realidad, no “crea” PendingIntent s. Usted los solicita desde el marco de Android. Cuando solicita un PendingIntent desde el marco de Android, comprueba si ya hay un PendingIntent que coincide con los criterios que pasa como argumentos. Si es así, no crea un nuevo PendingIntent , simplemente le devuelve un “token” que apunta al existente PendingIntent . Si no encuentra un PendingIntent coincidente, creará uno y luego le devolverá un “token” que apunta al que acaba de crear. Hay algunos indicadores que puede configurar para modificar este comportamiento, pero no demasiado. Lo más importante para entender aquí es la forma en que el marco de Android hace la comparación.

Para ello, comprueba si los siguientes parámetros coinciden (comparando el PendingIntent existente con los parámetros que ha pasado):

  • Los códigos de solicitud deben ser iguales. De lo contrario, no coinciden.
  • La “acción” en el Intent debe ser la misma (o ambas nulas). De lo contrario, no coinciden.
  • Los “datos” en la Intent deben ser los mismos (o ambos nulos). De lo contrario, no coinciden.
  • El “tipo” (de los datos) en el Intent debe ser el mismo (o ambos nulos). De lo contrario, no coinciden.
  • El “paquete” y / o “componente” en la Intent debe ser el mismo (o ambos nulos). De lo contrario, no coinciden. Los campos “paquete” y “componente” están configurados para Intent “explícitos”.
  • La lista de “categorías” en el Intent debe ser la misma. De lo contrario, no coinciden.

Deberías notar que los “extras” no están en la lista de arriba . Esto significa que si solicita un PendingIntent los “extras” no se tienen en cuenta cuando Android Framework intenta encontrar un PendingIntent coincidente. Este es un error común que hacen los desarrolladores.

Ahora podemos abordar los indicadores adicionales que puede agregar para modificar el comportamiento de una solicitud PendingIntent :

FLAG_CANCEL_CURRENT : cuando especifica este indicador, si se encuentra un PendingIntent coincidente, ese PendingIntent se cancela (elimina, elimina, invalida) y se crea uno nuevo. Esto significa que las aplicaciones que tienen un “token” apuntando al antiguo PendingIntent no podrán usarlo, porque ya no es válido.

FLAG_NO_CREATE – Cuando especifica este indicador, si se encuentra un PendingIntent coincidente, se PendingIntent un “token” que apunta al existente PendingIntent (este es el comportamiento habitual). Sin embargo, si no se encuentra PendingIntent coincidente, no se crea uno nuevo y la llamada simplemente devuelve null . Esto se puede usar para determinar si hay un PendingIntent activo para un conjunto específico de parámetros.

FLAG_ONE_SHOT : cuando especifica este indicador, el PendingIntent que se crea solo puede usarse una vez. Esto significa que si le da el “token” para este PendingIntent a múltiples aplicaciones, después del primer uso del PendingIntent se cancelará (eliminará, eliminará, invalidará) para que falle cualquier bash futuro de usarlo.

FLAG_UPDATE_CURRENT : cuando especifica este indicador, si se encuentra un PendingIntent coincidente, los “extras” en ese PendingIntent serán reemplazados por los “extras” en el Intent que pase como parámetro del método getxxx() . Si no se encuentra PendingIntent coincidente, se crea uno nuevo (este es el comportamiento normal). Esto se puede usar para cambiar los “extras” en un PendingIntent existente donde ya ha dado el “token” a otras aplicaciones y no desea invalidar el PendingIntent existente.

Déjame intentar abordar tu problema específico:

No puede tener más de un PendingIntent activo en el sistema si los parámetros de código de solicitud, acción, datos, tipo y paquete / componente son los mismos. Por lo tanto, no es posible su requisito para poder tener hasta 35 PendingIntent s activos con el mismo código de solicitud, acción, datos, tipo y parámetros de paquete / componente, pero con diferentes “extras”.

Le sugiero que use 35 códigos de solicitud diferentes o cree 35 parámetros de “acción” únicos diferentes para su Intent .

Sí, es posible simplemente poner acción de intención única para cada alarma

intent.setAction (“código único”);

 Intent intent = new Intent(context, MyAlarmReciver.class); intent.setAction("uniqueCode"); PendingIntent pendingIntent = PendingIntent.getBroadcast(activity, 0, intent, 0); AlarmManager alarmManager = (AlarmManager) context.getSystemService(activity.ALARM_SERVICE); Calendar c = Calendar.getInstance(); c.add(Calendar.MINUTE, 1); alarmManager.set(AlarmManager.RTC_WAKEUP, c.getTimeInMillis(), pendingIntent);