如何在Android"L"上获取最近的任务?

and*_*per 23 android process android-task android-5.0-lollipop

背景

我的应用程序允许在最近推出时对应用列表进行排序.

问题

从Android"L"开始,函数getRecentTasks将返回当前应用程序已启动的应用程序列表,如文档中所述:

如果您的应用使用ActivityManager.getRecentTasks()...

通过在即将发布的版本中引入新的并发文档和活动任务功能(请参阅下面的"最近的并发文档和活动"屏幕),现在不推荐使用ActivityManager.getRecentTasks()方法来提高用户隐私.为了向后兼容,此方法仍然返回其数据的一小部分,包括调用应用程序自己的任务以及可能的一些其他非敏感任务(例如Home).如果您的应用使用此方法检索自己的任务,请使用android.app.ActivityManager.getAppTasks()来检索该信息.

使用ADT显示此功能的文档(当前在Internet上不可用)时写入相同内容:

不推荐使用此方法.从L开始,此方法不再适用于第三方应用程序:因为引入以文档为中心的最新版本意味着它可能会将个人信息泄露给调用者.为了向后兼容,它仍将返回其数据的一小部分:至少是调用者自己的任务(尽管请参阅getAppTasks()以获取正确支持的方式来检索该信息),并且可能还有一些其他任务,例如home已知的不敏感.

我不明白为什么采取这种行为,因为很容易看到用户拥有哪些应用程序,甚至没有任何许可.

事实上,这是我添加的这个功能的一大限制,所以我希望有办法克服这个问题.

我试过的

目前,我只使用了一种关于最近推出了哪些应用程序的启发式方法 - 我得到了正在运行的进程列表.

我也可以使用流程的重要性值,也许还可以使用"importanceReasonComponent",但这只是所有的启发式和猜测......

这个问题

有没有办法克服这个限制?我没有想到的任何解决方法?

也许这有可能与root?还是BusyBox?

小智 34

要获取当前运行的top(Foreground)包名称,您需要使用Android Lollipop中的Usage Stats API.

但请注意,用户必须在每个应用程序的设置中批准访问使用数据.因此,您应该通过启动设置操作直接提示用户进行设置

Intent intent = new Intent(Settings.ACTION_USAGE_ACCESS_SETTINGS);
Run Code Online (Sandbox Code Playgroud)

要获得顶级包名称:

String topPackageName ;
if(Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) { 
    UsageStatsManager mUsageStatsManager = (UsageStatsManager)getSystemService("usagestats");                       
    long time = System.currentTimeMillis(); 
    // We get usage stats for the last 10 seconds
    List<UsageStats> stats = mUsageStatsManager.queryUsageStats(UsageStatsManager.INTERVAL_DAILY, time - 1000*10, time);                                    
    // Sort the stats by the last time used
    if(stats != null) {
        SortedMap<Long,UsageStats> mySortedMap = new TreeMap<Long,UsageStats>();
        for (UsageStats usageStats : stats) {
            mySortedMap.put(usageStats.getLastTimeUsed(),usageStats);
        }                    
        if(!mySortedMap.isEmpty()) {
            topPackageName =  mySortedMap.get(mySortedMap.lastKey()).getPackageName();                                   
        }                                       
    }
}
Run Code Online (Sandbox Code Playgroud)


Sam*_* Lu 6

如果使用UsageStats获取当前前台程序包,则当用户打开通知抽屉或锁定屏幕时,您将收到错误信息.(在Android Lollipop和Marshmallow上测试过)

您必须使用UsageStatsManager.queryEvents()并使用MOVE_TO_FOREGROUND事件类型查找最新事件以确定当前前台程序包.