android - programacion - Cómo determinar si una de mis actividades está en primer plano
manual de android en pdf (7)
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 intento, luego puede comer el intento para que nunca se notifique al receptor de difusión que registró en su manifiesto.
Esta pregunta ya tiene una respuesta aquí:
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 intento 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 intento enviado desde su servicio. Si no está en primer plano, no recibirá el intento, pero el servicio que invocó la transmisión sabrá que nadie ha interceptado su intento 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.
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.
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.
Usaría ActivityLifecycleCallbacks para obtener una solución mucho más limpia.
Puede ser inseguro, lea this 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
:
<application
android:name=".App" />
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
}
}
}
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".
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.