如何使用UsageStatsManager?
背景
Google已弃用“ActivityManager”类的函数“ getRecentTasks ”。 现在只需要获取当前应用程序打开的应用程序列表。
我甚至在StackOverflow上写了一篇文章,但是我注意到这是不可能的。
问题
我已经做了一个关于它的文章( 在这里 ,另一个是由别人创build的类似文章),并请求重新考虑它,Google决定创build一个新的类,它似乎提供了类似的function(更像是统计,但也可能是有用的),但我不知道如何使用它。
该类被称为“UsageStatsManager”,我的猜测是函数“ queryUsageStats ”做这个工作。
此外,它似乎有一个新的权限(“android.permission.PACKAGE_USAGE_STATS”),这是一个系统权限,但它写道:
声明权限意味着使用API的意图,并且设备的用户可以通过设置应用程序授予权限。
这是关于这个新function的另一个链接。
我发现了什么
我已经看了Android的代码,并注意到“Context”有USAGE_STATS_SERVICE,在JavaDocs中说下一件事:
/** * Use with {@link #getSystemService} to retrieve a {@link * android.app.UsageStatsManager} for interacting with the status bar. * * @see #getSystemService * @see android.app.UsageStatsManager * @hide */ public static final String USAGE_STATS_SERVICE = "usagestats";
奇怪的是,它不仅说“状态栏”,而且packageName不匹配(而应该是“android.app.usage.UsageStatsManager”)。
我也添加了正确的权限:
<uses-permission android:name="android.permission.PACKAGE_USAGE_STATS" tools:ignore="ProtectedPermissions" />
这里是我使用的代码:
final UsageStatsManager usageStatsManager=(UsageStatsManager)context.getSystemService("usagestats");// Context.USAGE_STATS_SERVICE); final int currentYear=Calendar.getInstance().get(Calendar.YEAR); final List<UsageStats> queryUsageStats=usageStatsManager.queryUsageStats(UsageStatsManager.INTERVAL_YEARLY,currentYear-2,currentYear);
在模拟器本身,我去“设置” – >“安全” – >“使用访问的应用程序”,并启用我的应用程序。
但是,运行代码时,我得到的是一个空列表…
这个问题
你如何使用UsageStatsManager?
另外,您如何让用户以最简单的方式授予权限? 还是自动完成,只要应用程序试图获得所需的信息?
尝试使用这个类时会发生什么,但用户还没有确认呢?
我怎样才能让代码返回一个真正的应用程序列表?
我认为文档只是日历的东西。 我不认为这只是2014年的实际工作。 但是我可能是错的。
为了访问UsageStats的实际列表,您需要使用正确的月份,date和年份创build一个Calendar对象。 MRK在另一个答案中是如何说的。 我复制并纠正了MRK代码中的错误,所以任何在将来看到它的人都可以看到它。
Calendar beginCal = Calendar.getInstance(); beginCal.set(Calendar.DATE, 1); beginCal.set(Calendar.MONTH, 0); beginCal.set(Calendar.YEAR, 2012); Calendar endCal = Calendar.getInstance(); endCal.set(Calendar.DATE, 1); endCal.set(Calendar.MONTH, 0); endCal.set(Calendar.YEAR, 2014); final List<UsageStats> queryUsageStats=usageStatsManager.queryUsageStats(UsageStatsManager.INTERVAL_YEARLY, beginCal.getTimeInMillis(), endCal.getTimeInMillis());
– 信用卡; 由我纠正(他不小心只是把cal而不是beginCal和endCal)
下面是使用访问设置的代码。 🙂
Intent intent = new Intent(Settings.ACTION_USAGE_ACCESS_SETTINGS); startActivity(intent);
我已经创build了一个如何在我的Github上使用UsageStats的示例。 希望对某人有所帮助
回答你最后的问题“我怎样才能让代码返回给我一个真正的应用程序列表?”。 queryUsageStats以毫秒为单位开始时间和结束时间,而不是int中年份的值。
Calendar beginCal = Calendar.getInstance(); beginCal.set(Calendar.DATE, 1); beginCal.set(Calendar.MONTH, 0); beginCal.set(Calendar.YEAR, 2012); Calendar endCal = Calendar.getInstance(); endCal.set(Calendar.DATE, 1); endCal.set(Calendar.MONTH, 0); endCal.set(Calendar.YEAR, 2014); final List<UsageStats> queryUsageStats=usageStatsManager.queryUsageStats(UsageStatsManager.INTERVAL_YEARLY, beginCal.getTimeInMillis(), endCal.getTimeInMillis());
这应该返回2012年和2013年的UsageStats列表(请记住,结束时间不包括最终结果时间范围)。
当用户打开通知抽屉或locking屏幕时,使用UsageStats将得到错误的信息。 您必须使用UsageStatsManager.queryEvents()并使用MOVE_TO_FOREGROUND事件types查找最新的事件。
实际上AOSP示例代码中包含一个示例应用程序 : developers/samples/android/system/AppUsageStatistics/
它包含在应用程序中使用UsageStats
所需的所有位:
-
在
AndroidManifest.xml
声明权限<uses-permission android:name="android.permission.PACKAGE_USAGE_STATS"/>
-
显示设置以授予访问
UsageStatsManager
权限startActivity(new Intent(Settings.ACTION_USAGE_ACCESS_SETTINGS));
-
查询
UsageStatsManager
进行统计。Calendar cal = Calendar.getInstance(); cal.add(Calendar.YEAR, -1); List<UsageStats> queryUsageStats = mUsageStatsManager .queryUsageStats(intervalType, cal.getTimeInMillis(), System.currentTimeMillis());
-
根据
UsageStats
创build一个应用程序列表
总结并应用于您的示例:
- 您似乎正确地要求并授予访问使用统计信息的权限。
- 您正确获取
UsageStats
系统服务。 - 然而,您查询的时间段是简短的:参数
beginTime
和endTime
是从纪元开始测量的毫秒数。Calendar
实例可以通过getTimeinMillis()
给你这个值。 你错误地做的是只给出年份数字(如果你今天运行该程序,2015
和2017
)。 这些值被解释为自纪元起的毫秒数,因此间隔仅为2毫秒,并且在1970年的某个时间。
而不是你发布的以下代码片段,你应该复制下面发布的示例:
错误:
final int currentYear=Calendar.getInstance().get(Calendar.YEAR); final List<UsageStats> queryUsageStats=usageStatsManager.queryUsageStats(UsageStatsManager.INTERVAL_YEARLY,currentYear-2,currentYear);
正确:
final long currentTime = System.currentTimeMillis(); // Get current time in milliseconds final Calendar cal = Calendar.getInstance(); cal.add(Calendar.YEAR, -2); // Set year to beginning of desired period. final long beginTime = cal.getTimeInMillis(); // Get begin time in milliseconds final List<UsageStats> queryUsageStats=usageStatsManager.queryUsageStats(UsageStatsManager.INTERVAL_YEARLY, beginTime, currentTime);
你可以这样做
//noinspection ResourceType final UsageStatsManager usageStatsManager=(UsageStatsManager)context.getSystemService("usagestats");// Context.USAGE_STATS_SERVICE); final int currentYear=Calendar.getInstance().get(Calendar.YEAR); final List<UsageStats> queryUsageStats=usageStatsManager.queryUsageStats(UsageStatsManager.INTERVAL_YEARLY,currentYear-2,currentYear);