Mi aplicación de Android está siendo llamada por una intención que está pasando información (pendiente en la barra de estado).
Cuando presiono el botón de inicio y vuelvo a abrir mi aplicación manteniendo presionado el botón de inicio, vuelve a llamar a la intención y los mismos extras siguen ahí.
@Override
public void onSaveInstanceState(Bundle savedInstanceState) {
super.onSaveInstanceState(savedInstanceState);
}
@Override
public void onRestoreInstanceState(Bundle savedInstanceState) {
super.onRestoreInstanceState(savedInstanceState);
}
este es el código que no se ejecuta como se supone que debe hacerlo
String imgUrl;
Bundle extras = this.getIntent().getExtras();
if(extras != null){
imgUrl = extras.getString("imgUrl");
if( !imgUrl.equals(textView01.getText().toString()) ){
imageView.setImageDrawable( getImageFromUrl( imgUrl ) );
layout1.setVisibility(0);
textView01.setText(imgUrl);//textview to hold the url
}
}
Y mi intención:
public void showNotification(String ticker, String title, String message,
String imgUrl){
String ns = Context.NOTIFICATION_SERVICE;
NotificationManager mNotificationManager =
(NotificationManager) getSystemService(ns);
int icon = R.drawable.icon; // icon from resources
long when = System.currentTimeMillis(); // notification time
CharSequence tickerText = ticker; // ticker-text
//make intent
Intent notificationIntent = new Intent(this, activity.class);
notificationIntent.putExtra("imgUrl", imgUrl);
notificationIntent.setFlags(
PendingIntent.FLAG_UPDATE_CURRENT |
PendingIntent.FLAG_ONE_SHOT);
PendingIntent contentIntent =
PendingIntent.getActivity(this, 0,
notificationIntent, PendingIntent.FLAG_UPDATE_CURRENT |
PendingIntent.FLAG_ONE_SHOT);
//make notification
Notification notification = new Notification(icon, tickerText, when);
notification.setLatestEventInfo(this, title, message, contentIntent);
//flags
notification.flags = Notification.FLAG_SHOW_LIGHTS |
Notification.FLAG_ONGOING_EVENT |
Notification.FLAG_ONLY_ALERT_ONCE |
Notification.FLAG_AUTO_CANCEL;
//sounds
notification.defaults |= Notification.DEFAULT_SOUND;
//notify
mNotificationManager.notify(1, notification);
}
¿Hay alguna forma de borrar la intención o comprobar si se ha utilizado antes?
android
android-intent
Marte
fuente
fuente
Respuestas:
ACTUALIZAR:
¡No me di cuenta de que se haría tanto referencia a esta respuesta cuando la escribí por primera vez hace más de 5 años!
Aclararé para señalar que según la respuesta de @ tato-rodrigo, esto no lo ayudará a detectar una intención ya manejada en algunas situaciones.
También debo señalar que puse "claro" entre comillas por una razón: realmente no está borrando la intención al hacer esto, solo está utilizando la eliminación del extra como una señal de que esta intención ya ha sido vista por la actividad .
Tuve exactamente el mismo problema.
La respuesta anterior me puso en el camino correcto y encontré una solución aún más simple, use:
llamada al método para "borrar" el Intent.
Es un poco tarde para responder ya que esto se preguntó hace un año, pero espero que esto ayude a otros en el futuro.
fuente
setIntent(new Intent())
y está funcionando bien ahora.EDITAR: Estoy editando para publicar la solución completa que estoy usando.
Esta solución funcionará si el problema es "No se ejecuta algún código cuando la actividad comienza desde el Historial (Aplicaciones recientes)" .
En primer lugar, declare un
boolean
en suActivity
para indicar siIntent
ya se consumió:Luego, almacene y restaure de manera segura este valor usando los métodos
onSaveInstanceState
yonCreate
para manejar los cambios de configuración y los casos en los que el sistema puede matarloActivity
cuando pasa a segundo plano.Ahora, verifique si puede ejecutar su código bajo el
onResume
método.Además, si
Activity
está configurado parasingleTop
, debe restablecer su bandera cuandoIntent
se entregue una nueva .fuente
(intent.getFlags() & Intent.FLAG_ACTIVITY_LAUNCHED_FROM_HISTORY)
así que ahora puedo averiguar cuándo comienza la actividad desde el historial y puedo ignorar mis extras.boolean shouldThisIntentTriggerMyCode = [...];
de la respuesta (¿para qué se usa?)consumedIntent
queString
contiene la notificación UID. Este Uid se puede agregar simplemente a la notificación en el backend como marca de tiempo actual. Además, debe guardar este UidonSaveInstanceState
solo si Intent ha venido de formaonCreate
. Esto significa que no debes guardar Uid deonNewIntent
.Hace que la respuesta funcione para borrar un extra:
Otro comando útil es:
También puede etiquetar una intención llamando a:
y luego simplemente verifique el valor.
fuente
Cuando lanzamos aplicaciones de Android desde Historial (Aplicaciones recientes), la aplicación podría iniciarse principalmente con tres indicadores de intención diferentes.
FLAG_ACTIVITY_LAUNCHED_FROM_HISTORY
Esto es cuando se inicia la actividad desde el historial de una aplicación que se minimizó (mantenga presionada la tecla de inicio).
Valor constante: 1048576 (0x00100000)
FLAG_ACTIVITY_NEW_TASK
Esto es cuando la actividad se inicia mediante "hacer clic en el icono de la aplicación" o mediante " Filtros de intención ". Aquí, la actividad se convertirá en el comienzo de una nueva tarea en esta pila de historial.
Valor constante: 268435456 (0x10000000)
FLAG_ACTIVITY_LAUNCHED_FROM_HISTORY | FLAG_ACTIVITY_NEW_TASK
Esto es cuando la aplicación se cerró presionando el botón Atrás y luego se reanudó desde el Historial (aplicaciones recientes).
Valor constante: 269484032 (0x10100000)
El valor constante se puede recuperar mediante
getIntent().getFlags()
En el tercer caso, Android recarga los últimos valores de Intent de su memoria. Por lo tanto, la intención de su aplicación (
getIntent
) tendrá valores de la última intención que lanzó la aplicación.En realidad, la aplicación debería comportarse como si fuera un lanzamiento nuevo, con valores de intención para un lanzamiento nuevo en lugar de los valores de intención del lanzamiento anterior. Este comportamiento se puede ver si inicia la aplicación haciendo clic en el ícono de la aplicación, nunca tendrá valores de intención antiguos. Esto se debe a que Android usa el siguiente filtro de intención para este escenario
Pero en el tercer caso (la aplicación que se cerró, se inicia desde el Historial de aplicaciones recientes), el sistema operativo Android usa esa última intención que inició la aplicación antes de salir (presionando el botón Atrás). Así que terminas teniendo valores de intención antiguos y el flujo de la aplicación no es el adecuado.
Eliminar la intención es una forma de resolverlo, ¡pero no resolvería el problema por completo! A medida que el sistema operativo Android recarga el Intent desde el último lanzamiento de las aplicaciones, y no la última instancia del intent de lanzamiento.
Una forma limpia de evitar que esto suceda es manejarlo obteniendo el tipo de Intent para determinar el tipo de lanzamiento.
Así que en su LaunchActivity (la que tiene la intención de filtro definido en el manifiesto), se puede utilizar el siguiente código en el
onCreate()
,onStart()
oonResume()
los métodos.Supongo
normalLaunch()
que no debería usar parámetros del Intent; de lo contrario, necesitaría segregar y optimizar su método de lanzamiento predeterminado para no usar los parámetros de Intent.fuente
getIntent().getFlags() & Intent.FLAG_ACTIVITY_LAUNCHED_FROM_HISTORY
, no importa si comienzo la actividad desde otra actividad (método startActivity) o la vuelvo a abrir desde la pila de Historial (aplicaciones recientes).Borrar un objeto de intención :
fuente
La respuesta corta es de ninguna manera
Respuesta larga. No existe la intención "única". A partir del experimento, se observa que la historia de actividad reciente en los androides modernos no es más que una "historia de intenciones". La última intención pasada a la actividad simplemente se registra en el sistema y ese es el trato. La gente de arriba sugiere usar
Pero no funciona porque la intención ya está registrada hasta el momento en que la ingresa en el método onNewIntent () o onStart ().
Resolví el problema evitando el uso de intenciones. Mi problema era similar al publicado por el autor. Intenté implementar Global Exit desde la aplicación a través del control en el área de notificación. Debe detener el servicio subyacente y cerrar todas las actividades de la aplicación. Puede encontrar el mismo comportamiento en la aplicación Waze.
El algoritmo:
Espero que esto ayude a alguien porque no encontré la respuesta en Internet.
fuente
Asegúrese de que está utilizando PendingIntent.FLAG_UPDATE_CURRENT bandera para PendingIntent .
Donde
mPutIntent
esta tuIntent
.Espero que esto te ayudará.
fuente
Recientemente tuve este problema y lo resolví agregando una marca de tiempo como parámetro adicional a la intención:
Después de eso, guarde la marca de tiempo en las preferencias compartidas:
fuente
Tengo exactamente el mismo problema. Mi solución fue agregar la
boolean
variable que se estableció cuandoIntent
se 'usó' y unaif
declaración basada en estoboolean
para verificar si debe usarIntent
o no.fuente
Cuando haya terminado de procesar la intención, haga esto:
No volverá a ver ese Intent procesado y no ocultará el problema editando el contenido del Intent procesado.
fuente
No pude encontrar una manera de eliminar Intent Extra . Ninguna de las respuestas sobre eliminar extra de la intención funciona si habilita "No conservar actividades " en las Opciones de desarrollador (de esa manera, puede destruir la actividad y volver para probar si los extras todavía están allí).
Como solución al problema, almacené un valor booleano en SharedPreferences después de que se procesan los Intent Extras. Cuando se vuelve a entregar el mismo Intent a la Actividad, verifico el valor SharedPreference y decido procesar el Intent Extra. En caso de que envíe otro Intent Extra nuevo a la misma actividad, hace que el valor SharedPreference sea falso y Activity lo procesará. Ejemplo :
fuente
Incluso después de borrar manualmente los extras Intent e Intent después de haber sido analizados, parece que Activity.getIntent () siempre devolverá el Intent original que inició la Activity.
Para evitar esto, recomiendo algo como esto:
De esta manera, hay un mecanismo para volcar el Intent original mientras se conserva la capacidad de retener explícitamente ciertas partes de los extras del Intent / Intent original.
Tenga en cuenta que no he probado todos los modos de inicio de actividad.
fuente
La forma más sencilla es evitar llamar a getIntent () desde métodos distintos a onCreate (). Pero esto causará problemas durante el próximo lanzamiento si el usuario abandona nuestra Actividad tocando el botón Inicio. Creo que este problema no tiene una solución completamente funcional.
fuente
Me enfrento al mismo problema e intento usar los métodos anteriores, pero no funciona.
Creo que puede ser la causa del modo de inicio de la actividad que usé el modo singleTop.
Cuando utilizo la aplicación en segundo plano y uso RamEater para simular un problema, esa intención siempre tiene más, incluso si la configuro como nula o elimino la clave.
El problema desapareció al usar el almacenamiento de preferencias en Android para verificar que se haya pasado.
fuente
No es una buena práctica agregar otro extra solo para saber si los extras se han consumido o no, ¿por qué no hacer esto ?:
fuente
¿Qué tal esto? Establece newIntent como intent.
fuente
¿Qué tal si desea borrar la intención, reemplazarla por una vacía?
p.ej.
fuente
Con suerte, esto ayudará a todos. Así que primero tenemos la intención
Coloque esto en algún lugar en Crear
Ahora configuremos esto para que cada vez que nuestra aplicación se destruya o salga, eliminemos los datos
Entiende la idea, si esto no es suficiente, busque más devoluciones de llamada 'on'
fuente
Si bien
Intent.removeExtra("key")
eliminará una clave específica de los extras, también existe el método Intent.replaceExtras (Bundle) , que se puede usar para eliminar todos los extras del Intent, sinull
se pasa como parámetro.De los documentos:
Debido a que los métodos putXXX () inicializan los extras con un Bundle nuevo si es nulo, esto no es un problema.
fuente
fuente