¿Cómo comprobar si la actividad está en primer plano o en un fondo visible?
Tengo una pantalla de presentación en un temporizador. Mi problema es que antes de realizar finish()
mi actividad necesito verificar que la siguiente actividad haya comenzado porque aparece un cuadro de diálogo del sistema y solo quiero finish()
; una vez que el usuario ha seleccionado una opción en el cuadro de diálogo?
Sé que hay muchas preguntas sobre cómo ver si tu actividad está en primer plano, pero no sé si esto también permite cuadros de diálogo encima de la actividad.
Aquí está el problema, el rojo es mi actividad que está en segundo plano mientras que el diálogo está en primer plano:
EDITAR: Intenté simplemente no usarlo finish()
, pero luego puedo volver a mi actividad en la pila de aplicaciones que estoy tratando de evitar.
Esto es lo que se recomienda como solución correcta :
La solución adecuada (los créditos son para Dan, CommonsWare y NeTeInStEiN) Realice un seguimiento de la visibilidad de su aplicación usted mismo utilizando los métodos Activity.onPause y Activity.onResume. Almacene el estado de "visibilidad" en alguna otra clase. Una buena opción es su propia implementación de la Aplicación o un Servicio (también existen algunas variaciones de esta solución si desea verificar la visibilidad de la actividad desde el servicio).
Ejemplo Implementar una clase de aplicación personalizada (tenga en cuenta el método estático isActivityVisible()):
public class MyApplication extends Application {
public static boolean isActivityVisible() {
return activityVisible;
}
public static void activityResumed() {
activityVisible = true;
}
public static void activityPaused() {
activityVisible = false;
}
private static boolean activityVisible;
}
Registre su clase de aplicación en AndroidManifest.xml:
<application
android:name="your.app.package.MyApplication"
android:icon="@drawable/icon"
android:label="@string/app_name" >
Agregue onPause y onResume a cada actividad en el proyecto (puede crear un ancestro común para sus actividades si lo desea, pero si su actividad ya está extendida desde MapActivity/ListActivity, etc., aún necesita escribir lo siguiente a mano) :
@Override
protected void onResume() {
super.onResume();
MyApplication.activityResumed();
}
@Override
protected void onPause() {
super.onPause();
MyApplication.activityPaused();
}
En su finish()
método, desea utilizarlo isActivityVisible()
para verificar si la actividad es visible o no. Allí también podrás comprobar si el usuario ha seleccionado una opción o no. Continúe cuando se cumplan ambas condiciones.
La fuente también menciona dos soluciones incorrectas... así que evita hacerlo.
Fuente: desbordamiento de pila
Si apunta al nivel API 14 o superior, se puede usar android.app.Application.ActivityLifecycleCallbacks
.
public class MyApplication extends Application implements ActivityLifecycleCallbacks {
private static boolean isInterestingActivityVisible;
@Override
public void onCreate() {
super.onCreate();
// Register to be notified of activity state changes
registerActivityLifecycleCallbacks(this);
// ...
}
public boolean isInterestingActivityVisible() {
return isInterestingActivityVisible;
}
@Override
public void onActivityResumed(Activity activity) {
if (activity instanceof MyInterestingActivity) {
isInterestingActivityVisible = true;
}
}
@Override
public void onActivityStopped(Activity activity) {
if (activity instanceof MyInterestingActivity) {
isInterestingActivityVisible = false;
}
}
// Other state change callback stubs
// ...
}
UPD : actualizado al estado Lifecycle.State.RESUMED
. Gracias a @htafoya por eso.
En 2019, con la ayuda de la nueva biblioteca de soporte 28+
o AndroidX, simplemente puedes usar:
val isActivityInForeground = activity.lifecycle.currentState.isAtLeast(Lifecycle.State.RESUMED)
Puede leer más en la documentación para comprender lo que sucedió bajo el capó.
Activity::hasWindowFocus() te devuelve el valor booleano que necesitas.
public class ActivityForegroundChecker extends TimerTask
{
private static final long FOREGROUND_CHECK_PERIOD = 5000;
private static final long FIRST_DELAY = 3000;
private Activity m_activity;
private Timer m_timer;
public ActivityForegroundChecker (Activity p_activity)
{
m_activity = p_activity;
}
@Override
public void run()
{
if (m_activity.hasWindowFocus() == true) {
// Activity is on foreground
return;
}
// Activity is on background.
}
public void start ()
{
if (m_timer != null) {
return;
}
m_timer = new Timer();
m_timer.schedule(this, FIRST_DELAY, FOREGROUND_CHECK_PERIOD);
}
public void stop ()
{
if (m_timer == null) {
return;
}
m_timer.cancel();
m_timer.purge();
m_timer = null;
}
}
Aquí tienes una clase de ejemplo para comprobar la visibilidad de tus actividades desde donde estés.
Recuerda que si muestras un diálogo , el resultado será falso ya que el diálogo tendrá el foco principal. Aparte de eso, es realmente útil y más confiable que las soluciones sugeridas.