¿Para qué se usa "requestCode" en PendingIntent?

110

Antecedentes:

Estoy usando PendingIntent para alarmas a través de AlarmManager.

El problema:

Al principio pensé que para cancelar los anteriores, debía proporcionar el requestCode exacto que había usado antes para iniciar la alarma.

Pero luego descubrí que estaba equivocado, como dice la API de cancelación :

Elimina las alarmas con una intención coincidente. Se cancelará cualquier alarma, de cualquier tipo, cuyo Intent coincida con este (según lo definido por filterEquals (Intent)).

mirando " filterEquals ", la documentación dice:

Determine si dos intenciones son iguales a los efectos de la resolución de intenciones (filtrado). Es decir, si su acción, datos, tipo, clase y categorías son los mismos. Esto no compara ningún dato adicional incluido en las intenciones.

así que no entiendo para qué sirve el "requestCode" ...

La pregunta:

¿Para qué se utiliza "requestCode"?

¿Qué sucede si creo varias alarmas con el mismo "requestCode"? ¿Se anulan entre sí?

desarrollador de Android
fuente
si usa el mismo requestCode, obtendrá el mismo PendingIntent
pskink
3
Para PendingIntent.getBroadcast (), requestCode aparentemente es ignorado por Android. A partir de API 22, no hará que su intención pendiente sea única. Lo hace para getActivity () (y quizás getService () pero no lo he probado). stackoverflow.com/a/33203752/2301224
Baker
@Baker ¿No se considera esto un error? Si es un error, debe escribir sobre él aquí: code.google.com/p/android/issues/list
desarrollador de Android
1
Bueno, en realidad, la documentación especifica la usaga del requestiCode: If you truly need multiple distinct PendingIntent objects active at the same time (such as to use as two notifications that are both shown at the same time), then you will need to ensure there is something that is different about them to associate them with different PendingIntents. This may be any of the Intent attributes considered by Intent#filterEquals(Intent), or different request code integers supplied.
Eir
@Eir Correcto, entonces, ¿cuál es el punto de usar el requestCode? ¿Donde puede ser usado?
desarrollador de Android

Respuestas:

77
  1. requestCode se usa para recuperar la misma instancia de intención pendiente más adelante (para cancelar, etc.).
  2. Sí, supongo que las alarmas se anularán entre sí. Mantendría los códigos de solicitud únicos.
Minhaj Arfin
fuente
5
¿Es necesario configurar el requestCode para que sea único incluso en caso de que las intenciones de las alarmas sean muy diferentes (una para el servicio A y otra para el servicio B, por ejemplo)? Además, ¿cómo es que la documentación no dice nada al respecto? ¿Es posible eliminar todas las alarmas de un determinado tipo, sin importar cuál sea el código de solicitud?
desarrollador de Android
1
No, no es necesario para diferentes propósitos. Y no sé por qué la documentación no dice nada al respecto, pero aprendí esto cuando configuré alarmas repetidas y también cuando usé la misma intención.
Minhaj Arfin
2
Estaba hablando de PendingIntent. startActivityForResult usa una intención normal.
desarrollador de Android
2
¿Cuál es el propósito de "startActivityForResult con PendingIntent usando una actividad de proxy"? ¿Puede dar un ejemplo?
desarrollador de Android
3
Estoy de acuerdo; la documentación de PendingIntent y AlarmManager es una mierda total, empeorada por el hecho de que no es posible enumerar las alarmas mediante programación.
Alguien en algún lugar
33

Solo quiero agregar a la respuesta de @Minhaj Arfin

1- requestCode se usa para obtener la misma intención pendiente más adelante (para cancelar, etc.)

2- Sí, se anularán siempre que especifique el mismo Receptor para su Intención que especifique en su PendingIntent

ejemplo:

Intent startIntent1 = new Intent(context, AlarmReceiverFirst.class);
PendingIntent pendingIntent1 = PendingIntent.getBroadcast(context, 0, startIntent1, 0);

Intent startIntent2 = new Intent(context, AlarmReceiverSecond.class);
PendingIntent pendingIntent2 = PendingIntent.getBroadcast(context, 0, startIntent2, 0);

Del ejemplo anterior, no se anularán entre sí porque el receptor es diferente (AlarmReceiverFirst y AlarmReceiverSecond)

Intent startIntent2 = new Intent(context, AlarmReceiverSecond.class);
PendingIntent pendingIntent2 = PendingIntent.getBroadcast(context, 0, startIntent2, 0);

Intent startIntent3 = new Intent(context, AlarmReceiverSecond.class);
PendingIntent pendingIntent3 = PendingIntent.getBroadcast(context, 0, startIntent3, 0);

Del ejemplo anterior, que se anulan entre sí, ya que el receptor es la misma (AlarmReceiverSecond)

HendraWD
fuente
Intención startIntent4 = nueva Intención (contexto, AlarmReceiverSecond.class); PendingIntent pendienteIntent4 = PendingIntent.getService (contexto, 0, startIntent4, 0); estaría bien entonces? Quiero decir, ¿no se anulará esto porque está llamando a getService () en lugar de getBroadcast ()?
Jenix
Lamento hacer otra pregunta, pero porque stackoverflow no me permite escribir una pregunta sin una sola línea de código. ¿No tiene el último argumento de los métodos de PendingIntent como getBroadcast () algo que ver con la anulación? Solía ​​poner 0 allí como el código de ejemplo anterior, pero también vi que muchas personas estaban poniendo algún valor de opción específico en lugar de 0.
Jenix
1
@Jenix usa AlarmReceiverSecond.classen la intención y luego usa PendingIntent.getService(). No funcionará, ya que AlarmReceiverSecond.classes un BroadcastReceiver, no unService
HendraWD
1
Acerca de las banderas, son las propiedades que puede establecer, las que harán que el comportamiento de su PendingIntent de acuerdo con las banderas que proporcionó. 0 significa que todas las banderas están apagadas
HendraWD
Ah, fui estúpido jaja ¿Qué demonios estaba pensando? Estaba un poco confundido acerca de PendingIntent y tu respuesta fue realmente útil. Y solo quería dejarlo más claro, pero ahora me di cuenta de que mi pregunta no tenía ningún sentido al principio. ¡Gracias!
Jenix
2

