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:
- Android: Activity.onDestroy () no es llamado cuando Dalvik elimina esta actividad
- Android: Cómo dibujar gratis encima de cualquier cosa (cualquier actividad)
- Android: reenvía las consultas de búsqueda a una sola actividad que maneja la búsqueda
- Cómo iniciar una actividad desde la vista personalizada
- Pase objetos personalizados a la siguiente actividad en Xamarin Android
- 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
- 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
- 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>
- ¿cómo volver a la actividad principal en android?
- No se puede actualizar la vista de lista de android en onPostExecute
- ¿Mi proceso de almacenamiento en caché de imágenes va a perder memoria?
- Enviar enlace a Whatsapp a través de Android Intent
- ¿Cómo detener / cancelar el administrador de alarmas en otra actividad?
- Cambiar el estado del conmutador de Android
- Cómo devolver el mapa de bits de la actividad secundaria en android
- ¿Cómo hacer la actividad no a pantalla completa?
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.
-
¿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.
- ¿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.
- ¿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
- ¿Cómo probar las capacidades de notificación push de la aplicación móvil en un emulador?
- ¿Cómo convertir un pdf a una imagen?