Aplicación para Android, estado de actividad (en ejecución, no en ejecución, en primer plano / fondo)

Me he encontrado con un requisito, pero no soy capaz de obtener la forma correcta de implementación y por lo tanto necesitan su ayuda.

¿Lo que quiero hacer? – Quiero realizar una acción dependiendo de la notificación que recibo de la siguiente manera:

  1. Cuando la aplicación está abierta y en primer plano, es decir, visible para el usuario y recibo notificación, simplemente muestro una ventana emergente para iniciar mi Actividad B
  2. Cuando la aplicación está cerrada, es decir, ni en segundo plano ni en primer plano y recibo la notificación voy a iniciar mi aplicación primero y luego iniciar la actividad B
  3. Cuando la aplicación se está ejecutando, pero en el fondo, es decir, en los últimos, pero no visible para el usuario, entonces quiero iniciar mi actividad B sin reiniciar la aplicación. Además, en este caso cuando el usuario presiona de nuevo en la Actividad B, deberían ver la pantalla que dejaron antes de enviarla al fondo.

¿Que he hecho? He logrado los puntos # 1 y # 2. Quiero alcanzar el punto # 3. He intentado lo siguiente

public static boolean isApplicationBroughtToBackground(final Activity activity) { ActivityManager activityManager = (ActivityManager) activity.getSystemService(Context.ACTIVITY_SERVICE); List<ActivityManager.RunningTaskInfo> tasks = activityManager.getRunningTasks(1); // Check the top Activity against the list of Activities contained in the Application's package. if (!tasks.isEmpty()) { ComponentName topActivity = tasks.get(0).topActivity; try { PackageInfo pi = activity.getPackageManager().getPackageInfo(activity.getPackageName(), PackageManager.GET_ACTIVITIES); for (ActivityInfo activityInfo : pi.activities) { if(topActivity.getClassName().equals(activityInfo.name)) { return false; } } } catch( PackageManager.NameNotFoundException e) { return false; // Never happens. } } return true; } 

Sin embargo esto devuelve verdadero en ambos casos, punto # 2 y # 3, así que no soy capaz de distinguir sólo # 3.

También he intentado lo siguiente en cada actividad que tengo,

 @Override protected void onPause() { super.onPause(); saveIsPausedInPref(true); } @Override protected void onResume() { super.onResume(); saveIsPausedInPref(false); } 

Pero, también no da el resultado deseado coz si la aplicación se envía a fondo pulsando el botón Inicio mi preferencia tendrá isPaused = true y si el usuario elimina la aplicación de reciente, entonces se mantendrá la verdad y de nuevo no voy a Ser capaz de diferenciar los puntos # 2 y # 3 cuando llega la notificación.

Disculpas por toda la historia, pero espero poder explicar mi requisito.

Gracias por adelantado. 🙂

Editar:

  <activity android:name=".HomeActivity" android:screenOrientation="portrait" > </activity> <activity android:name=".ChatProfileActivity" android:screenOrientation="portrait" > </activity> 

Para diferenciar entre el caso # 2 y el caso # 3, puede hacer lo siguiente:

Inicie la ActivityB si no es el caso # 1. En ActivityB.onCreate() haga lo siguiente:

 super.onCreate(...); if (isTaskRoot()) { // ActivityB has been started when the app is not running, // start the app from the beginning Intent restartIntent = new Intent(this, MyRootActivity.class); startActivity(restartIntent); finish(); return; } ... rest of onCreate() code here... 

Por debajo del código funciona para mí

En AndroidManifest.xml

 <application android:icon="@drawable/ic_launcher" android:label="@string/app_name" android:name=".MyApplication" > 

MyApplication.java

 public class MyApplication extends Application { private ActivityLifecycleCallbacks myLifecycleHandler; @Override public void onCreate() { super.onCreate(); myLifecycleHandler=new MyLifecycleHandler(); registerActivityLifecycleCallbacks(myLifecycleHandler); } } 

MyLifecycleHandler.java

 public class MyLifecycleHandler implements Application.ActivityLifecycleCallbacks { private static final String TAG = MyLifecycleHandler.class.getSimpleName(); private static int resumed; private static int paused; private static int started; private static int stopped; @Override public void onActivityCreated(Activity activity, Bundle savedInstanceState) { } @Override public void onActivityDestroyed(Activity activity) { } @Override public void onActivityResumed(Activity activity) { ++resumed; } @Override public void onActivityPaused(Activity activity) { ++paused; Log.d(TAG, "application is in foreground: " + (resumed > paused)); } @Override public void onActivitySaveInstanceState(Activity activity, Bundle outState) { } @Override public void onActivityStarted(Activity activity) { ++started; } @Override public void onActivityStopped(Activity activity) { ++stopped; Log.d(TAG, "application is visible: " + (started > stopped)); } public static boolean isApplicationVisible() { return started > stopped; } public static boolean isApplicationInForeground() { return resumed > paused; } } 

Ahora, utilizando los métodos myLifecycleHandler , puede obtener todos los estados que necesita.

IsApplicationInForeground significa -> Al menos una actividad está en estado visible.

IsApplicationVisible significa -> Atleast una actividad es allí que se inició pero no se detuvo, significa que la aplicación está en ejecución estado

If isApplicationInForeground es true isApplicationVisible siempre será true, pero viceversa no es cierto

Sé que u figura 1 & 2, pero mal derecho mis propios toughts en caso u hizo algo más y u quiere echar un vistazo.

  1. ¿Cómo saber si su aplicación está en primer plano?

    Esto debe ser la forma correcta, si su en primer plano luego publicar un evento a través de eventbus , eventbus es mi manera preffered.

  2. ¿Inicia la aplicación en una actividad específica con la pila? Echar un vistazo a TaskStackBuilder con esta respuesta , que proporcionará información sobre cómo hacerlo correctamente.
  3. ¿Reanudar la aplicación con una cierta actividad mientras se mantiene la pila actual? Compruebe el estado de la aplicación con las devoluciones de llamada y, al recibir la notificación, abra la actividad sin FLAG_ACTIVITY_NEW_TASK. Esto debería hacer el tricl.

Si cambia a no mostrar ningún pop-up, sólo para ir a la actividad B siempre (destruido, fondo o primer plano), no necesita ninguna de esta comprobación. Sólo para trabajar con las banderas FLAG_ACTIVITY_X en su notificación (GCM esta notificación?).

LaunchMode en Manifest

Intent Flags

Puede utilizar el método onNewIntent para comprobar la intención si procede de una notificación e iniciar la Actividad B.

Notificación adecuada BackStack

  • Android: pasa el objeto de la actividad al servicio
  • Volver a actividad específica de la pila
  • Llame a un método de actividad de un BroadcastReceiver. ¿Es posible?
  • No obtener el valor actualizado de la preferencia compartida en el servicio
  • ¿Cómo obtener todas las vistas en una actividad?
  • Ciclo de vida de Android Fragment sobre cambios de orientación
  • Conexión de http de Android con OkHttp No funciona
  • Android - Fadeout animación para la pantalla de bienvenida
  • ¿Cómo uso estilos de interfaz de usuario comunes en Android?
  • Aplicación de Android: ¿Cómo leer obtener parámetros de un esquema de url personalizado?
  • Pila de actividad de Android
  • FlipAndroid es un fan de Google para Android, Todo sobre Android Phones, Android Wear, Android Dev y Aplicaciones para Android Aplicaciones.