Cómo determinar si una de mis actividades está en primer plano

Implementé un BroadcastReceiver que es activado por AlarmManager. El AlarmManager se inicializa en BOOT_COMPLETED. Entonces tengo que declarar el receptor en el manifiesto.

Mi problema es que quiero que el BroadcastReceiver solo haga algo cuando ninguna de mis actividades está en primer plano (también conocido como el usuario no está interactuando con mi aplicación). Extraigo información de un servidor remoto y no quiero notificar al usuario si está actualmente en mi aplicación.

Hasta ahora no he logrado encontrar una manera de determinar si mi aplicación está en primer plano. ¿Hay alguna manera de hacer tal cosa? El ActivityManager me dice si mi aplicación se está ejecutando, pero no si está en primer plano.

El problema es más o menos el mismo que se describe aquí: Informar Actividad de un BroadcastReceiver SÓLO si está en primer plano

SOLUCIÓN:

Después de evaluar varias soluciones, quiero resumir rápidamente lo que creo que es el mejor método para tratar las actividades en segundo plano / en primer plano.

La forma preferida es registrar un receptor de difusión en el método onResume de su actividad y anular el registro en las actividades de onPause. Cualquier servicio u otro elemento de fondo tendrá que enviar un bash de difusión con una acción específica que su actividad interceptará.

Si su actividad está en primer plano, tendrá su receptor de intención registrado y podrá tratar directamente con el bash enviado desde su servicio. Si no está en primer plano, no recibirá el bash, pero el servicio que invocó la transmisión sabrá que nadie ha interceptado su bash de transmisión y podrá tratarlo por sí mismo. Por ejemplo, podría lanzar la actividad deseada, mostrar una notificación, etc.

La siguiente respuesta: “La aplicación se está ejecutando en segundo plano “, resume las soluciones disponibles para la verificación de fondo / primer plano.

Nota:
Anteriormente, esta respuesta sugería utilizar ActivityManager.getRunningAppProcesses() ; sin embargo, ese método parecía no ser completamente confiable y se desaconseja su uso. Verifique el enlace de arriba para los detalles.

Su actividad puede rastrear su propio estado en cuanto a si está en primer plano (establezca booleano a true en onStart() , a false en onStop() ). Por desgracia, la actividad no te proporciona ese booleano automáticamente.

ActivityManager#getRunningAppProcesses() devuelve una lista de RunningAppProcessInfo . Cada RunningAppProcessInfo tiene un campo llamado importancia. importancia igual a RunningAppProcessInfo.IMPORTANCE_FOREGROUND parece mostrar qué actividad está siendo observada activamente por el usuario. También hay RunningAppProcessInfo.IMPORTANCE_VISIBLE que es más bajo pero vale la pena consultarlo.

echa un vistazo a mi solución para determinar si una actividad está en primer plano: http://www.mannaz.at/codebase/android-activity-foreground-surveillance/

Debería ser fácil revertir la lógica de “en primer plano” a “no en primer plano”.

Implementé un BroadcastReceiver que es activado por AlarmManager. El AlarmManager se inicializa en BOOT_COMPLETED. Entonces tengo que declarar el receptor en el manifiesto.

Mi problema es que quiero que el BroadcastReceiver solo haga algo cuando ninguna de mis actividades está en primer plano (también conocido como el usuario no está interactuando con mi aplicación). Extraigo información de un servidor remoto y no quiero notificar al usuario si está actualmente en mi aplicación.

Hasta ahora no he logrado encontrar una manera de determinar si mi aplicación está en primer plano. ¿Hay alguna manera de hacer tal cosa? El ActivityManager me dice si mi aplicación se está ejecutando, pero no si está en primer plano.

No parece haber una manera directa de determinar si una de sus actividades es la actividad de primer plano en ejecución. Sin embargo, puede obtener el efecto deseado mediante el uso de una transmisión ordenada y dos receptores de difusión. Un receptor de difusión debe estar registrado en OnResume () y no registrado en OnPause (). El segundo receptor de difusión se declarará en su manifiesto como ya lo hizo. Establezca el android: prioridad para sus receptores de modo que si el receptor registrado dinámicamente está registrado, primero recibirá el bash, luego puede comer el bash para que nunca se notifique al receptor de difusión que registró en su manifiesto.

Puede probar si la ventana tiene foco , pero como se indica en los documentos de desarrollo, esto no es lo mismo que si la actividad estuviera en primer plano.

Usaría ActivityLifecycleCallbacks para obtener una solución mucho más limpia.

Puede ser inseguro, lea esto antes de que decida usar el siguiente ejemplo en producción. Funciona en ‘desarrollo del hogar’ para mi dispositivo y la versión del sistema operativo.

 public class App extends Application implements Application.ActivityLifecycleCallbacks { private boolean inForeground; @Override public void onCreate() { super.onCreate(); registerActivityLifecycleCallbacks(this); } @Override public void onActivityResumed(Activity activity) { inForeground = activity instanceof YourActivity; } public boolean isInForeground() { return inForeground; } 

App registro en AndroidManifest :

  

Y la última pieza del rompecabezas:

 public class YourReceiver extends BroadcastReceiver { @Override public void onReceive(Context context, Intent intent) { App app = (App) context.getApplicationContext(); if(app.isInForeground()){ // do some stuff } } }