检查Android应用程序是否在后台运行

通过背景,我的意思是应用程序的任何活动目前都不可见

有几种方法来检测您的应用程序是否在后台运行,但只有其中一个是完全可靠的:

  1. 正确的解决scheme (学分丹 , CommonsWare和NeTeInStEiN )
    使用Activity.onPauseActivity.onResume方法跟踪您的应用程序的可见性。 将“可见度”状态存储在其他一些类中。 好的select是你自己实现的ApplicationService (如果你想检查服务的活动可见性,这个解决scheme也有一些变化 )。


    实现自定义Application类(注意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; } 

    AndroidManifest.xml注册您的应用程序类:

     <application android:name="your.app.package.MyApplication" android:icon="@drawable/icon" android:label="@string/app_name" > 

    onPauseonResume添加到项目中的每个Activity (如果您愿意,可以为您的活动创build一个共同的祖先,但是如果您的活动已经从MapActivity / ListActivity等扩展了,则仍然需要手动编写以下内容) :

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

    更新
    ActivityLifecycleCallbacks被添加到API级别14(Android 4.0)中。 您可以使用它们来跟踪您的应用程序的活动当前对用户是否可见。 检查Cornstalks的答案在下面的细节。

  2. 错误的一个
    我曾经提出以下解决scheme:

    你可以使用ActivityManager.getRunningAppProcesses()来检测当前的前台/后台应用程序,它返回一个RunningAppProcessInfologging列表。 要确定您的应用程序是否在前台检查RunningAppProcessInfo.importance字段是否与RunningAppProcessInfo.IMPORTANCE_FOREGROUND相等,而RunningAppProcessInfo.processName是否等于您的应用程序包名称。

    另外,如果从应用程序UI线程中调用ActivityManager.getRunningAppProcesses() ,则无论它是否处于前台,它都将为您的任务返回IMPORTANCE_FOREGROUND的重要性。 在后台线程中调用它(例如通过AsyncTask ),它将返回正确的结果。

    虽然这个解决scheme可能会工作(而且大部分时间确实有效),我强烈build议不要使用它。 这是为什么。 正如Dianne Hackborn所写 :

    这些API不是让应用程序基于其UIstream,而是为用户显示正在运行的应用程序或任务pipe理器等。

    是的,这些东西有一个记忆清单。 然而,它是在另一个过程中,由与您分开运行的线程pipe理的,而不是您可以指望的(a)及时看到做出正确的决定或(b)在您返回时有一个一致的图片。 再加上关于“下一个”要进行的活动的决定总是在交换机要发生的地方完成,而且直到那个确切点(活动状态被暂时locking以进行交换)实际上知道接下来会发生什么。

    而且这里的实施和全球行为不能保证在未来保持不变。

    我希望在我发表一个关于SO的答案之前,我已经阅读过了,但是希望现在认识我的错误还为时不晚。

  3. 错误的解决scheme
    其中一个答案中提到的Droid-Fu库使用ActivityManager.getRunningTasks作为其isApplicationBroughtToBackground方法。 请参阅上面的Dianne的评论,也不要使用这种方法。

关键是使用ActivityLifecycleCallbacks (注意,这需要Android API级别14(Android 4.0))。 只要检查停止活动的数量是否等于已开始活动的数量。 如果他们是平等的,你的应用程序正在后台。 如果有更多已启动的活动,您的应用程序仍然可见。 如果恢复的时间比暂停的活动多,则您的应用程序不仅可见,而且还处于前台。 有三个主要的状态,你的活动可以在,然后:可见,在前景,可见,但不在前景,不可见,不在前景(即在后台)。

关于这个方法的真正getRunningTasks()在于它没有getRunningTasks()所做的asynchronous问题,但是您也不必修改应用程序中的每个Activity以在onResumed() / onPaused()设置/取消设置。 这只是自我包含的几行代码,它贯穿整个应用程序。 另外,也没有任何时髦的权限要求。

