Android 获取前台应用

一 .背景:

可以获取到Android设备当前正在显示的前台应用(如果可以,精细到页面)。

二.风险点

三.调研方案

3.1 Android 5.0之前getRunningTasks

Android5.0以前,使用ActivityManager的getRunningTasks()方法,可以得到应用包名和Activity;

还需要声明权限:

这种方法不止能获取包名,还能获取Activity名。但是在Android 5.0以后,系统就不再对第三方应用提供这种方式来获取前台应用了,虽然调用这个方法还是能够返回结果,但是结果只包含你自己的Activity和Launcher了。

具体可见下面的权限判断:

3.2 通过使用量统计功能获取前台应用

在StackOverFlow上大多数的答案都是使用usage statistics API。

Android提供了usage statistics API。这个API本来是系统用来统计app使用情况的,包含了每个app最近一次被使用的时间。我们只需要找出距离现在时间最短的那个app,就是当前在前台的app。

问题点:

这个权限试了下Android Studio 直接提示为系统权限,普通App无法申请。

到这里基本可以先否定这个方案了,步骤复杂,还需要用户手动开启权限,不可能哒!

3.3 通过辅助服务获取前台应用

Android 辅助服务(AccessibilityService)有很多神奇的妙用,比如辅助点击,比如页面抓取,还有就是获取前台应用。

这里简单介绍一下如何使用辅助服务,首先要在AndroidManifest.xml中声明:

然后在res/xml/文件夹下新建文件accessibility.xml,内容如下:

关键是typeWindowStateChanged。 新建AccessibilityMonitorService,主要内容如下:

问题点

so,这种方案不太稳定而且也是需要用户手动去开启,不可能哒!

3.4 通过设备辅助应用程序获取前台应用(比较鸡肋)

所谓设备辅助应用程序,是在一些接近原生的系统上,长按Home键就会触发的应用,默认是会触发Google搜索。设备辅助应用程序有点像是需要主动触发的辅助服务,因为应用中是无法主动去触发其功能的,所以说比较鸡肋,

3.5 PS 命令

在Android 的ADB命令中我们可以通过PS命令来获取到一些应用进程信息,看下官方解释:

大概意思就是说这个会列出系统调度列表,如果是系统的话,那是不是就说明能够得到界面的调度呢?


Android shell tricks: ps

If you ever played around with the adb shell you may have found that the ps utility, which lists process lists, is not as verbose as you would expect it to be. And, to make things worse, there’s no inline help or man entries. Here’s the ps utility usage line: ps -t -x -P -p -c [pid|name].

 

img

Android shell tricks: ps

Android’s core toolbox (shell utilities) are more primitive than the ones you may be used to. Notice how each argument needs to be separated and you can’t just -txPcit all, the command line argument parser is non-complex.

It’s a pity how command line arguments are not shown. If you need something that’s not available by the stock ps shell utility, try manually combing through the /procdirectory. For the command line one would do cat /proc/<pid>/cmdline.


首先我们在cmd命令行模式输入 : adb shell ps 输出一下信息:

 

img

然后能很清晰的看见各种包名而且都是系统正在运行中的,按照说明如果 -p 参数可以列出前台进程调度的话,如果我们在切换程序或者对出时包名列表都会有变化。

以下是输入 adb shell ps -p 后输出的信息:

 

img

仔细观察会发现u0开头的都是我们正常程序的包名,而且在程序切换到后台以后,这个列表是有变化的,随便启动一个自己安装的应用,列表也刚好出现那个应用。在此大家应该就已经知道怎么写了,这里也提供一下实现思路:

1、命令行获取控制台输出流 2、找出每行输出的 u0开通的信息获取包名 3、用一个列表存入,与每次获取的当前列表项与上一次列表项对比,如果旧的列表不存在此包名,那就证明这个包就是新启动的了,如果没有就不做任何操作。

测试结论:

3.5 大招

从网络上看到一篇老外大神的做法,中文分析博客已经丢失,google一下也没有啥有效因袭。所以只好自己大概猜测和理解了

上代码:

 

不详细分析,大概意思就是每次前台应用变动就会改变一个配置文件,因此可以通过读取改配置的方案来获取前台应用。经过测试,基本主流应用在前台时都可以捕捉到。

四.大结论

原文