Android: ¿cómo puedo verificar si la actividad se está ejecutando?

¿Hay alguna manera simple de determinar si una determinada actividad está activa o no? Quiero hacer ciertas cosas dependiendo de qué actividad esté activa. p.ej:

if(activityrunning == activity1) //do this else if (activityrunning == activity2) //do something else 

Puedes usar una variable static dentro de la actividad.

 class MyActivity extends Activity { static boolean active = false; @Override public void onStart() { super.onStart(); active = true; } @Override public void onStop() { super.onStop(); active = false; } } 

El único problema es que si lo usas en dos actividades que se vinculan entre sí, onStop en la primera se llama a veces después de onStart en la segunda. Entonces, ambos podrían ser ciertos brevemente.

Dependiendo de lo que intenta hacer (¿actualiza la actividad actual de un servicio?). Simplemente puede registrar un oyente estático en el servicio en su actividad en el método onStart , luego el oyente correcto estará disponible cuando su servicio quiera actualizar la IU.

Creo más claro así:

  public boolean isRunning(Context ctx) { ActivityManager activityManager = (ActivityManager) ctx.getSystemService(Context.ACTIVITY_SERVICE); List tasks = activityManager.getRunningTasks(Integer.MAX_VALUE); for (RunningTaskInfo task : tasks) { if (ctx.getPackageName().equalsIgnoreCase(task.baseActivity.getPackageName())) return true; } return false; } 

Mucho mejor que usar una variable estática y seguir OOP

