关键字: 应用统计 Android源码 应用使用时长 应用使用次数
上篇文章讲到关于Android系统应用数据统计的结果及其相关的数据结构,接下来主要从源码方面分析系统是如何记录相关数据的。
首先,我们可以找到这样一个Service。
/**
* A service that collects, aggregates, and persists application usage data.
* This data can be queried by apps that have been granted permission by AppOps.
*/
public class UsageStatsService extends SystemService implements
UserUsageStatsService.StatsUpdatedListener {
@Override
public void onStart() {
mAppOps = (AppOpsManager) getContext().getSystemService(Context.APP_OPS_SERVICE);
mUserManager = (UserManager) getContext().getSystemService(Context.USER_SERVICE);
mHandler = new H(BackgroundThread.get().getLooper());
//正如第一篇文章所阐述的那样,建立相关的文件目录
File systemDataDir = new File(Environment.getDataDirectory(), "system");
mUsageStatsDir = new File(systemDataDir, "usagestats");
mUsageStatsDir.mkdirs();
if (!mUsageStatsDir.exists()) {
throw new IllegalStateException("Usage stats directory does not exist: "
+ mUsageStatsDir.getAbsolutePath());
}
getContext().registerReceiver(new UserRemovedReceiver(),
new IntentFilter(Intent.ACTION_USER_REMOVED));
synchronized (mLock) {
cleanUpRemovedUsersLocked();
}
//这里的时间,也可以稍微注意下,因为每次记录都会就爱那个相关时间戳写入文件中
mRealTimeSnapshot = SystemClock.elapsedRealtime();
mSystemTimeSnapshot = System.currentTimeMillis();
//以下两行最为关键,注册了两个Service
publishLocalService(UsageStatsManagerInternal.class, new LocalService());
publishBinderService(Context.USAGE_STATS_SERVICE, new BinderService());
}
将UsageStatsService的注释翻译过来,可知,该Service用于收集,统计,保存相关的应用使用情况的数据。在第三方应用权限允许的情况下,可以为该应用提供这些数据。在检查了相关文件目录,完成对应的准备工作之后,UsageStatsService注册了两个Service,分别为 LocalService 和 BinderService。这两个Service是UsageStatsService的两个内部类。具体如下:
LocalService
/**
* This local service implementation is primarily used by ActivityManagerService.
* ActivityManagerService will call these methods holding the 'am' lock, which means we
* shouldn't be doing any IO work or other long running tasks in these methods.
*/
private class LocalService extends UsageStatsManagerInternal {
@Override
public void reportEvent(ComponentName component, int userId, int eventType) {
if (component ==