如何在 Android "L" 上获取最近的任务?
Posted
技术标签:
【中文标题】如何在 Android "L" 上获取最近的任务?【英文标题】:How to get recent tasks on Android "L"? 【发布时间】:2014-08-26 18:02:06 【问题描述】:背景
My app 允许按最近启动的时间对应用列表进行排序。
问题
从 android "L" 开始,函数 getRecentTasks 将只返回当前应用已启动的应用列表,如 documentation 中所述:
如果您的应用使用 ActivityManager.getRecentTasks()...
随着新的并发文档和活动的引入 即将发布的版本中的任务功能(请参阅并发文档和 活动在最近的屏幕下方), ActivityManager.getRecentTasks() 方法现在已被弃用以改进 用户隐私。为了向后兼容,这个方法仍然返回一个 其数据的一小部分,包括调用应用程序自己的 任务和可能的其他一些非敏感任务(例如家庭)。如果 您的应用正在使用此方法来检索自己的任务,请使用 android.app.ActivityManager.getAppTasks() 而不是检索那个 信息。
使用 ADT 显示该函数的文档时也是这样写的(目前在 Internet 上不可用):
此方法已弃用。自 L 起,此方法不再可用 到第三方应用程序:作为以文档为中心的引入 最近意味着它可以将个人信息泄露给来电者。为了 向后兼容性,它仍将返回其一小部分 数据:至少调用者自己的任务(尽管参见 getAppTasks() 检索该信息的正确支持方式),并且可能 其他一些已知不敏感的任务,例如家。
我不明白为什么要采取这种行动,因为很容易看到用户拥有哪些应用程序,即使没有任何许可。
问题是,这是我添加的这个功能的一个很大的限制,所以我希望有办法克服这个问题。
我尝试过的
目前,我只使用启发式方法来了解最近启动了哪些应用程序 - 我得到的是正在运行的进程列表。
我也可以使用流程的重要性值,也许还有“importanceReasonComponent”,但这只是所有的启发式和猜测......
问题
有没有办法克服这个限制?有什么我没有想到的解决方法?
也许有可能用root?还是 BusyBox?
【问题讨论】:
好吧,他们说原因:the ActivityManager.getRecentTasks() method is now deprecated to improve user privacy
我真的没有答案,但是对于“我不明白为什么要删除它”部分,我想通过 L 引入的新的“以文档为中心”的任务,你会'已经能够知道用户打开了哪些文档或单个网页。
@ianhanniballake 是的,我读过。我只是不同意它有助于隐私,因此我对此发表了一点评论。
@matiash 是的,我已经阅读了所有内容(或者至少我在这里发布的内容),并且还观看了视频,但我在这里要求另一种方法或解决方法,甚至如果需要 root/BusyBox。获取当前应用启动的内容并没有多大帮助...
主演this issue 并希望 Google 在 L 正式发布之前改变主意似乎是最好的选择。
【参考方案1】:
要获取当前运行的***(前台)包名称,您需要使用 Android Lollipop 中的 Usage Stats API。
但请注意,用户必须在每个应用程序的设置中批准对使用数据的访问。 因此,您应该通过使用
启动设置操作来直接提示用户进行设置Intent intent = new Intent(Settings.ACTION_USAGE_ACCESS_SETTINGS);
获取***包名:
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();
【讨论】:
是的,我忘了更新问题或添加答案。对不起。这是一个类似的问题,在我注意到这是使用它的方法之后:***.com/q/26431795/878126。不过有点奇怪。你能保证获得***应用吗?我的意思是,如果它在 10 多秒前被打开怎么办? 是的,你说得对,如果顶部打开超过 10 秒,则统计信息将返回空列表...大时间会增加列表的大小,因此有时间对其进行排序..所以它会加深您的实现以及您希望如何使用***包的知识。对我来说 10 秒就足够了。 也许,至少它可以获取最近的,从上次打开设备开始?我认为如果查询时间过长,需要相当长的时间才能得到结果。 @user3742392 适用于大多数应用程序,但不适用于某些系统应用程序(Google Now 启动器、下载等)。当其中一个应用程序运行时,它总是返回“com.google.android.googlequicksearchbox” 你会如何在 Android Wear 上做到这一点?它没有用户可以启用此功能的 ACTION_USAGE_ACCESS_SETTINGS 设置屏幕。提前致谢。【参考方案2】:如果您使用 UsageStats 获取当前前台包,当用户打开通知抽屉或锁定屏幕时,您将获得错误信息。 (在 Android Lollipop 和 Marshmallow 上测试)
您必须使用 UsageStatsManager.queryEvents() 并查找具有 MOVE_TO_FOREGROUND 事件类型的最新事件来决定当前的前台包。
【讨论】:
这个答案只是省了我很多麻烦,应该是公认的答案。 是不是也可以知道里面有哪些app有生存过程?【参考方案3】:@user3742392 的回答很好,但是使用 TreeMap 查找上次使用的时间有点矫枉过正(尤其是如果您想定期检查运行最频繁的应用程序)。
这是编辑后的答案,没有使用简单循环的 TreeMap:
String topPackageName;
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP)
UsageStatsManager mUsageStatsManager = (UsageStatsManager) getSystemService("usagestats");
long currentTime = System.currentTimeMillis();
// get usage stats for the last 10 seconds
List<UsageStats> stats = mUsageStatsManager.queryUsageStats(UsageStatsManager.INTERVAL_DAILY, currentTime - 1000 * 10, currentTime);
// search for app with most recent last used time
if (stats != null)
long lastUsedAppTime = 0;
for (UsageStats usageStats : stats)
if (usageStats.getLastTimeUsed() > lastUsedAppTime)
topPackageName = usageStats.getPackageName();
lastUsedAppTime = usageStats.getLastTimeUsed();
【讨论】:
【参考方案4】:Lollipop 已弃用该方法;但是有一个新的 API 允许您查看应用程序的使用情况。 由于安全问题,该方法已被弃用。 :\
UsageStatsManager 有一些有用的方法可以查看时间间隔之间的活动。 希望这足以满足您的需求!
https://developer.android.com/reference/android/app/usage/package-summary.html
【讨论】:
是的,很抱歉没有更新这个问题。我也找到了,现在不知道怎么用。能否请您检查一下:***.com/q/26431795 看看您是否成功使用它?如果是这样,我可以标记两个答案。以上是关于如何在 Android "L" 上获取最近的任务?的主要内容,如果未能解决你的问题,请参考以下文章
android 如何将swiperefreshlayout刷新动画能定制吗
如何在 android:updatePeriodMillis="0" 时从 Flutter 更新 Android 小部件?