原文:http://p.codekk.com/detail/Android/wenmingvs/AndroidProcess




AndroidProcess

项目地址: wenmingvs/AndroidProcess 简介:判断指定 App 是否位于前台的方法 更多: 作者    提 Bug    标签: getRunningTask替代- 判断应用是否在前台- 获取程序使用信息-

提供 6 种方法来判断 App 处于前台还是后台,并且封装成工具类供大家使用

最后一种方法堪称 Android 黑科技(非原创),既可以突破 Android5.0 以上的权限封锁,获取任意前台 App 的包名,又不需要权限,此方法并非我原创,原作者是国外的大神,GitHub 项目在这里,也一并加入到工程中,供大家做全面的参考选择

2016.2.11 更新------感谢@EffectiveMatrix大神带来的新的判断前后台的方法

快速下载体验

百度网盘

预览图

用法

传入 Context 参数与想要判断是否位于前台的 App 的包名,会返回 ture 或者 false 表示 App 是否位于前台

//六种方法任选其一//使用方法一Boolean isForeground = BackgroundUtil.getRunningTask(context, packageName);//使用方法二Boolean isForeground = BackgroundUtil.getRunningAppProcesses(context, packageName);//使用方法三Boolean isForeground = BackgroundUtil.getApplicationValue(context);//使用方法四Boolean isForeground = BackgroundUtil.queryUsageStats(context, packageName);//使用方法五Boolean isForeground = BackgroundUtil.getFromAccessibilityService(context, packageName);//使用方法六Boolean isForeground = BackgroundUtil.getLinuxCoreInfo(context, packageName);

六种方法的区别

方法 判断原理 需要权限 可以判断其他应用位于前台 特点
方法一 RunningTask Android4.0 系列可以,5.0 以上机器不行 5.0 此方法被废弃
方法二 RunningProcess 当 App 存在后台常驻的 Service 时失效
方法三 ActivityLifecycleCallbacks 简单有效,代码最少
方法四 UsageStatsManager 需要用户手动授权
方法五 通过 Android 无障碍功能实现 需要用户手动授权
方法六 读取/proc 目录下的信息 当 proc 目录下文件夹过多时,过多的 IO 操作会引起耗时

方法一:通过 RunningTask

原理
当一个 App 处于前台的时候,会处于 RunningTask 的这个栈的栈顶,所以我们可以取出 RunningTask 的栈顶的任务进程,看他与我们的想要判断的 App 的包名是否相同,来达到效果

缺点
getRunningTask 方法在 Android5.0 以上已经被废弃,只会返回自己和系统的一些不敏感的 task,不再返回其他应用的 task,用此方法来判断自身 App 是否处于后台,仍然是有效的,但是无法判断其他应用是否位于前台,因为不再能获取信息

方法二:通过 RunningProcess

原理
通过 runningProcess 获取到一个当前正在运行的进程的 List,我们遍历这个 List 中的每一个进程,判断这个进程的一个 importance 属性是否是前台进程,并且包名是否与我们判断的 APP 的包名一样,如果这两个条件都符合,那么这个 App 就处于前台

缺点
在聊天类型的 App 中,常常需要常驻后台来不间断的获取服务器的消息,这就需要我们把 Service 设置成 START_STICKY,kill 后会被重启(等待 5 秒左右)来保证 Service 常驻后台。如果 Service 设置了这个属性,这个 App 的进程就会被判断是前台,代码上的表现就是 appProcess.importance 的值永远是 ActivityManager.RunningAppProcessInfo.IMPORTANCE_FOREGROUND,这样就永远无法判断出到底哪个是前台了。

方法三:通过 ActivityLifecycleCallbacks

原理
AndroidSDK14 在 Application 类里增加了 ActivityLifecycleCallbacks,我们可以通过这个 Callback 拿到 App 所有 Activity 的生命周期回调。

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

知道这些信息,我们就可以用更官方的办法来解决问题,当然还是利用方案二里的 Activity 生命周期的特性,我们只需要在 Application 的 onCreate()里去注册上述接口,然后由 Activity 回调回来运行状态即可。

可能还有人在纠结,我用 back 键切到后台和用 Home 键切到后台,一样吗?以上方法适用吗?在 Android 应用开发中一般认为 back 键是可以捕获的,而 Home 键是不能捕获的(除非修改 framework),但是上述方法从 Activity 生命周期着手解决问题,虽然这两种方式的 Activity 生命周期并不相同,但是二者都会执行 onStop();所以并不关心到底是触发了哪个键切入后台的。另外,Application 是否被销毁,都不会影响判断的正确性

