Checking if an Android application is running in the background

前端 未结 30 2808
无人共我
无人共我 2020-11-21 06:19

By background, I mean none of the application\'s activities are currently visible to the user?

30条回答
  •  日久生厌
    2020-11-21 07:09

    There are few ways to detect whether your application is running in the background, but only one of them is completely reliable:

    1. The right solution (credits go to Dan, CommonsWare and NeTeInStEiN)
      Track visibility of your application by yourself using Activity.onPause, Activity.onResume methods. Store "visibility" status in some other class. Good choices are your own implementation of the Application or a Service (there are also a few variations of this solution if you'd like to check activity visibility from the service).
       
      Example
      Implement custom Application class (note the isActivityVisible() static method):

      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;
      }
      

      Register your application class in AndroidManifest.xml:

      
      

      Add onPause and onResume to every Activity in the project (you may create a common ancestor for your Activities if you'd like to, but if your activity is already extended from MapActivity/ListActivity etc. you still need to write the following by hand):

      @Override
      protected void onResume() {
        super.onResume();
        MyApplication.activityResumed();
      }
      
      @Override
      protected void onPause() {
        super.onPause();
        MyApplication.activityPaused();
      }
      

       
      Update
      ActivityLifecycleCallbacks were added in API level 14 (Android 4.0). You can use them to track whether an activity of your application is currently visible to the user. Check Cornstalks' answer below for the details.

    2. The wrong one
      I used to suggest the following solution:

      You can detect currently foreground/background application with ActivityManager.getRunningAppProcesses() which returns a list of RunningAppProcessInfo records. To determine if your application is on the foreground check RunningAppProcessInfo.importance field for equality to RunningAppProcessInfo.IMPORTANCE_FOREGROUND while RunningAppProcessInfo.processName is equal to your application package name.

      Also if you call ActivityManager.getRunningAppProcesses() from your application UI thread it will return importance IMPORTANCE_FOREGROUND for your task no matter whether it is actually in the foreground or not. Call it in the background thread (for example via AsyncTask) and it will return correct results.

      While this solution may work (and it indeed works most of the time) I strongly recommend to refrain from using it. And here's why. As Dianne Hackborn wrote:

      These APIs are not there for applications to base their UI flow on, but to do things like show the user the running apps, or a task manager, or such.

      Yes there is a list kept in memory for these things. However, it is off in another process, managed by threads running separately from yours, and not something you can count on (a) seeing in time to make the correct decision or (b) have a consistent picture by the time you return. Plus the decision about what the "next" activity to go to is always done at the point where the switch is to happen, and it is not until that exact point (where the activity state is briefly locked down to do the switch) that we actually know for sure what the next thing will be.

      And the implementation and global behavior here is not guaranteed to remain the same in the future.

      I wish I had read this before I posted an answer on the SO, but hopefully it's not too late to admit my error.

    3. Another wrong solution
      Droid-Fu library mentioned in one of the answers uses ActivityManager.getRunningTasks for its isApplicationBroughtToBackground method. See Dianne's comment above and don't use that method either.

提交回复
热议问题