en mi caso, quiero abrir la misma actividad con dos intenciones diferentes, por lo que si hay dos o más FCMS en la bandeja, cualquiera de ellos solo abrirá y el otro no, así que cambié los códigos de solicitud de intención pendiente y funcionó.

 PendingIntent pendingIntent =
                            PendingIntent.getActivity(this, **Some unique id for all GCMS** /* Request code */, intent,
                                    PendingIntent.FLAG_ONE_SHOT);
JSONParser
fuente
No hubo necesidad de verificar más el código para mi caso, ¿puede decir en qué caso se requerirá la instancia de intención pendiente? Con respecto a la pregunta, el cambio de código de solicitud me ayudó a ir a la pantalla correcta, no sé si esta es la forma correcta y para mí el error solo ocurría cuando había varios FCM en la bandeja
JSONParser
Entonces, ¿por qué establecer un código de solicitud diferente, si no lo necesita?
desarrollador de Android
ok, lo explicaré en detalle, tuve algo de ACTIVIDAD A, está destinado a mostrar preguntas, pasaré la identificación de las notificaciones a través de la intención y luego realizaré una solicitud de red para esa identificación y buscaré la pregunta en particular, entonces, ¿qué estaba sucediendo cuando allí? Hay más de 1 notificaciones en la bandeja de notificaciones y luego hago clic en cualquiera de ellas y obtengo la identificación de la pregunta que estaba en el primer GCM, después de cambiar el código de solicitud de intención pendiente a un valor único que funcionó. Espero haberlo dejado claro ahora, si se requiere más discusión, estoy allí, también quiero aprender más, gracias
JSONParser
Oh, quisiste decir que de otra manera no habría funcionado en absoluto, ¿verdad? Perdón por la confusión. Esta pregunta se hizo hace mucho tiempo y no la recuerdo bien en absoluto ...
desarrollador de Android
1

Una cosa importante requestCodeque afectará seriamente a su aplicación es el uso de widgets. Los widgets no funcionarán después de reiniciar el teléfono si requestCodeson iguales. eso significa que el pendingIndentque establezca en el remoteViewsde su widget debe ser un requestCode único, generalmente el widgetId que acompaña a un número.

Alireza Jamali
fuente
0

En realidad, la documentación establece claramente para qué se utiliza el código de solicitud:

Si realmente necesita varios objetos PendingIntent distintos activos al mismo tiempo (por ejemplo, para usarlos como dos notificaciones que se muestran al mismo tiempo), entonces deberá asegurarse de que haya algo diferente en ellos para asociarlos con diferentes PendingIntents. Puede ser cualquiera de los atributos Intent considerados por Intent # filterEquals (Intent), o diferentes números enteros de código de solicitud proporcionados a getActivity (Context, int, Intent, int), getActivities (Context, int, Intent [], int), getBroadcast ( Context, int, Intent, int) o getService (Context, int, Intent, int).

Como parece que todavía no está tan claro, permítanme intentar explicar:

Cuando desea utilizar un PendingIntentobjeto, no solo crea una instancia de uno. Más bien, se obtiene una del sistema utilizando los PendingIntentmétodos estáticos ( getActivity, getBroadcast, getServiceetc). El sistema mantiene un montón de instancias PendingIntent y le proporciona una. Cuál le da, depende de los parámetros de entrada que pase a estos métodos getter. Esos parámetros de entrada son:, Contextes decir, el receptor de destino de la intención, el Intentuso requestCodey flags. Cuando pasas el mismo Context, el mismo requestCodey el mismo intento (es decir, un intento que filterEqualscon otro intento), obtienes el mismo PendingIntentobjeto. El caso es que el sistema quiere tener la menor cantidad de PendingIntentobjetos posible, por lo que tiende a reutilizar los existentes tanto como sea posible.

Por ejemplo, tiene dos notificaciones de calendario, para dos fechas diferentes. Cuando haces clic en uno de ellos, quieres que tu aplicación se abra en la fecha correspondiente de esa notificación. En ese escenario, tiene el mismo Contextobjetivo y el Intentobjeto que está pasando difiere solo en EXTRA_DATA (que especifica la fecha en la que debe estar abierto). Si proporciona lo mismo requestCodeal obtener el PendingIntentobjeto, terminará con el mismo PendingIntentobjeto. Entonces, al crear la segunda notificación, reemplazará el Intentobjeto anterior con el nuevo EXTRA_DATA y terminará con dos notificaciones que apuntan a la misma fecha.

Si desea tener dos PendingIntentobjetos diferentes , como debería en este escenario, debe especificar uno diferente requestCodeal obtener el PendingIntentobjeto.

Eir
fuente
Pero como mencioné, para cancelar las alarmas, no puede usar solo requestCode. No significa nada por eso. Tendrás que poner datos extra para diferenciarlos. No lo recuerdo, pero creo que incluso puedes usar el mismo código de solicitud para múltiples alarmas.
desarrollador de Android
@androiddeveloper lo que acaba de decir es incorrecto. Intentalo.
Eir