My app允许在最近推出时对应用列表进行排序。
从Android“L”开始,函数getRecentTasks将返回当前应用已启动的应用列表,如documentation中所述:
如果您的应用使用ActivityManager.getRecentTasks()...
随着新的并发文件和活动的引入 即将发布的版本中的任务功能(请参阅并发文档和 活动在下面的“最近”屏幕中) 现在不推荐使用ActivityManager.getRecentTasks()方法来改进 用户隐私。为了向后兼容,此方法仍返回a 它的一小部分数据,包括调用应用程序自己的数据 任务以及可能的其他一些非敏感任务(例如Home)。如果 您的应用正在使用此方法检索自己的任务,使用 而不是android.app.ActivityManager.getAppTasks()来检索它 信息。
使用ADT显示此功能的文档(目前在Internet上不可用)时写的相同:
不推荐使用此方法。截至L,此方法不再可用 到第三方应用程序:作为以文档为中心的引入 最近意味着它可以将个人信息泄露给呼叫者。对于 向后兼容性,它仍然会返回它的一小部分 data:至少是调用者自己的任务(尽管请参阅getAppTasks()) 检索该信息的正确支持方式),并且可能 其他一些任务,如家庭,已知不敏感。
我不明白为什么采取这种行为,因为很容易看到用户拥有哪些应用,甚至没有任何许可。
事实上,这是我添加的这个功能的一个很大的限制,所以我希望有办法克服这一点。
目前,我只使用了一种关于最近推出了哪些应用的启发式方法 - 我得到了正在运行的进程列表。
我也可以使用流程的重要性值,也许还可以使用“importanceReasonComponent”,但这只是所有的启发式和猜测......
有没有办法克服这个限制?我没有想到的任何解决方法?
也许root可以吗?还是BusyBox?
答案 0 :(得分:34)
要获取当前正在运行的top(Foreground)包名称,您需要使用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();
}
}
}
答案 1 :(得分:6)
如果使用UsageStats获取当前前台程序包,则当用户打开通知抽屉或锁定屏幕时,您将收到错误信息。 (在Android Lollipop和Marshmallow上测试过)
您必须使用UsageStatsManager.queryEvents()并使用MOVE_TO_FOREGROUND事件类型查找最新事件,以确定当前前台程序包。
答案 2 :(得分:2)
@ 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();
}
}
}
}
答案 3 :(得分:1)
Lollipop弃用了该方法;但是有一个新的API允许您查看应用程序使用情况。 由于安全问题,该方法已被弃用。 :\
UsageStatsManager有一些有用的方法可以查看时间间隔之间的活动。 希望这足以满足您的需求!
https://developer.android.com/reference/android/app/usage/package-summary.html