Shared Preferences se pueden usar para compartir variables con otras activities y servicios desde una application

  public class example extends Activity { @Override protected void onStart() { super.onStart(); // Store our shared preference SharedPreferences sp = getSharedPreferences("OURINFO", MODE_PRIVATE); Editor ed = sp.edit(); ed.putBoolean("active", true); ed.commit(); } @Override protected void onStop() { super.onStop(); // Store our shared preference SharedPreferences sp = getSharedPreferences("OURINFO", MODE_PRIVATE); Editor ed = sp.edit(); ed.putBoolean("active", false); ed.commit(); } } 

Usa preferencias compartidas Tiene la información de estado más confiable, menos problemas de cambio / destrucción de la aplicación, nos ahorra pedir otro permiso más y nos da más control para decidir cuándo nuestra actividad es realmente la más alta. ver detalles aquí abd aquí también

Una opción sin usar ninguna variable auxiliar es:

 activity.getWindow().getDecorView().getRootView().isShown() 

donde la actividad es fe: this o getActivity ().

El valor devuelto por esta expresión cambia en onStart () / onStop (), que son los eventos que comienzan / detienen mostrando el diseño de la actividad en el teléfono.

Usé el método MyActivity.class y getCanonicalName y obtuve una respuesta.

 protected Boolean isActivityRunning(Class activityClass) { ActivityManager activityManager = (ActivityManager) getBaseContext().getSystemService(Context.ACTIVITY_SERVICE); List tasks = activityManager.getRunningTasks(Integer.MAX_VALUE); for (ActivityManager.RunningTaskInfo task : tasks) { if (activityClass.getCanonicalName().equalsIgnoreCase(task.baseActivity.getClassName())) return true; } return false; } 

Este es un código para verificar si un servicio en particular se está ejecutando. Estoy bastante seguro de que también puede funcionar para una actividad siempre que cambie getRunningServices con getRunningAppProcesses () o getRunningTasks (). Eche un vistazo aquí http://developer.android.com/reference/android/app/ActivityManager.html#getRunningAppProcesses ()

Cambiar constantes.PACKAGE y Constants.BACKGROUND_SERVICE_CLASS en consecuencia

  public static boolean isServiceRunning(Context context) { Log.i(TAG, "Checking if service is running"); ActivityManager activityManager = (ActivityManager)context.getSystemService(Context.ACTIVITY_SERVICE); List services = activityManager.getRunningServices(Integer.MAX_VALUE); boolean isServiceFound = false; for (int i = 0; i < services.size(); i++) { if (Constants.PACKAGE.equals(services.get(i).service.getPackageName())){ if (Constants.BACKGROUND_SERVICE_CLASS.equals(services.get(i).service.getClassName())){ isServiceFound = true; } } } Log.i(TAG, "Service was" + (isServiceFound ? "" : " not") + " running"); return isServiceFound; } 

gracias kkudi! Pude adaptar tu respuesta al trabajo para una actividad … esto es lo que funcionó en mi aplicación …

 public boolean isServiceRunning() { ActivityManager activityManager = (ActivityManager)Monitor.this.getSystemService (Context.ACTIVITY_SERVICE); List services = activityManager.getRunningTasks(Integer.MAX_VALUE); isServiceFound = false; for (int i = 0; i < services.size(); i++) { if (services.get(i).topActivity.toString().equalsIgnoreCase("ComponentInfo{com.lyo.AutoMessage/com.lyo.AutoMessage.TextLogList}")) { isServiceFound = true; } } return isServiceFound; } 

este ejemplo le dará un verdadero o falso si topActivity coincide con lo que el usuario está haciendo. Entonces, si la actividad que busca no se muestra (es decir, está en Pausa), no obtendrá una coincidencia. Además, para hacer esto, debe agregar el permiso a su manifiesto.

  

¡Espero que esto haya sido útil!

Creo que la respuesta aceptada es una manera horrible de manejar esto.

No sé cuál es el caso de uso, pero considere un método protegido en la clase base

 @protected void doSomething() { } 

y anularlo en la clase derivada.

Cuando ocurre el evento, simplemente llame a este método en la clase base. La clase “activa” correcta lo manejará en ese momento. La clase en sí misma puede verificar si no está Paused() .

Mejor aún, use un bus de eventos como GreenRobot’s , Square’s , pero ese está en desuso y sugiere usar RxJava.

Hay una manera mucho más sencilla que todo lo anterior y este enfoque no requiere el uso de android.permission.GET_TASKS en el manifiesto, ni tiene el problema de las condiciones de carrera o pérdidas de memoria señaladas en la respuesta aceptada.

  1. Haz una variable ESTÁTICA en la Actividad principal. Estático permite que otras actividades reciban datos de otra actividad. onPause() establece esta variable como false , onResume y onCreate() configuran esta variable como verdadera .

     private static boolean mainActivityIsOpen; 
  2. Asigna getters y setters de esta variable.

     public static boolean mainActivityIsOpen() { return mainActivityIsOpen; } public static void mainActivityIsOpen(boolean mainActivityIsOpen) { DayView.mainActivityIsOpen = mainActivityIsOpen; } 
  3. Y luego desde otra actividad o Servicio

     if (MainActivity.mainActivityIsOpen() == false) { //do something } else if(MainActivity.mainActivityIsOpen() == true) {//or just else. . . ( or else if, does't matter) //do something } 

¿qué pasa con activity.isFinishing()

No estoy seguro de que sea una forma “correcta” de “hacer cosas”.
Si no hay una forma de API para resolver la (o una) pregunta de lo que debería pensar un poco, tal vez esté haciendo algo mal y lea más documentos en su lugar, etc.
(Como entendí las variables estáticas es una forma comúnmente incorrecta en Android. Por qué podría funcionar, pero definitivamente habrá casos en los que no funcionará [por ejemplo, en producción, en millones de dispositivos]).
Exactamente en su caso, sugiero que piense por qué necesita saber si hay otra actividad viva … puede comenzar otra actividad para que el resultado obtenga su funcionalidad. O puede derivar la clase para obtener su funcionalidad, etc.
Atentamente.

Si está interesado en el estado del ciclo de vida de la instancia específica de la actividad, la solución de siliconeagle parece correcta, excepto que la nueva variable “activa” debe ser una variable de instancia, en lugar de estática.

Use una transmisión ordenada. Ver http://android-developers.blogspot.nl/2011/01/processing-ordered-broadcasts.html

En su actividad, registre un receptor en onStart, anule el registro en onStop. Ahora, cuando, por ejemplo, un servicio necesita manejar algo que la actividad pueda hacer mejor, envíe una transmisión ordenada desde el servicio (con un controlador predeterminado en el servicio mismo). Ahora puede responder en la actividad cuando se está ejecutando. El servicio puede verificar los datos del resultado para ver si se manejó la transmisión y, si no, tomar las medidas adecuadas.

if (!a.isFinishing()) un cheque if (!a.isFinishing()) y parece hacer lo que necesito. a es la instancia de actividad. ¿Es esto incorrecto? ¿Por qué nadie intentó esto?

ActivityLifecycleCallbacks es una excelente forma de realizar un seguimiento de todas las actividades en la aplicación:

 public class BaseActivityLifecycleCallbacks implements Application.ActivityLifecycleCallbacks { private ActivityState homeState, contentState; @Override public void onActivityCreated(Activity activity, Bundle bundle) { if (activity instanceof HomeActivityv2) { homeState = ActivityState.CREATED; } else if (activity instanceof ContentDisplayActivity) { contentState = ActivityState.CREATED; } } @Override public void onActivityStarted(Activity activity) { if (activity instanceof HomeActivityv2) { homeState = ActivityState.STARTED; } else if (activity instanceof ContentDisplayActivity) { contentState = ActivityState.STARTED; } } @Override public void onActivityResumed(Activity activity) { if (activity instanceof HomeActivityv2) { homeState = ActivityState.RESUMED; } else if (activity instanceof ContentDisplayActivity) { contentState = ActivityState.RESUMED; } } @Override public void onActivityPaused(Activity activity) { if (activity instanceof HomeActivityv2) { homeState = ActivityState.PAUSED; } else if (activity instanceof ContentDisplayActivity) { contentState = ActivityState.PAUSED; } } @Override public void onActivityStopped(Activity activity) { if (activity instanceof HomeActivityv2) { homeState = ActivityState.STOPPED; } else if (activity instanceof ContentDisplayActivity) { contentState = ActivityState.STOPPED; } } @Override public void onActivitySaveInstanceState(Activity activity, Bundle bundle) { } @Override public void onActivityDestroyed(Activity activity) { if (activity instanceof HomeActivityv2) { homeState = ActivityState.DESTR0YED; } else if (activity instanceof ContentDisplayActivity) { contentState = ActivityState.DESTR0YED; } } public ActivityState getHomeState() { return homeState; } public ActivityState getContentState() { return contentState; } } 

ActivityState:

 public enum ActivityState { CREATED,STARTED, RESUMED, PAUSED, STOPPED, DESTR0YED; } 

Extienda la clase de aplicación y proporcione su referencia en el archivo de manifiesto de Android:

 import android.app.Application; public final class BaseApplication extends Application { private BaseActivityLifecycleCallbacks baseALC; @Override public void onCreate() { super.onCreate(); baseALC = new BaseActivityLifecycleCallbacks(); this.registerActivityLifecycleCallbacks(baseALC); } public BaseActivityLifecycleCallbacks getBaseALC() { return baseALC; } } 

Ckeck en cualquier lugar de la actividad para el estado de otra actividad:

 private void checkAndLaunchHomeScreen() { Application application = getApplication(); if (application instanceof BaseApplication) { BaseApplication baseApplication = (BaseApplication) application; if (baseApplication.getBaseALC().getHomeState() == null || baseApplication.getBaseALC().getHomeState() == ActivityState.DESTR0YED){ //Do anything you want } } } 

https://developer.android.com/reference/android/app/Application.ActivityLifecycleCallbacks.html

Encontré una solución fácil con el siguiente código

 @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); if ((getIntent().getFlags() & Intent.FLAG_ACTIVITY_BROUGHT_TO_FRONT) != 0) { // Activity is being brought to front and not being created again, // Thus finishing this activity will bring the last viewed activity to foreground finish(); } } 

Además de la respuesta aceptada , si tiene varias instancias de la actividad, puede usar un contador en su lugar:

 class MyActivity extends Activity { static int activeInstances = 0; static boolean isActive() { return (activeInstance > 0) } @Override public void onStart() { super.onStart(); activeInstances++; } @Override public void onStop() { super.onStop(); activeInstances--; } } 

Este trabajo si no tienes la misma actividad en primer plano. Si abres desde la notificación no funciona hice algunos ajustes y vine con esto:

 public static boolean ativo = false; public static int counter = 0; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); ... counter++; } @Override protected void onStart() { super.onStart(); ativo = true; } @Override protected void onStop() { super.onStop(); if (counter==1) ativo = false; } @Override protected void onDestroy() { counter--; super.onDestroy(); } 

Eso funciona para mí con varias actividades abiertas al mismo tiempo.