我的尝试

/*** 判断应用是否是在后台*/public static boolean isBackground(Context context) {ActivityManager activityManager = (ActivityManager) context.getSystemService(Context.ACTIVITY_SERVICE);KeyguardManager keyguardManager = (KeyguardManager) context.getSystemService(KEYGUARD_SERVICE);List<ActivityManager.RunningAppProcessInfo> appProcesses = activityManager.getRunningAppProcesses();for (ActivityManager.RunningAppProcessInfo appProcess : appProcesses) {if (TextUtils.equals(appProcess.processName, context.getPackageName())) {return appProcess.importance == ActivityManager.RunningAppProcessInfo.IMPORTANCE_BACKGROUND;}}return false;}

一开始我用这个方法用来判断手机是否处于后台状态,如果应用处于后台的话,就停止应用程序中的音乐播放,但是却发现,点击 Home 键让应用退到后台并不会让音乐停止播放,后来发现如果应用正在播放音乐的话,此时点击 Home 键应用并不会进入后台状态( ActivityManager.RunningAppProcessInfo.IMPORTANCE_BACKGROUND ),而是进入了一个 ActivityManager.RunningAppProcessInfo.IMPORTANCE_PERCEPTIBLE 的状态, 这个状态正是系统提供的应用后台播放应用的状态,好了,我们继续在原来的代码上进行完善:

/*** 判断应用是否是在后台*/public static boolean isBackground(Context context) {ActivityManager activityManager = (ActivityManager) context.getSystemService(Context.ACTIVITY_SERVICE);KeyguardManager keyguardManager = (KeyguardManager) context.getSystemService(KEYGUARD_SERVICE);List<ActivityManager.RunningAppProcessInfo> appProcesses = activityManager.getRunningAppProcesses();for (ActivityManager.RunningAppProcessInfo appProcess : appProcesses) {if (TextUtils.equals(appProcess.processName, context.getPackageName())) {return (appProcess.importance == ActivityManager.RunningAppProcessInfo.IMPORTANCE_BACKGROUND || appProcess.importance == ActivityManager.RunningAppProcessInfo.IMPORTANCE_PERCEPTIBLE);}}return false;}

这样即使应用在播放应用的时候点击 Home 键也可以认为此时处于后台状态,但是此时依然会出现判断应用是否在后台不准确的情况,我们继续优化原来的代码。

/*** 判断应用是否是在后台*/public static boolean isBackground(Context context) {ActivityManager activityManager = (ActivityManager) context.getSystemService(Context.ACTIVITY_SERVICE);KeyguardManager keyguardManager = (KeyguardManager) context.getSystemService(KEYGUARD_SERVICE);List<ActivityManager.RunningAppProcessInfo> appProcesses = activityManager.getRunningAppProcesses();for (ActivityManager.RunningAppProcessInfo appProcess : appProcesses) {if (TextUtils.equals(appProcess.processName, context.getPackageName())) {boolean isBackground = (appProcess.importance != ActivityManager.RunningAppProcessInfo.IMPORTANCE_FOREGROUND && appProcess.importance != ActivityManager.RunningAppProcessInfo.IMPORTANCE_VISIBLE);boolean isLockedState = keyguardManager.inKeyguardRestrictedInputMode();return isBackground || isLockedState;}}return false;}

上面这个方法通过监测应用进程是否处于前台状态,是否可见,手机是否锁屏来判断应用是否处于前台,如果这些情况有任一条达成的话就表明应用没有处于前台状态,这个方法在大部分测试机上都没有发现异常,但是我却在原生的 Nexus 5 手机上发现当当栈中的Activiy只有一个 Activity的时候,例如:应用启动,SplashActivity启动LoginActivity后,关闭SplashActivity,此时栈中就只生剩下了LoginActivity,此时,无论是点击返回键退出、点击 Home 键退到后台甚至点击右侧的多进程按键,此时的appProcess.importance 的都为 ActivityManager.RunningAppProcessInfo.IMPORTANCE_FOREGROUND,这样就彻底宣告了判断 appProcess.importance方法的失败。

最终用法

继承 Application.ActivityLifecycleCallbacks 写一个自己的 ActivityLifecycleCallbacks:

