How can I tell if Android app is running in the fo

2019-01-03 02:02发布

I am doing a status bar notification in my android app that is triggered by c2dm. I don't want to display the notification if the app is running. How do you determine if the app is running and is in the foreground?

18条回答
我命由我不由天
2楼-- · 2019-01-03 02:35

Make a global variable like private boolean mIsInForegroundMode; and assign a false value in onPause() and a true value in onResume().

Sample code:

private boolean mIsInForegroundMode;

@Override
protected void onPause() {
    super.onPause();
    mIsInForegroundMode = false;
}

@Override
protected void onResume() {
    super.onResume();
    mIsInForegroundMode = true;
}

// Some function.
public boolean isInForeground() {
    return mIsInForegroundMode;
}
查看更多
女痞
3楼-- · 2019-01-03 02:35

This is useful only when you want to perform some action just when your activity starts and its where you want to check if app is in foreground or background.

Instead of using Activity manager there is a simple trick which you can do through code. If you observe the activity cycle closely, the flow between two activities and foreground to background is as follows. Suppose A and B are two activities.

When transition from A to B: 1. onPause() of A is called 2. onResume() of B is called 3. onStop() of A is called when B is fully resumed

When app goes into background: 1. onPause() of A is called 2. onStop() of A is called

You can detect your background event by simply putting a flag in activity.

Make an abstract activity and extend it from your other activities, so that you wont have to copy paste the code for all other activities wherever you need background event.

In abstract activity create flag isAppInBackground.

In onCreate() method: isAppInBackground = false;

In onPause() method: isAppInBackground = false;

In onStop() method: isAppInBackground = true;

You just to need to check in your onResume() if isAppInBackground is true. n after you check your flag then again set isAppInBackground = false

For transition between two activities since onSTop() of first will always called after second actvity resumes, flag will never be true and when app is in background, onStop() of activity will be called immediately after onPause and hence the flag will be true when you open the app later on.

There is one more scenario though in this approach. If any of your app screen is already open and you put the mobile idle then after some time mobile will go into sleep mode and when you unlock mobile, it will be treated at background event.

查看更多
闹够了就滚
4楼-- · 2019-01-03 02:36

Slightly cleaned up version of Gadenkan's solution. Put it any Activity, or maybe a base class for all your Activities.

protected boolean isRunningInForeground() {
    ActivityManager manager = 
         (ActivityManager) getSystemService(Context.ACTIVITY_SERVICE);
    List<ActivityManager.RunningTaskInfo> tasks = manager.getRunningTasks(1);
    if (tasks.isEmpty()) {
        return false;
    }
    String topActivityName = tasks.get(0).topActivity.getPackageName();
    return topActivityName.equalsIgnoreCase(getPackageName());
}

To be able to call getRunningTasks(), you need to add this in your AndroidManifest.xml:

<uses-permission android:name="android.permission.GET_TASKS"/>

Do note what ActivityManager.getRunningTasks() Javadoc says though:

Note: this method is only intended for debugging and presenting task management user interfaces. This should never be used for core logic in an application, such as deciding between different behaviors based on the information found here. Such uses are not supported, and will likely break in the future.

Update (Feb 2015)

Note that getRunningTasks() was deprecated in API level 21!

As of LOLLIPOP, this method is no longer available to third party applications: the introduction of document-centric recents means it can leak person information to the caller. For backwards compatibility, it will still return a small subset of its data: at least the caller's own tasks, and possibly some other tasks such as home that are known to not be sensitive.

So what I wrote earlier is even more relevant:

In many cases you can probably come up with a better solution. For example, doing something in onPause() and onResume(), perhaps in a BaseActivity for all your Activities.

(In our case we didn't want an offline alert activity to be launched if we are not in the foreground, so in BaseActivity onPause() we simply unsubscribe from the RxJava Subscription listening for "went offline" signal.)

查看更多
贪生不怕死
5楼-- · 2019-01-03 02:37

I would like to add that a safer way to do this - than checking if your app is in the background before creating a notification - is to just disable and enable the Broadcast Receiver onPause() and onResume() respectively.

This method gives you more control in the actual application logic and is not likely to change in the future.

@Override
protected void onPause() {
    unregisterReceiver(mHandleMessageReceiver);
    super.onPause();
}

@Override
protected void onResume() {
    super.onResume();
    registerReceiver(mHandleMessageReceiver, new IntentFilter(DISPLAY_MESSAGE_ACTION));
}
查看更多
乱世女痞
6楼-- · 2019-01-03 02:37
     public static boolean isAppRunning(Context context) {

 // check with the first task(task in the foreground)
 // in the returned list of tasks

   ActivityManager activityManager = (ActivityManager)
   context.getSystemService(Context.ACTIVITY_SERVICE);
 List<RunningTaskInfo> services =
 activityManager.getRunningTasks(Integer.MAX_VALUE);
     if
     (services.get(0).topActivity.getPackageName().toString().equalsIgnoreCase(context.getPackageName().toString()))
     {
     return true;
     }
     return false;
     }
查看更多
啃猪蹄的小仙女
7楼-- · 2019-01-03 02:39

Based on the various answers and comments, here is a more inlined version that you can add to a helper class:

public static boolean isAppInForeground(Context context) {
  List<RunningTaskInfo> task =
      ((ActivityManager) context.getSystemService(Context.ACTIVITY_SERVICE))
          .getRunningTasks(1);
  if (task.isEmpty()) {
    return false;
  }
  return task
      .get(0)
      .topActivity
      .getPackageName()
      .equalsIgnoreCase(context.getPackageName());
}

As mentioned in other answers you need to add the following permission to your AndroidManifest.xml .

<uses-permission android:name="android.permission.GET_TASKS"/>
查看更多
登录 后发表回答