MyLifecycleHandler.java:

 public class MyLifecycleHandler implements ActivityLifecycleCallbacks { // I use four separate variables here. You can, of course, just use two and // increment/decrement them instead of using four and incrementing them all. private int resumed; private int paused; private int started; private int stopped; @Override public void onActivityCreated(Activity activity, Bundle savedInstanceState) { } @Override public void onActivityDestroyed(Activity activity) { } @Override public void onActivityResumed(Activity activity) { ++resumed; } @Override public void onActivityPaused(Activity activity) { ++paused; android.util.Log.w("test", "application is in foreground: " + (resumed > paused)); } @Override public void onActivitySaveInstanceState(Activity activity, Bundle outState) { } @Override public void onActivityStarted(Activity activity) { ++started; } @Override public void onActivityStopped(Activity activity) { ++stopped; android.util.Log.w("test", "application is visible: " + (started > stopped)); } // If you want a static function you can use to check if your application is // foreground/background, you can use the following: /* // Replace the four variables above with these four private static int resumed; private static int paused; private static int started; private static int stopped; // And these two public static functions public static boolean isApplicationVisible() { return started > stopped; } public static boolean isApplicationInForeground() { return resumed > paused; } */ } 

MyApplication.java:

 // Don't forget to add it to your manifest by doing // <application android:name="your.package.MyApplication" ... public class MyApplication extends Application { @Override public void onCreate() { // Simply add the handler, and that's it! No need to add any code // to every activity. Everything is contained in MyLifecycleHandler // with just a few lines of code. Now *that's* nice. registerActivityLifecycleCallbacks(new MyLifecycleHandler()); } } 

@Mewzer已经提出了一些关于这个方法的很好的问题,我想在每个人的回答中回答这个问题:

onStop()在低内存情况下不被调用; 这是一个问题吗?

没有onStop()的文档说:

请注意,在内存不足的情况下,可能永远不会调用此方法,因为系统没有足够的内存来保存活动的进程在调用onPause()方法后运行。

这里的关键是“保持你的活动的进程运行 …”如果这种低内存的情况下,你的过程实际上是被杀害(不只是你的活动)。 这意味着这种检查背景性的方法仍然有效,因为a)如果你的进程被终止,你不能检查背景,b)如果你的进程再次启动(因为新的活动被创build),成员MyLifecycleHandlervariables(无论是否为静态)将被重置为0

这是否适用于configuration更改?

默认情况下,不。 你必须在你的清单文件中明确地设置configChanges=orientation|screensize|和其他任何你想要的)并处理configuration的改变,否则你的活动将被破坏和重新创build。 如果你没有设置,你的活动的方法将按照以下顺序调用: onCreate -> onStart -> onResume -> (now rotate) -> onPause -> onStop -> onDestroy -> onCreate -> onStart -> onResume 。 如您所见,没有重叠(通常,两个活动在两者之间切换时非常简短地重叠,这是这种背景检测方法的工作原理)。 为了解决这个问题,你必须设置configChanges以便你的活动不被破坏。 幸运的是,我不得不在我的所有项目中都设置了configChanges ,因为我的整个活动在屏幕上被旋转/resize是不可取的,所以我从来没有发现这是有问题的。 (感谢dpimka为此刷新我的记忆并纠正我!)

一个注意:

当我在这里回答“背景”时,我的意思是“你的应用程序不再可见”。 Android活动可以看到,但不在前台(例如,如果有透明的通知覆盖)。 这就是为什么我更新了这个答案来反映这一点。

重要的是要知道,在切换没有任何事情在前台的活动时,Android会有一个怪异的时刻。 因此,如果在切换活动时(在同一应用程序中)检查应用程序是否在前台,则会被告知不在前台(即使您的应用程序仍然是活动的应用程序并且是可见的)。

super.onPause() 之后,你可以检查你的应用是否在ActivityonPause()方法的super.onPause() 。 只要记住我刚才谈到的那种怪异的状态。

