UsageStatsManager
简介
- UsageStatsManager就是使用情况统计管理者,通过它可以获取应用的使用情况
- 系统会统计应用的使用情况并保存起来,然后按照这些保存起来的信息的时间长短进行划分
统计数据组别
- 日长短级别数据:Daily data, 最长7天内的数据
- 星期长短级别数据:Weekly data最长4个星期内的数据
- 月长短级别数据: Monthly data最长6个月内的数据
- 年长短级别数据: Yearly data最长2年内的数据,也就是说,数据最长保存2年
统计数据类型
- 对于每一个应用来说,系统会记录以下信息:
- 应用最后一次被用的时间
- 对应存储的4个级别,应用在前台的总共时间
- 时间戳:一个组件一天之内改变状态的时刻(从前台到后台,或从后台到前台),这个组件可以通过包名或activity的名字来唯一标示。
- 时间戳:设备配置信息改变的时刻,如:横竖屏切换。
使用
首先声明权限
<uses-permission android:name="android.permission.PACKAGE_USAGE_STATS"
tools:ignore="ProtectedPermissions"/>
手动确保拥有对应的权限
@TargetApi(Build.VERSION_CODES.LOLLIPOP)
private static boolean checkUsageStatsPermission(Context context) {
try {
PackageManager packageManager = context.getPackageManager();
ApplicationInfo applicationInfo = packageManager.getApplicationInfo(context.getPackageName(), 0);
AppOpsManager appOpsManager = (AppOpsManager) context.getSystemService(Context.APP_OPS_SERVICE);
int mode = appOpsManager.checkOpNoThrow(AppOpsManager.OPSTR_GET_USAGE_STATS, applicationInfo.uid, applicationInfo.packageName);
return (mode == AppOpsManager.MODE_ALLOWED);
} catch (PackageManager.NameNotFoundException e) {
return false;
}
}
if (Build.VERSION.SDK_INT >=21 && !checkUsageStatsPermission(context)) {
RecAlertDialog.RecBuilder builder = RecAlertDialog.builder(mContext)
.setMessage(R.string.camera_permission_dialog_content)
.setPositiveButton(R.string.done, new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
Intent intent = new Intent(Settings.ACTION_USAGE_ACCESS_SETTINGS);
intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
context.startActivity(intent);
}
});
builder.setCancelable(false);
AlertDialogActivity.alert(builder);
AlertDialogActivity.show(mContext);
}
具体使用
Calendar calendar=Calendar.getInstance();
calendar.setTime(new Date());
long endt = calendar.getTimeInMillis();
calendar.add(Calendar.DAY_OF_MONTH, -1);
long statt = calendar.getTimeInMillis();
UsageStatsManager usageStatsManager=(UsageStatsManager) getSystemService(USAGE_STATS_SERVICE);
List<UsageStats> queryUsageStats = usageStatsManager.queryUsageStats(UsageStatsManager.INTERVAL_MONTHLY,statt,endt);
- 无论使用哪种级别,start和end都必须时时间戳
- 在设置时间间隔时,最好不要将时间间隔设置的太短,否则如果没有上面对应的数据,查询的数据很可能是为空的
检则前台app
private String getForegroundApp () {
ActivityManager mActivityManager =(ActivityManager) mContext.getSystemService(Context.ACTIVITY_SERVICE);
if (mActivityManager.getRunningTasks(1) == null) {
Log.e(TAG, "running task is null, ams is abnormal!!!");
return null;
}
ActivityManager.RunningTaskInfo mRunningTask = mActivityManager.getRunningTasks(1).get(0);
if (mRunningTask == null) {
Log.e(TAG, "failed to get RunningTaskInfo");
return null;
}
return mRunningTask.topActivity.getPackageName();
}
@TargetApi(21)
private String getForegroundAppL (Context context) {
UsageStatsManager usageStatsManager =(UsageStatsManager) context.getSystemService(Context.USAGE_STATS_SERVICE);
long ts = System.currentTimeMillis();
UsageEvents usageEvents = usageStatsManager.queryEvents(ts - 20000, ts);
if (usageEvents == null) {
return null;
}
UsageEvents.Event event = new UsageEvents.Event();
UsageEvents.Event lastEvent = null;
while (usageEvents.hasNextEvent()) {
usageEvents.getNextEvent(event);
if (event.getPackageName() == null || event.getClassName() == null) {
continue;
}
if (lastEvent == null || lastEvent.getTimeStamp() < event.getTimeStamp()) {
lastEvent = event;
}
}
if (lastEvent == null) {
return null;
}
return lastEvent.getPackageName();
}