使用 UsageStatsManager 获取应用信息
Android 5.0 之后,需要使用 UsageStatsManager 获取手机中的应用信息
使用方式
UsageStatsManager usageStatsManager = (UsageStatsManager) context.getSystemService(Context.USAGE_STATS_SERVICE);
List<UsageStats> queryUsageStats = usageStatsManager.queryUsageStats(UsageStatsManager.INTERVAL_MONTHLY,beginTime,endTime);
UsageStatsManager.queryUsageStats()方法解析:
有三个参数,分别是 intervalType、beginTime 和 endTime。
beginTime: 表示待查询时间范围的起始时间,返回的结果会包括起始时间
endTime:表示待查询时间范围的结束时间,返回的结果不包括结束时间
而 intervalType 表示时间间隔的类型,它有5个值:
INTERVAL_DAILY:天存储级别的数据;
INTERVAL_WEEKLY:星期存储级别的数据;
INTERVAL_MONTHLY:月存储级别的数据;
INTERVAL_YEARLY:年存储级别的数据;
INTERVAL_BEST:根据给定时间范围选取最佳时间间隔类型。
queryUsageStats() 返回的数据,它是一个 UsageStats 类型的数据集合,其中有几个关键字段:
mBeginTimeStamp:查询范围的起始时间;
mEndTimeStamp:查询范围的起结束时间;
mLastTimeUsed:应用最后一次使用结束时的时间;
mTotalTimeInForeground:查询范围内应用在前台的累积时长;
mAppLaunchCount:查询范围内应用的打开次数。
queryUsageStats 的查询范围依赖 intervalType 而定,比如 INTERVAL_DAILY 类型会查询一天内的使用情况,并且根据传入的 beginTime 计算出该天的起始和结束时间。这里的天并非自然日的概念,而是受时区影响的一天,即北京时间(东八区)从 08:00:00 开始算一天,但在少数机型上也发现从 00:00:00 开始算一天。不过可以肯定的是 mBeginTimeStamp 会受到时区的影响,比如当前是东八区,修改到东十区,一天的起始时间会相应增加2小时。
查询的时间段无法调整到更精确的范围,只能考虑增加对 mLastTimeUsed 的判断,这个字段是应用最后一次使用结束时的时间,可以判断 mLastTimeUsed 是不是在 beginTime 和 endTime 之间来确定用户当天是否有使用过应用。
但是如果想判断用户当天是否有使用应用达到一定时长,就不能很准确的判断了。因为 mTotalTimeInForeground 统计的是 mBeginTimeStamp 到 mEndTimeStamp 期间应用在前台的累计时长,所以即使结合 mLastTimeUsed 判断出用户当天有打开过应用,但还是无法准确得知当天打开应用后的使用时长。
对UsageStatsManager.queryUsageStats() 返回list进行研究:
开始 - mBeginTimeStamp,结束 - mEndTimeStamp
从2019/9/5 10:35:16开始到当前时间的天气应用一天的使用概况:
返回的list有2个
1.开始:2019/9/5 9:10:2 ,结束:2019/9/6 9:10:2
2.开始:2019/9/6 9:18:25 ,结束:2019/9/6 10:26:55
- 其中第一个UsageStats是有应用打开次数的,最后一次使用的时间是2019/9/5 17:31:46,好像也符合我使用的时间。
- 而第二个则没有。
从0开始到当前时间的天气应用一天的使用概况:
返回的list有10个
1.开始:2019/8/28 4:16:45 ,结束:2019/8/29 4:16:45
2.开始:2019/8/29 4:58:4 ,结束:2019/8/30 4:58:4
3.开始:2019/8/30 5:0:15 ,结束:2019/8/31 5:0:15
.....
8.开始:2019/9/4 8:45:3 ,结束:2019/9/5 8:45:3
9.开始:2019/9/5 9:10:2 ,结束:2019/9/6 9:10:2
10.开始:2019/9/6 9:18:25 ,结束:2019/9/6 10:16:55
其中第9个UsageStats是有应用打开次数的,最后一次使用的时间是2019/9/5 17:31:46,跟上面的使用时间是一致的。
其他则都没有。
从数据可以了解到beginTime是会被包含在mBeginTimeStamp里面的。
而mEndTimeStamp 则会在endTime之前。
还有就是真正能统计到应用打开数据的则是最近一天的数据项,而不是当前时间,可能跟你选择的
intervalType 有关系,以上的数据统计使用的是INTERVAL_DAILY。
调查开始时间和结束时间的规律
从某一个app开始调研,筛选出它的包名,然后用包名匹配返回结果中它的数据条目,将它的数据条目进行分析。
范围:beginTime - endTime
开始 - mBeginTimeStamp,结束 - mEndTimeStamp
范围: 0 - 当前时间
1.开始:2019/9/4 8:45:3 结束:2019/9/5 8:45:3 ,最后:2019/9/4 19:14:20
2.开始:2019/9/5 9:10:2 结束:2019/9/6 9:10:2 ,最后:2019/9/5 18:52:52
- 开始:2019/9/6 9:18:25 结束:2019/9/6 16:44:38 ,最后:2019/9/6 16:44:38
范围: 昨天 - 当前时间
1.开始:2019/9/5 9:10:2 结束:2019/9/6 9:10:2 ,最后:2019/9/5 18:52:52
2.开始:2019/9/6 9:18:25 结束:2019/9/6 16:44:38 ,最后:2019/9/6 16:44:38
范围: 2019/9/6 16:13:13 - 2019/9/6 17:13:13 (查询当天一小时内)
1.开始:2019/9/6 9:18:25 结束:2019/9/6 17:11:46 ,最后:2019/9/6 17:11:46
范围:0 - 2019/9/5 17:45:35(昨天)
1.开始:2019/9/4 8:45:3 结束:2019/9/5 8:45:3 ,最后:2019/9/4 19:14:20
2.开始:2019/9/5 9:10:2 结束:2019/9/6 9:10:2 ,最后:2019/9/5 18:52:52
根据这些数据可以总结出
- beginTime 的不同会影响查询出app的单条或多条数据,从0开始会查出全部数据。
- endTime 的不同一样也会影响查询的数据,跟beginTime 的大致相同,只不过它会影响结果的下限范围,即查从0-昨天的范围,返回的数据只会到昨天,不会显示今天的数据。
- 上面的每一个数据代表一天的使用情况,这并不是一定的,这个由 intervalType 决定,使用INTERVAL_DAILY 则代表一天,如果是 INTERVAL_MONTHLY 则代表一个月,所以单条数据里面的mAppLaunchCount 可以表示一天的启动次数,也可以表示一个月的启动次数。
- mBeginTimeStamp 相对来说是比较没有规律的,它跟 beginTime 并没有显而易见的关系,以天为单位的数据条目,总是以上午时间开始收集。
- mEndTimeStamp 则是会包含endTime,既是mEndTimeStamp >= endTime。