问题背景:
目前需求统计应用的当天使用情况,在 5.0 以上有权限 android.permission.PACKAGE_USAGE_STATS
,获取到该权限后可以通过 UsageStatsManager.queryUsageStats(int intervalType, long beginTime, long endTime)
方法查询到应用的使用情况。
问题描述:
第一天下午使用一些应用后,可以查询到相应应用的当天使用记录。第二天早上七点打开手机,在确定未使用这些应用的情况下,还是查询到了这些应用的当天使用记录。因为查询的是当天使用记录,所以在过去了一个自然日后,应该查询不到应用的使用记录才对。
问题分析:
queryUsageStats
有三个参数,分别是 intervalType
、beginTime
和 endTime
。先说说 beginTime
和 endTime
,它们分别表示待查询时间范围的起始时间和结束时间。而 intervalType
表示时间间隔的类型,它有5个值:
INTERVAL_DAILY
:天存储级别的数据;INTERVAL_WEEKLY
:星期存储级别的数据;INTERVAL_MONTHLY
:月存储级别的数据;INTERVAL_YEARLY
:年存储级别的数据;INTERVAL_BEST
:根据给定时间范围选取最佳时间间隔类型。
既然有了待查询时间范围,那么时间类型又有什么用呢,这就是导致上述问题发生的原因了。测试中查询的时间范围默认是当天零点到当前时间,而时间类型用的是 INTERVAL_DAILY
。在实际查询结果中发现查询到的使用记录并不是按给定时间范围来的,而是从前一天的某个时间点开始的。
我们先看下 queryUsageStats
返回的数据,它是一个 UsageStats
类型的数据集合,其中有几个关键字段:
mBeginTimeStamp
:查询范围的起始时间;mEndTimeStamp
:查询范围的起结束时间;mLastTimeUsed
:应用最后一次使用结束时的时间;mTotalTimeInForeground
:查询范围内应用在前台的累积时长;mLaunchCount
:查询范围内应用的打开次数。
进一步分析查询结果,发现其中的 mBeginTimeStamp
和 mEndTimeStamp
并不是传入的时间范围,而是和 intervalType
有关,比如在 INTERVAL_DAILY
情况下进行如下测试:
查询时间范围 2018-10-31 00:00:00
到 2018-10-31 18:00:00
,查询结果中 mBeginTimeStamp
和 mEndTimeStamp
分别为 2018-10-30 08:00:00
和 2018-10-31 07:59:59
。
查询时间范围 2018-10-30 10:00:00
到 2018-10-31 18:00:00
,查询结果中 mBeginTimeStamp
和 mEndTimeStamp
分别为 2018-10-30 08:00:00
和 2018-10-31 07:59:59
。
查询时间范围 2018-10-31 10:00:00
到 2018-10-31 18:00:00
,查询结果中 mBeginTimeStamp
和 mEndTimeStamp
分别为 2018-10-31 08:00:00
和 2018-10-31 19:17:32
(当前系统时间)。
从以上3次测试结果可以看出,beginTime
、endTime
与 mBeginTimeStamp
、mEndTimeStamp
没有显而易见的关系。我们再看一