public class MyLifecycleHandler implements Application.ActivityLifecycleCallbacks {private static int resumed;private static int paused;private static int started;private static int stopped;@Overridepublic void onActivityCreated(Activity activity, Bundle savedInstanceState) {}@Overridepublic void onActivityStarted(Activity activity) {++started;}@Overridepublic void onActivityResumed(Activity activity) {++resumed;}@Overridepublic void onActivityPaused(Activity activity) {++paused;android.util.Log.w("test", "application is in foreground: " + (resumed > paused));}@Overridepublic void onActivityStopped(Activity activity) {++stopped;android.util.Log.w("test", "application is visible: " + (started > stopped));}@Overridepublic void onActivityDestroyed(Activity activity) {}@Overridepublic void onActivitySaveInstanceState(Activity activity, Bundle outState) {}public static boolean isApplicationVisible() {return started > stopped;}public static boolean isApplicationInForeground() {// 当所有 Activity 的状态中处于 resumed 的大于 paused 状态的,即可认为有Activity处于前台状态中 return resumed > paused;}
}

然后在自己定义的 Application 中的 onCreate() 方法中注册该 ActivityLifecycleCallbacks:

registerActivityLifecycleCallbacks(new MyLifecycleHandler());

这样的话我们就可以在自己定义的 ActivityLifecycleCallbacks 中监控自己应用中的所有的 Activity 的状态,通过 MyLifecycleHandler.isApplicationInForeground() 方法即可判断应用此时一定处于前台状态中,反之,则是处于”后台状态”。

以上就是我对于当前应用是处于前台还是后台的判断,无论大家是发现BUG和改进,还是有其它更好的办法,欢迎前来讨论!

需要注意:ActivityLifecycleCallbacks是在 API 14 即 Android 4.0加入的。

参考链接

http://stackoverflow.com/questions/3667022/checking-if-an-android-application-is-running-in-the-background/13809991#13809991
http://stackoverflow.com/questions/3667022/checking-if-an-android-application-is-running-in-the-background/5862048#5862048
https://segmentfault.com/q/1010000000687701
http://www.dewen.net.cn/q/10250/android%E7%B3%BB%E7%BB%9F%E8%BF%9B%E7%A8%8B%E9%87%8D%E8%A6%81%E7%AD%89%E7%BA%A7%E4%B8%ADIMPORTANCE_BACKGROUND%E5%92%8CIMPORTANCE_PERCEPTIBLE%E4%BB%80%E4%B9%88%E5%8C%BA%E5%88%AB%EF%BC%9F

【Android】判断你的应用在前台还是在后台相关推荐

  1. Android 系统(73)---Android判断你的应用在前台还是在后台

    Android判断你的应用在前台还是在后台 /*** 判断应用是否是在后台*/public static boolean isBackground(Context context) {Activity ...

  2. android 判断当前application 是在前台还是在后台

    2019独角兽企业重金招聘Python工程师标准>>> /**      *判断当前应用程序处于前台还是后台      *       * @param context * @ret ...

  3. android 判断activity是否在运行,Android 判断某个Activity 是否在前台运行的实例

    如下所示: /** * 判断某个界面是否在前台 * * @param context Context * @param className 界面的类名 * @return 是否在前台显示 */ pub ...

  4. android5.0以后获取应用运行状态,Android判断App前台运行还是后台运行(运行状态)...

    本文通过图文并茂的方式给大家介绍android判断app状态的相关内容,具体详情如下所示: 要了解这块,首先需要明白一些概念,app,process,task 1.process就是进程,是linux ...

  5. android 判断进程是否处于前台

    今天,简单讲讲如何判断android 的进程是否处于前台. 1.通过RunningTaskInfo类判断(需要额外权限): /***判断当前应用程序处于前台还是后台*/public static bo ...

  6. Android 判断app是否在前台还是在后台运行

    Android 判断app是否在前台还是在后台运行,直接看代码,可直接使用. [java]  view plain copy public static boolean isBackground(Co ...

  7. 如何判断Android app退后台、进前台

    安卓应用进后台要释放资源.进前台执行一些逻辑(比如执行接口刷数据.打开手势密码.启动服务等等). 要解决2个问题: 1. 如何判断应用当前是否在前台? 2.如何得到用户按Home键.再次打开应用的事件 ...

  8. Android判断App前台运行还是后台运行(运行状态)

    原文:http://p.codekk.com/detail/Android/wenmingvs/AndroidProcess AndroidProcess 项目地址:https://github.co ...

  9. Android判断应用是否在前台或后台

    Android判断应用是否在前台或后台 判断是否前台是否前端显示: /** * 判断一个程序是否显示在前端,根据测试此方法执行效率在11毫秒,无需担心此方法的执行效率 * * @param packa ...

最新文章

  1. golang sdk后端怎么用_Golang资深后端工程师需要了解的知识点
  2. adviser vs mentor
  3. 找出1个小时前更新的文件并进行拷贝
  4. Linux性能测试 sar命令
  5. Leetcode 76最小覆盖子串77组合78子集
  6. 中国经验对印度等金砖国家智慧城市建设的启示
  7. linux 网卡绑定updelay,Linux 配置双网卡绑定实现负载均衡
  8. 【区间DP】摆渡线路(2017 特长生 T4)
  9. linux /windows 基础篇
  10. linux运行jar包依赖,linux怎么打jar包
  11. 莫烦Tensorflow学习笔记(10-12)——构建简单的神经网络及其可视化
  12. 商城开发-用户管理模块(2)
  13. WIN10合并磁盘扩展区是灰色的
  14. 亲自动手从源码 构建 Groovy 2.3.8 发布包
  15. C——esc按键按下与识别
  16. Unity 按住A键更改鼠标光标样式
  17. Tesseract-OCR的使用---提取图片中的文字(OneNote)
  18. 贪心算法的最优解条件
  19. 程序人生 - 变脸的原理
  20. nod32官方升级服务器地址

热门文章

  1. 置换群的基本概念与题目
  2. 物理机(服务器)安装centos7系统,物理机上安装 centos7
  3. 支付宝手机网页支付接口调用
  4. 最佳教育:只要把一件事情做好,人生就能够成功
  5. 我接的是地啊,不,你接的是土!
  6. 设计原汁原味的 Windows Phone 应用
  7. vue 公共列表选择组件,引用museUI的样式
  8. Linux命令--top
  9. 【NOIP模拟】旷野大计算
  10. Boosting(Adboost、GBDT、Xgboost)