方法四:通过使用 UsageStatsManager 获取

原理
通过使用 UsageStatsManager 获取,此方法是 Android5.0 之后提供的新 API,可以获取一个时间段内的应用统计信息,但是必须满足一下要求

使用前提

  1. 此方法只在 android5.0 以上有效
  2. AndroidManifest 中加入此权限
  3. 打开手机设置,点击安全-高级,在有权查看使用情况的应用中,为这个 App 打上勾

enter image description here

方法五:通过 Android 自带的无障碍功能

非常感谢@EffectiveMatrix大神带来的新的判断前后台的方法

此方法属于他原创,具体的博文参照这里http://effmx.com/articles/tong-guo-android-fu-zhu-gong-neng-accessibility-service-jian-ce-ren-yi-qian-tai-jie-mian/

此方法无法直观的通过下拉通知视图来进行前后台的观察,请到 LogCat 中进行观察即可,以下是 LogCat 中打印的信息

Android判断App前台运行还是后台运行(运行状态)_第1张图片

原理
Android 辅助功能(AccessibilityService) 为我们提供了一系列的事件回调,帮助我们指示一些用户界面的状态变化。 我们可以派生辅助功能类,进而对不同的 AccessibilityEvent 进行处理。 同样的,这个服务就可以用来判断当前的前台应用

优势

  1. AccessibilityService 有非常广泛的 ROM 覆盖,特别是非国产手机,从 Android API Level 8(Android 2.2) 到 Android Api Level 23(Android 6.0)
  2. AccessibilityService 不再需要轮询的判断当前的应用是不是在前台,系统会在窗口状态发生变化的时候主动回调,耗时和资源消耗都极小
  3. 不需要权限请求
  4. 它是一个稳定的方法,与 “方法 6”读取 /proc 目录不同,它并非利用 Android 一些设计上的漏洞,可以长期使用的可能很大
  5. 可以用来判断任意应用甚至 Activity, PopupWindow, Dialog 对象是否处于前台

劣势

  1. 需要要用户开启辅助功能
  2. 辅助功能会伴随应用被“强行停止”而剥夺

方法六:读取 Linux 系统内核保存在/proc 目录下的 process 进程信息

此方法并非我原创,原作者是国外的大神,GitHub 项目在这里,也一并加入到工程中,供大家做全面的参考选择

原理
无意中看到乌云上有人提的一个漏洞,Linux 系统内核会把 process 进程信息保存在/proc 目录下,Shell 命令去获取的他,再根据进程的属性判断是否为前台

优点

  1. 不需要任何权限
  2. 可以判断任意一个应用是否在前台,而不局限在自身应用

缺点

  1. 当/proc 下文件夹过多时,此方法是耗时操作

用法
获取一系列正在运行的 App 的进程

List processes = ProcessManager.getRunningAppProcesses();

获取任一正在运行的 App 进程的详细信息

AndroidAppProcess process = processes.get(location);String processName = process.name;Stat stat = process.stat();int pid = stat.getPid();int parentProcessId = stat.ppid();long startTime = stat.stime();int policy = stat.policy();char state = stat.state();Statm statm = process.statm();long totalSizeOfProcess = statm.getSize();long residentSetSize = statm.getResidentSetSize();PackageInfo packageInfo = process.getPackageInfo(context, 0);String appName = packageInfo.applicationInfo.loadLabel(pm).toString();

判断是否在前台

if (ProcessManager.isMyProcessInTheForeground()) {  // do stuff}

获取一系列正在运行的 App 进程的详细信息

List processes = ProcessManager.getRunningAppProcessInfo(ctx);

更多相关文章

  1. (转)Android 应用程序退出后不在运行列表中显示的方法
  2. Android Gallery控件使用方法详解
  3. Android 设置横屏竖屏的方法
  4. Android 复习笔记之图解View类的XML属性、相关方法及说明
  5. Android关于looper的几个方法的个人理解
  6. android后台安装apk
  7. Android 2.3.3 安卓系统 源代码 在Eclipse查看方法

随机推荐

  1. 在网络安全方面,苹果公司懈怠了吗?
  2. 输入年(包含闰年)和月份,输出天数
  3. 杀软对抗:一个面向***工程师的杀软绕过思
  4. 打造一款 刷Java 知识的小程序(一)
  5. 06. SpringCloud实战项目-Docker安装redi
  6. 07. SpringCloud实战项目-本地开发环境配
  7. springboot+vue项目实战-天猫商城
  8. 打造一款 刷Java 知识的小程序(二)
  9. 08. SpringCloud实战项目-配置Git
  10. 个人搭建网站要如何选择服务器?