Actividad abierta dos veces

Tengo una aplicación que utiliza el dirigible urbano para la notificación del empuje. Cuando llega una notificación y el usuario hace clic en ella, la actividad A de mi aplicación debe abrirse y hacer algo.

He instalado BroadcastReceiver como se muestra en los documentos , y está casi funcionando.

  1. Cuando mi aplicación está en primer plano, no dejo que el usuario vea la notificación en absoluto y solo la maneje automáticamente.
  2. Cuando mi aplicación no se ejecuta en absoluto, la actividad se abre muy bien.
  3. Cuando mi aplicación está en segundo plano (lo que siempre sucede cuando A es la actividad superior), se crea una segunda instancia de la actividad A.

Esto es, por supuesto, un problema. No quiero dos actividades A, solo quiero una de ellas. Aquí está el código BroadcastReceiver relevante:

 @Override public void onReceive(Context ctx, Intent intent) { Log.i(tag, "Push notification received: " + intent.toString()); String action = intent.getAction(); int notificationId = intent.getIntExtra(PushManager.EXTRA_NOTIFICATION_ID, -1); if(action.equals(PushManager.ACTION_NOTIFICATION_OPENED)) { Intent intentActivity = new Intent(ctx, ActivityA.class); intentActivity.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK); UAirship.shared().getApplicationContext().startActivity((intentActivity); } } 

ACTUALIZACIÓN: Traté de omitir este error llamando a System.exit(0) cuando el usuario presiona atrás en la actividad A. El proceso finalizó, pero luego se reinició de inmediato! Mi BroadcastReceiver no se llama de nuevo en la segunda instancia. ¿Que está pasando?

UPDATE 2: @codeMagic pidió más información sobre la aplicación y la actividad A.

Esta aplicación permite a su usuario revisar ciertos elementos y comentarlos. La actividad A se inicia cuando se inicia la aplicación. Si la sesión del usuario ya no es válida, se inicia una actividad de inicio de sesión. Una vez que el usuario inicia sesión, la actividad A vuelve a estar activa. A sólo tiene un mensaje "No hay elementos para revisar" y un botón "Inténtelo ahora".

Cuando el usuario inicia sesión, el servidor comienza a enviar notificaciones push siempre que un nuevo elemento esté disponible para su revisión. Cuando la aplicación obtiene la notificación, la actividad A accede al servidor y obtiene el siguiente elemento para revisar. El elemento se muestra en la actividad B. Una vez que la revisión se envía al servidor, la actividad B termina y la actividad A es de nuevo la actividad principal.

El servidor sabe cuándo un usuario está revisando un elemento (porque la actividad A lo ha obtenido) y no envía notificaciones push hasta que se envíe la revisión, lo que significa que una notificación no puede venir si el usuario no ha iniciado sesión o si el usuario está viendo la actividad B.

Mientras estoy de acuerdo hay una condición de carrera sutil aquí, no está causando el problema que estoy viendo – en las pruebas estoy 100% positivo no hay condición de carrera – la notificación push sólo se envía después de Actividad A se vuelve a activar de nuevo.

La solución fue añadir un launchMode='singleTask' a la actividad en AndroidManifest.xml . Como resultado, en lugar de una nueva actividad, onNewIntent de la misma instancia de actividad se llama.

Puede utilizar uno de varios Intent Flags . FLAG_ACTIVITY_REORDER_TO_FRONT siendo uno de ellos. Esto llevará la Activity al frente de la pila si ya está en la pila y si no, entonces creará una nueva instancia. Creo que seguirá necesitando FLAG_ACTIVITY_NEW_TASK si no lo está llamando desde una Activity

Intent.FLAG_ACTIVITY_CLEAR_TOP también debería funcionar. Pero esto borrará cualquier otra Activities en la pila. Sólo depende de qué otra funcionalidad que necesita. Mire a través de las Banderas de Intención y vea cuál de ellas funcionará mejor para usted

Hay múltiples escenarios cuando esto podría suceder. Uno de ellos se puede manejar de esta manera. Por favor, vea mi respuesta aquí: https://stackoverflow.com/a/44117025/2959575

Ok, dos notas sobre esto:

  • Puede registrar un receptor de difusión a través del manifiesto para que sea independiente de cualquier parte de su aplicación. y usar un patrón Singleton (mantener una referencia estática a su actividad en algún lugar de su aplicación) de esa manera puede comprobar si es una actividad de ver o no y el proceso en consecuencia.

     // your activity A @Override public void onCreate(Bundle bundle) { super.onCreate(bundle); myActivityReference = this; } public void onPause() { super.onPause(); if (isFinishing()) { myActivityReference = null; } } 
  • o puede mantener todo como es y utilizar la actividad almuerzo modos banderas en su manifiesto como singleTop, singleInstance ... etc echa un vistazo aquí android actividad almuerzo modos

  • SMS Broadcast Receiver no recibe el mensaje de texto
  • Servicios Roboeléctricos y de Intención
  • BroadcastReceiver cómo iniciar una nueva intención
  • Android OrderedBroadcast No funciona en la versión de lanzamiento
  • Widget de actualización de Android desde el receptor de difusión
  • ¿Cómo comprobar si Receiver está registrado en Android?
  • Notificación de muestra de Android de BroadcastReceiver
  • Cuando los incendios de Android ACTION_BATTERY_LOW
  • Android: detecta cuando la aplicación está instalada
  • ¿Cómo detectar el cambio de estado Bluetooth con un receptor de difusión?
  • Preferencias compartidas dentro de broadcastreceiver
  • FlipAndroid es un fan de Google para Android, Todo sobre Android Phones, Android Wear, Android Dev y Aplicaciones para Android Aplicaciones.