Android判断你的应用在前台还是在后台
/*** 判断应用是否是在后台*/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;}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17

一开始我用这个方法用来判断手机是否处于后台状态,如果应用处于后台的话,就停止应用程序中的音乐播放,但是却发现,点击 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;}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17

这样即使应用在播放应用的时候点击 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;}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19

上面这个方法通过监测应用进程是否处于前台状态,是否可见,手机是否锁屏来判断应用是否处于前台,如果这些情况有任一条达成的话就表明应用没有处于前台状态,这个方法在大部分测试机上都没有发现异常,但是我却在原生的 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;}
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49

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

registerActivityLifecycleCallbacks(new MyLifecycleHandler());
  • 1

这样的话我们就可以在自己定义的 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 系统(73)---Android判断你的应用在前台还是在后台相关推荐

  1. 【android系统】android系统升级流程分析(一)---recovery模式中进行update包升级流程分析

    今天我们直接来看下android中具体的升级过程是如何的. 升级流程概述 升级的流程图: 升级流程分析 第一步:升级包获取 升级获取可以通过远程下载,也可直接拷贝到指定目录即可. 第二步:准备升级 然 ...

  2. Android系统架构-[Android取经之路]

    摘要:本节主要来讲解Android的系统架构 阅读本文大约需要花费10分钟. 文章首发微信公众号:IngresGe 专注于Android系统级源码分析,Android的平台设计,欢迎关注我,谢谢! 欢 ...

  3. android 服务端技术,移动应用服务器端开发(基于JSP技术)-2017 Android系统构架 Android系统构架.docx...

    Android系统构架 PAGE 1 目 录 TOC \o "1-3" \h \z \u 一.Android系统构架 1 二.Linux内核层 2 三.系统运行库层 3 (一)系统 ...

  4. 【android系统】android系统升级流程分析(二)---update升级包分析

    接下来我们将通过几篇文章来分析update.zip包在具体Android系统升级的过程,来理解Android系统中Recovery模式服务的工作原理.今天让我先来分析下升级包update.zip. 一 ...

  5. android log抓取方法,Android系统之Android抓取各种log的方法

    Android系统之Android抓取各种log的方法 2018年11月25日 | 萬仟网移动技术 | 我要评论 android之android抓取各种log的方法 1.logcat (四类log b ...

  6. Android 系统(71)---Android系统build.prop文件生成过程

    Android系统build.prop文件生成过程 Android系统build.prop生成过程 这个文件类似于windows的注册表文件,定义了系统初始的一些参数属性,功能的开放等,通过调整或增加 ...

  7. Android系统(62)-----Android 7.1 新特性之 Shortcuts 介绍

    Android 7.1 新特性之 Shortcuts 介绍 Android 7.1 允许 App 自定义 Shortcuts,类似 iOS 的 3D touch.通过在桌面长按 App 弹出 Shor ...

  8. Android 系统(11)---android 系统权限大全

    收集到的android权限都很实用的(permission)大全 1.android.permission.WRITE_USER_DICTIONARY 允许应用程序向用户词典中写入新词 2.andro ...

  9. 【Android】判断你的应用在前台还是在后台

    我的尝试 /*** 判断应用是否是在后台*/public static boolean isBackground(Context context) {ActivityManager activityM ...

最新文章

  1. IIS 用户验证及授权
  2. mysql路由器配置文件_如何安装并配置mysql 5.7.13解压缩版?
  3. OpenCV isContinuous()连续存储的问题
  4. Android开发技巧——自定义控件之自定义属性
  5. tar中的zxvf都是什么?
  6. java课程设计进程管理_Java课设总结(个人版)
  7. 《知易行难》扩展练习
  8. leetcode - 141. 环形链表(哈希表)
  9. Java抽象类(abstract)、final关键字
  10. 计算机组成原理2套题,计算机组成原理试卷2套含答案(大学期末复习资料).doc...
  11. 驱动加载工具(InstDrv - V1.3中文版)
  12. 文件服务器挂在网上,(6)NAS简述 - 服务器 【已迁移到IXPUB】 - ITPUB论坛-专业的IT技术社区...
  13. 现在基因测序的瓶颈主要在哪里?精度?速度?
  14. 什么是二进制8421码?
  15. 西北大学计算机系房教授,西北大学段清波院长的秦陵尘封的帝国有人看过吗?...
  16. Android开发 RFC 2136 DNS动态更新协议
  17. 太白山北坡旅游路线登顶攻略
  18. vue设置页面背景色
  19. 告别夏日的烤串,迎来秋季的凉爽
  20. Unity中制作动画

热门文章

  1. 中断触发流程三(中断控制器)
  2. poll接口《来自Linux驱动程序开发实例》
  3. 使用pyinstaller打包python程序时问题记录
  4. 风险评估资产重要性识别_什么是风险分析,如何识别和评估风险?
  5. java kafka client_Kafka Client API 基本使用
  6. Oracle的10046事件
  7. springboot+springcloud相关面试题
  8. JDK、Tomcat、Maven配置
  9. maven ${path.separator}
  10. 转载-Oracle ORACLE的sign函数和DECODE函数