你可以在你的ActivityonStop()方法super.onStop() 之后检查你的app是否可见(即,如果它不在后台super.onStop()

Idolon的答案是容易出错和复杂得多,虽然在这里重复检查Android应用程序是否在前台? 并在这里从后台任务或服务确定当前的前台应用程序

有一个更简单的方法:

所有活动扩展基本活动上:

 protected static boolean isVisible = false; @Override public void onResume() { super.onResume(); setVisible(true); } @Override public void onPause() { super.onPause(); setVisible(false); } 

每当你需要检查你的应用程序活动是否在前台时,只需检查 isVisible() ;

为了理解这种方法,请检查并排活动生命周期的这个答案: 活动并行生命周期

我尝试了使用Application.ActivityLifecycleCallbacks和许多其他的推荐的解决scheme,但他们没有按预期工作。 感谢Sarge ,我提出了一个简单而直接的解决scheme,我将在下面进行介绍。

他们的解决scheme的关键是理解如果我们有ActivityA和ActivityB,并且从ActivityA调用ActivityB(而不是调用ActivityA.finish ),那么ActivityB的onStart() ActivityA onStop() 之前被调用。

这也是onStop()onPause()之间的主要区别,在我阅读的文章中没有提到。

所以根据这个Activity的生命周期行为,你可以简单的计算onStart()onPause()在你的程序中调用了多less次。 请注意, 对于程序的每个 Activity ,都必须重写onStart()onStop() ,以增加/减less用于计数的静态variables。 下面是实现这个逻辑的代码。 请注意,我正在使用扩展Application的类,因此不要忘记在Application标签: android:name=".Utilities" Manifest.xml声明,尽pipe它也可以使用简单的自定义类来实现。

 public class Utilities extends Application { private static int stateCounter; public void onCreate() { super.onCreate(); stateCounter = 0; } /** * @return true if application is on background * */ public static boolean isApplicationOnBackground() { return stateCounter == 0; } //to be called on each Activity onStart() public static void activityStarted() { stateCounter++; } //to be called on each Activity onStop() public static void activityStopped() { stateCounter--; } } 

现在在我们的程序的每个Activity上,我们应该覆盖onStart()onStop()并递增/递减,如下所示:

 @Override public void onStart() { super.onStart(); Utilities.activityStarted(); } @Override public void onStop() { Utilities.activityStopped(); if(Utilities.isApplicationOnBackground()) { //you should want to check here if your application is on background } super.onStop(); } 

有了这个逻辑,有两种可能的情况:

  1. stateCounter = 0 :已停止的数量与已启动的活动数量相等,这意味着应用程序正在后台运行。
  2. stateCounter > 0 :启动次数大于停止次数,表示应用程序在前台运行。

注意: stateCounter < 0意味着有更多的停止活动而不是开始,这是不可能的。 如果遇到这种情况,那就意味着你不应该像你应该的那样增加/减less柜台。

你准备好了。 你应该想检查你的应用程序是否在onStop()背景。

没有办法,只要你自己跟踪,确定你的任何活动是否可见。 也许你应该考虑问一个新的StackOverflow问题,解释你试图从用户体验中获得什么,所以我们也许可以给你另外的实现想法。

由于Android API 16有一个简单的方法来检查应用程序是否在前台。 它可能不是万无一失的,但Android上没有任何方法是万无一失的。 当你的服务从服务器接收到更新并且必须决定是否显示通知时(这是因为如果UI是前景的,用户将在没有通知的情况下注意到更新),这个方法足够好用。

 RunningAppProcessInfo myProcess = new RunningAppProcessInfo(); ActivityManager.getMyMemoryState(myProcess); isInBackground = myProcess.importance != RunningAppProcessInfo.IMPORTANCE_FOREGROUND; 

您可以使用ComponentCallbacks2来检测应用程序是否在后台。 顺便说一句,这个callback只适用于API 14级(冰淇淋三明治)及以上。

你会得到一个方法的调用:

public abstract void onTrimMemory (int level)

如果级别是ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN那么应用程序在后台。

您可以将此接口实现为activityservice

 public class MainActivity extends AppCompatActivity implements ComponentCallbacks2 { @Override public void onConfigurationChanged(final Configuration newConfig) { } @Override public void onLowMemory() { } @Override public void onTrimMemory(final int level) { if (level == ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN) { // app is in background } } } 

build立在@Cornstalks答案包括一些有用的function。

额外function:

  • 引入单例模式,所以你可以在应用程序的任何地方做到这一点:AppLifecycleHandler.isApplicationVisible()和AppLifecycleHandler.isApplicationInForeground()
  • 增加对重复事件的处理(参见注释//对可见性的改变采取一些行动,//对前景的改变采取一些行动)

App.java

 public class App extends Application { @Override public void onCreate() { super.onCreate(); registerActivityLifecycleCallbacks(AppLifecycleHandler.getInstance()); } } 

AppLifecycleHandler.java

 public class AppLifecycleHandler implements Application.ActivityLifecycleCallbacks { private int resumed; private int started; private final String DebugName = "AppLifecycleHandler"; private boolean isVisible = false; private boolean isInForeground = false; private static AppLifecycleHandler instance; public static AppLifecycleHandler getInstance() { if (instance == null) { instance = new AppLifecycleHandler(); } return instance; } private AppLifecycleHandler() { } @Override public void onActivityCreated(Activity activity, Bundle savedInstanceState) { } @Override public void onActivityDestroyed(Activity activity) { } @Override public void onActivityResumed(Activity activity) { ++resumed; android.util.Log.w(DebugName, "onActivityResumed -> application is in foreground: " + (resumed > 0) + " (" + activity.getClass() + ")"); setForeground((resumed > 0)); } @Override public void onActivityPaused(Activity activity) { --resumed; android.util.Log.w(DebugName, "onActivityPaused -> application is in foreground: " + (resumed > 0) + " (" + activity.getClass() + ")"); setForeground((resumed > 0)); } @Override public void onActivitySaveInstanceState(Activity activity, Bundle outState) { } @Override public void onActivityStarted(Activity activity) { ++started; android.util.Log.w(DebugName, "onActivityStarted -> application is visible: " + (started > 0) + " (" + activity.getClass() + ")"); setVisible((started > 0)); } @Override public void onActivityStopped(Activity activity) { --started; android.util.Log.w(DebugName, "onActivityStopped -> application is visible: " + (started > 0) + " (" + activity.getClass() + ")"); setVisible((started > 0)); } private void setVisible(boolean visible) { if (isVisible == visible) { // no change return; } // visibility changed isVisible = visible; android.util.Log.w(DebugName, "App Visiblility Changed -> application is visible: " + isVisible); // take some action on change of visibility } private void setForeground(boolean inForeground) { if (isInForeground == inForeground) { // no change return; } // in foreground changed isInForeground = inForeground; android.util.Log.w(DebugName, "App In Foreground Changed -> application is in foreground: " + isInForeground); // take some action on change of in foreground } public static boolean isApplicationVisible() { return AppLifecycleHandler.getInstance().started > 0; } public static boolean isApplicationInForeground() { return AppLifecycleHandler.getInstance().resumed > 0; } } 

为了搭载CommonsWare和Key所说的话,你可以扩展Application类,让所有的活动在onPause / onResume方法上调用它。 这可以让你知道哪些活动是可见的,但这可能会更好地处理。

你能详细说明一下你的想法吗? 当你说在后台运行,你的意思是简单地让你的应用程序仍然在内存中,即使它不在屏幕上? 你有没有看过使用服务作为一个更持久的方式来pipe理你的应用程序,当它没有在焦点?

我做了我自己的ActivityLifecycleCallbacks实现。 我正在使用SherlockActivity,但对于正常的活动类可能工作。

首先,我创build了一个接口,其中包含跟踪活动生命周期的所有方法:

 public interface ActivityLifecycleCallbacks{ public void onActivityStopped(Activity activity); public void onActivityStarted(Activity activity); public void onActivitySaveInstanceState(Activity activity, Bundle outState); public void onActivityResumed(Activity activity); public void onActivityPaused(Activity activity); public void onActivityDestroyed(Activity activity); public void onActivityCreated(Activity activity, Bundle savedInstanceState); } 

其次,我在我的应用程序的类中实现了这个接口:

 public class MyApplication extends Application implements my.package.ActivityLifecycleCallbacks{ @Override public void onCreate() { super.onCreate(); } @Override public void onActivityStopped(Activity activity) { Log.i("Tracking Activity Stopped", activity.getLocalClassName()); } @Override public void onActivityStarted(Activity activity) { Log.i("Tracking Activity Started", activity.getLocalClassName()); } @Override public void onActivitySaveInstanceState(Activity activity, Bundle outState) { Log.i("Tracking Activity SaveInstanceState", activity.getLocalClassName()); } @Override public void onActivityResumed(Activity activity) { Log.i("Tracking Activity Resumed", activity.getLocalClassName()); } @Override public void onActivityPaused(Activity activity) { Log.i("Tracking Activity Paused", activity.getLocalClassName()); } @Override public void onActivityDestroyed(Activity activity) { Log.i("Tracking Activity Destroyed", activity.getLocalClassName()); } @Override public void onActivityCreated(Activity activity, Bundle savedInstanceState) { Log.i("Tracking Activity Created", activity.getLocalClassName()); } } 

第三,我创build了一个从SherlockActivity扩展的类:

 public class MySherlockActivity extends SherlockActivity { protected MyApplication nMyApplication; protected void onCreate(Bundle savedInstanceState) { // TODO Auto-generated method stub super.onCreate(savedInstanceState); nMyApplication = (MyApplication) getApplication(); nMyApplication.onActivityCreated(this, savedInstanceState); } protected void onResume() { // TODO Auto-generated method stub nMyApplication.onActivityResumed(this); super.onResume(); } @Override protected void onPause() { // TODO Auto-generated method stub nMyApplication.onActivityPaused(this); super.onPause(); } @Override protected void onDestroy() { // TODO Auto-generated method stub nMyApplication.onActivityDestroyed(this); super.onDestroy(); } @Override protected void onStart() { nMyApplication.onActivityStarted(this); super.onStart(); } @Override protected void onStop() { nMyApplication.onActivityStopped(this); super.onStop(); } @Override protected void onSaveInstanceState(Bundle outState) { nMyApplication.onActivitySaveInstanceState(this, outState); super.onSaveInstanceState(outState); } } 

第四,从SherlockActivity扩展的所有类,我replace为MySherlockActivity:

 public class MainActivity extends MySherlockActivity{ @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.main); } } 

现在,在logcat中,您将看到My​​Application中的接口实现中编写的日志。

我提出的最好的解决scheme是使用定时器。

你已经在onPause()中启动了一个定时器,并且在onResume()中取消了同一个定时器,定时器有1个实例(通常在Application类中定义)。 定时器本身被设置为在2秒后运行一个Runnable(或者你认为合适的间隔),当定时器触发时,你将一个标记应用程序的标志设置为背景。

在取消计时器之前的onResume()方法中,您可以查询后台标志以执行任何启动操作(例如,启动下载或启用位置服务)。

此解决scheme允许您在后退堆栈上执行多个活动,并且不需要任何权限来执行。

如果您使用事件总线,此解决scheme也可以正常工作,因为您的计时器可以简单地触发事件,并且应用程序的各个部分都可以相应地进行响应

如果您打开开发人员设置“不要保持活动” – 只检查创build的活动计数是不够的。 您还必须检查isSaveInstanceState 。 我的自定义方法是应用程序运行()检查是Android应用程序正在运行:

在这里我的工作代码:

 public class AppLifecycleService implements Application.ActivityLifecycleCallbacks { private int created; private boolean isSaveInstanceState; private static AppLifecycleService instance; private final static String TAG = AppLifecycleService.class.getName(); public static AppLifecycleService getInstance() { if (instance == null) { instance = new AppLifecycleService(); } return instance; } public static boolean isApplicationRunning() { boolean isApplicationRunning = true; if (getCountCreatedActvities() == 0 && !isSaveInstanceState()) { isApplicationRunning = false; } return isApplicationRunning; } public static boolean isSaveInstanceState() { return AppLifecycleService.getInstance().isSaveInstanceState; } public static int getCountCreatedActvities() { return AppLifecycleService.getInstance().created; } private AppLifecycleService() { } @Override public void onActivitySaveInstanceState(Activity activity, Bundle outState) { this.isSaveInstanceState = true; } @Override public void onActivityCreated(Activity activity, Bundle savedInstanceState) { ++created; } @Override public void onActivityDestroyed(Activity activity) { --created; } @Override public void onActivityResumed(Activity activity) { } @Override public void onActivityPaused(Activity activity) { } @Override public void onActivityStarted(Activity activity) { } @Override public void onActivityStopped(Activity activity) { } } 

这个旧post的另一个解决scheme(对于那些可能有帮助的):


 <application android:name=".BaseApplication" ... > 

 public class BaseApplication extends Application { private class Status { public boolean isVisible = true; public boolean isFocused = true; } private Map<Activity, Status> activities; @Override public void onCreate() { activities = new HashMap<Activity, Status>(); super.onCreate(); } private boolean hasVisibleActivity() { for (Status status : activities.values()) if (status.isVisible) return true; return false; } private boolean hasFocusedActivity() { for (Status status : activities.values()) if (status.isFocused) return true; return false; } public void onActivityCreate(Activity activity, boolean isStarting) { if (isStarting && activities.isEmpty()) onApplicationStart(); activities.put(activity, new Status()); } public void onActivityStart(Activity activity) { if (!hasVisibleActivity() && !hasFocusedActivity()) onApplicationForeground(); activities.get(activity).isVisible = true; } public void onActivityWindowFocusChanged(Activity activity, boolean hasFocus) { activities.get(activity).isFocused = hasFocus; } public void onActivityStop(Activity activity, boolean isFinishing) { activities.get(activity).isVisible = false; if (!isFinishing && !hasVisibleActivity() && !hasFocusedActivity()) onApplicationBackground(); } public void onActivityDestroy(Activity activity, boolean isFinishing) { activities.remove(activity); if(isFinishing && activities.isEmpty()) onApplicationStop(); } private void onApplicationStart() {Log.i(null, "Start");} private void onApplicationBackground() {Log.i(null, "Background");} private void onApplicationForeground() {Log.i(null, "Foreground");} private void onApplicationStop() {Log.i(null, "Stop");} } 

 public class MyActivity extends BaseActivity {...} 

 public class BaseActivity extends Activity { private BaseApplication application; @Override protected void onCreate(Bundle state) { application = (BaseApplication) getApplication(); application.onActivityCreate(this, state == null); super.onCreate(state); } @Override protected void onStart() { application.onActivityStart(this); super.onStart(); } @Override public void onWindowFocusChanged(boolean hasFocus) { application.onActivityWindowFocusChanged(this, hasFocus); super.onWindowFocusChanged(hasFocus); } @Override protected void onStop() { application.onActivityStop(this, isFinishing()); super.onStop(); } @Override protected void onDestroy() { application.onActivityDestroy(this, isFinishing()); super.onDestroy(); } } 

请参阅onActivityDestroyed函数中的注释。

适用于SDK目标版本14>:

 import android.app.Activity; import android.app.Application; import android.os.Bundle; import android.util.Log; public class AppLifecycleHandler implements Application.ActivityLifecycleCallbacks { public static int active = 0; @Override public void onActivityStopped(Activity activity) { Log.i("Tracking Activity Stopped", activity.getLocalClassName()); active--; } @Override public void onActivityStarted(Activity activity) { Log.i("Tracking Activity Started", activity.getLocalClassName()); active++; } @Override public void onActivitySaveInstanceState(Activity activity, Bundle outState) { Log.i("Tracking Activity SaveInstanceState", activity.getLocalClassName()); } @Override public void onActivityResumed(Activity activity) { Log.i("Tracking Activity Resumed", activity.getLocalClassName()); active++; } @Override public void onActivityPaused(Activity activity) { Log.i("Tracking Activity Paused", activity.getLocalClassName()); active--; } @Override public void onActivityDestroyed(Activity activity) { Log.i("Tracking Activity Destroyed", activity.getLocalClassName()); active--; // if active var here ever becomes zero, the app is closed or in background if(active == 0){ ... } } @Override public void onActivityCreated(Activity activity, Bundle savedInstanceState) { Log.i("Tracking Activity Created", activity.getLocalClassName()); active++; } } 

You should use a shared preference to store the property and act upon it using service binding from your activities. If you use binding only, (that is never use startService), then your service would run only when you bind to it, (bind onResume and unbind onPause) that would make it run on foreground only, and if you do want to work on background you can use the regular start stop service.

I think this question should be more clear. 什么时候? 哪里? What is your specific situation you want to konw if your app is in background?

I just introduce my solution in my way.
I get this done by using the field "importance" of RunningAppProcessInfo class in every activity's onStop method in my app, which can be simply achieved by providing a BaseActivity for other activities to extend which implements the onStop method to check the value of "importance". 这里是代码:

 public static boolean isAppRunning(Context context) { ActivityManager activityManager = (ActivityManager) context .getSystemService(Context.ACTIVITY_SERVICE); List<RunningAppProcessInfo> appProcesses = activityManager .getRunningAppProcesses(); for (RunningAppProcessInfo appProcess : appProcesses) { if (appProcess.processName.equals(context.getPackageName())) { if (appProcess.importance != RunningAppProcessInfo.IMPORTANCE_PERCEPTIBLE) { return true; } } } return false; } 

Activity gets paused when a Dialog comes above it so all the recommended solutions are half-solutions. You need to create hooks for dialogs as well.

I recommend reading through this page: http://developer.android.com/reference/android/app/Activity.html

In short, your activity is no longer visible after onStop() has been called.

What about using getApplicationState().isInForeground() ?

In my activities onResume and onPause I write an isVisible boolean to SharedPrefences.

  SharedPreferences sharedPrefs = PreferenceManager.getDefaultSharedPreferences(this); Editor editor = sharedPrefs.edit(); editor.putBoolean("visible", false); editor.commit(); 

And read it elsewhere when needed via,

  // Show a Toast Notification if App is not visible (ie in background. Not running, etc) SharedPreferences sharedPrefs = PreferenceManager.getDefaultSharedPreferences(context); if(!sharedPrefs.getBoolean("visible", true)){...} 

Maybe not elegant, but it works for me…

It might be too late to answer but if somebody comes visiting then here is the solution I suggest, The reason(s) an app wants to know it's state of being in background or coming to foreground can be many, a few are, 1. To show toasts and notifications when the user is in BG. 2.To perform some tasks for the first time user comes from BG, like a poll, redraw etc.

The solution by Idolon and others takes care of the first part, but does not for the second. If there are multiple activities in your app, and the user is switching between them, then by the time you are in second activity, the visible flag will be false. So it cannot be used deterministically.

I did something what was suggested by CommonsWare, "If the Service determines that there are no activities visible, and it remains that way for some amount of time , stop the data transfer at the next logical stopping point."

The line in bold is important and this can be used to achieve second item. So what I do is once I get the onActivityPaused() , don not change the visible to false directly, instead have a timer of 3 seconds (that is the max that the next activity should be launched), and if there is not onActivityResumed() call in the next 3 seconds, change visible to false. Similarly in onActivityResumed() if there is a timer then I cancel it. To sum up,the visible becomes isAppInBackground.

Sorry cannot copy-paste the code…

Another simple and accurate solution. Complete gist here

 public class BaseLifeCycleCallbacks implements Application.ActivityLifecycleCallbacks { HashMap<String, Integer> activities; BaseLifeCycleCallbacks() { activities = new HashMap<String, Integer>(); } @Override public void onActivityCreated(Activity activity, Bundle savedInstanceState) { } @Override public void onActivityStarted(Activity activity) { //map Activity unique class name with 1 on foreground activities.put(activity.getLocalClassName(), 1); applicationStatus(); } @Override public void onActivityResumed(Activity activity) { } @Override public void onActivityPaused(Activity activity) { } @Override public void onActivityStopped(Activity activity) { //map Activity unique class name with 0 on foreground activities.put(activity.getLocalClassName(), 0); applicationStatus(); } @Override public void onActivitySaveInstanceState(Activity activity, Bundle outState) { } @Override public void onActivityDestroyed(Activity activity) { } /** * Check if any activity is in the foreground */ private boolean isBackGround() { for (String s : activities.keySet()) { if (activities.get(s) == 1) { return false; } } return true; } /** * Log application status. */ private void applicationStatus() { Log.d("ApplicationStatus", "Is application background" + isBackGround()); if (isBackGround()) { //Do something if the application is in background } } 

I would like to recommend you to use another way to do this.

I guess you want to show start up screen while the program is starting, if it is already running in backend, don't show it.

Your application can continuously write current time to a specific file. While your application is starting, check the last timestamp, if current_time-last_time>the time range your specified for writing the latest time, it means your application is stopped, either killed by system or user himself.