前言
UsageStatsManager是用来知晓,设备中应用的使用情况的管理。它能给我们提供应用的进入前台动作与时间戳、进入后台的动作与时间戳、上次的使用时间、使用总时长等等信息。此功能在原生的设置-应用-使用统计中有所展示。
所需权限
<uses-permission android:name="android.permission.PACKAGE_USAGE_STATS"/>
查询当前应用的使用事件
这里使用的是queryEventsForSelf方法,在这个方法返回的数据里包含相同应用每一次进入前后台的时间点。
代码
fun query(context: Context) {
//查询的开始时间
val startCalendar = Calendar.getInstance()
startCalendar.set(Calendar.HOUR_OF_DAY, 0)
startCalendar.set(Calendar.MINUTE, 0)
startCalendar.set(Calendar.SECOND, 0)
//查询的结束时间
val endCalendar = Calendar.getInstance()
endCalendar.set(Calendar.HOUR_OF_DAY, 23)
endCalendar.set(Calendar.MINUTE, 59)
endCalendar.set(Calendar.SECOND, 59)
val simpleDateFormat = SimpleDateFormat("yyyy-MM-dd HH:mm:ss")
var usageStatsManager: UsageStatsManager = context.getSystemService(Context.USAGE_STATS_SERVICE) as UsageStatsManager
/**
* 查询当前应用的使用事件
*/
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.P) {
val usageEvents = usageStatsManager.queryEventsForSelf(startCalendar.timeInMillis, endCalendar.timeInMillis)
while (usageEvents.hasNextEvent()) {
val event = UsageEvents.Event()
usageEvents.getNextEvent(event)
when (event.eventType) {
MOVE_TO_FOREGROUND -> Log.e("zh", "进入前台 ${event.packageName} ${simpleDateFormat.format(event.timeStamp)}")
MOVE_TO_BACKGROUND -> Log.e("zh", "退出后台 ${event.packageName} ${simpleDateFormat.format(event.timeStamp)}")
else -> Log.e("zh", "其他事件 ${event.eventType} ${event.packageName} ${simpleDateFormat.format(event.timeStamp)}")
}
}
}
}
结果:
2023-05-23 11:25:37.934 14013-14013 zh com.xx.dev E 进入前台 com.xx.dev 2023-05-23 11:24:56
2023-05-23 11:25:37.935 14013-14013 zh com.xx.dev E 退出后台 com.xx.dev 2023-05-23 11:25:33
2023-05-23 11:25:37.935 14013-14013 zh com.xx.dev E 进入前台 com.xx.dev 2023-05-23 11:25:33
2023-05-23 11:25:37.935 14013-14013 zh com.xx.dev E 退出后台 com.xx.dev 2023-05-23 11:25:34
2023-05-23 11:25:37.935 14013-14013 zh com.xx.dev E 进入前台 com.xx.dev 2023-05-23 11:25:34
2023-05-23 11:25:37.935 14013-14013 zh com.xx.dev E 退出后台 com.xx.dev 2023-05-23 11:25:35
2023-05-23 11:25:37.935 14013-14013 zh com.xx.dev E 进入前台 com.xx.dev 2023-05-23 11:25:35
2023-05-23 11:25:37.935 14013-14013 zh com.xx.dev E 退出后台 com.xx.dev 2023-05-23 11:25:37
2023-05-23 11:25:37.935 14013-14013 zh com.xx.dev E 进入前台 com.xx.dev 2023-05-23 11:25:37
查询设备全局应用的使用事件
这里使用的是queryEvents方法
代码
fun query(context: Context) {
//查询的开始时间
val startCalendar = Calendar.getInstance()
startCalendar.set(Calendar.HOUR_OF_DAY, 0)
startCalendar.set(Calendar.MINUTE, 0)
startCalendar.set(Calendar.SECOND, 0)
//查询的结束时间
val endCalendar = Calendar.getInstance()
endCalendar.set(Calendar.HOUR_OF_DAY, 23)
endCalendar.set(Calendar.MINUTE, 59)
endCalendar.set(Calendar.SECOND, 59)
val simpleDateFormat = SimpleDateFormat("yyyy-MM-dd HH:mm:ss")
var usageStatsManager: UsageStatsManager = context.getSystemService(Context.USAGE_STATS_SERVICE) as UsageStatsManager
/**
* 查询设备全局应用的使用事件
*/
val usageEvents = usageStatsManager.queryEvents(startCalendar.timeInMillis, endCalendar.timeInMillis)
while (usageEvents.hasNextEvent()) {
val event = UsageEvents.Event()
usageEvents.getNextEvent(event)
when (event.eventType) {
MOVE_TO_FOREGROUND -> Log.e("zh", "进入前台 ${event.packageName} ${simpleDateFormat.format(event.timeStamp)}")
MOVE_TO_BACKGROUND -> Log.e("zh", "退出后台 ${event.packageName} ${simpleDateFormat.format(event.timeStamp)}")
}
}
}
结果
2023-05-23 14:09:23.051 6144-6144 zh com.xx.dev E 进入前台 com.android.launcher3 2023-05-23 14:08:57
2023-05-23 14:09:23.051 6144-6144 zh com.xx.dev E 退出后台 com.android.launcher3 2023-05-23 14:09:05
2023-05-23 14:09:23.051 6144-6144 zh com.xx.dev E 进入前台 com.xx.dev 2023-05-23 14:09:05
2023-05-23 14:09:23.051 6144-6144 zh com.xx.dev E 退出后台 com.xx.dev 2023-05-23 14:09:08
查询设备的应用使用统计情况
请注意下面的输入了时间间隔类型UsageStatsManager.INTERVAL_BEST,但是不代表返回的数值就是准确的,比如如果我查询中午12点至下午六点的使用统计,实际上它依然会返回今天应用的全部使用情况
代码
fun query(context: Context) {
//查询的开始时间
val startCalendar = Calendar.getInstance()
startCalendar.set(Calendar.HOUR_OF_DAY, 0)
startCalendar.set(Calendar.MINUTE, 0)
startCalendar.set(Calendar.SECOND, 0)
//查询的结束时间
val endCalendar = Calendar.getInstance()
endCalendar.set(Calendar.HOUR_OF_DAY, 23)
endCalendar.set(Calendar.MINUTE, 59)
endCalendar.set(Calendar.SECOND, 59)
val simpleDateFormat = SimpleDateFormat("yyyy-MM-dd HH:mm:ss")
var usageStatsManager: UsageStatsManager = context.getSystemService(Context.USAGE_STATS_SERVICE) as UsageStatsManager
/**
* 查询设备的应用使用统计情况
*/
val list = usageStatsManager.queryUsageStats(UsageStatsManager.INTERVAL_BEST, startCalendar.timeInMillis, endCalendar.timeInMillis)
for (item in list) {
Log.e("zh", "包名:${item.packageName}")
Log.e("zh", "开始时间:${simpleDateFormat.format(item.firstTimeStamp)}")
Log.e("zh", "上次时间戳:${simpleDateFormat.format(item.lastTimeStamp)}")
Log.e("zh", "最后使用时间:${simpleDateFormat.format(item.lastTimeUsed)}")
Log.e("zh", "前台总的时间:${item.totalTimeInForeground}")
}
}
结果
2023-05-23 14:28:04.162 9020-9020 zh com.xx.dev E 包名:com.android.server.telecom
2023-05-23 14:28:04.162 9020-9020 zh com.xx.dev E 开始时间:2023-05-23 09:44:08
2023-05-23 14:28:04.162 9020-9020 zh com.xx.dev E 上次时间戳:2023-05-23 14:23:13
2023-05-23 14:28:04.162 9020-9020 zh com.xx.dev E 最后使用时间:1970-01-01 08:00:00
2023-05-23 14:28:04.162 9020-9020 zh com.xx.dev E 前台总的时间:0
2023-05-23 14:28:04.162 9020-9020 zh com.xx.dev E 包名:android.ext.services
2023-05-23 14:28:04.162 9020-9020 zh com.xx.dev E 开始时间:2023-05-23 09:44:08
2023-05-23 14:28:04.162 9020-9020 zh com.xx.dev E 上次时间戳:2023-05-23 14:23:13
2023-05-23 14:28:04.163 9020-9020 zh com.xx.dev E 最后使用时间:1970-01-01 08:00:00
2023-05-23 14:28:04.163 9020-9020 zh com.xx.dev E 前台总的时间:0
2023-05-23 14:28:04.163 9020-9020 zh com.xx.dev E 包名:com.mediatek.capctrl.service
2023-05-23 14:28:04.163 9020-9020 zh com.xx.dev E 开始时间:2023-05-23 09:44:08
2023-05-23 14:28:04.163 9020-9020 zh com.xx.dev E 上次时间戳:2023-05-23 14:23:13
2023-05-23 14:28:04.163 9020-9020 zh com.xx.dev E 最后使用时间:1970-01-01 08:00:00
2023-05-23 14:28:04.163 9020-9020 zh com.xx.dev E 前台总的时间:0
2023-05-23 14:28:04.163 9020-9020 zh com.xx.dev E 包名:net.huanci.hsj
2023-05-23 14:28:04.163 9020-9020 zh com.xx.dev E 开始时间:2023-05-23 09:44:08
2023-05-23 14:28:04.163 9020-9020 zh com.xx.dev E 上次时间戳:2023-05-23 14:23:13
2023-05-23 14:28:04.163 9020-9020 zh com.xx.dev E 最后使用时间:2023-05-23 11:10:10
2023-05-23 14:28:04.163 9020-9020 zh com.xx.dev E 前台总的时间:11449
2023-05-23 14:28:04.163 9020-9020 zh com.xx.dev E 包名:com.android.smspush
2023-05-23 14:28:04.163 9020-9020 zh com.xx.dev E 开始时间:2023-05-23 09:44:08
2023-05-23 14:28:04.163 9020-9020 zh com.xx.dev E 上次时间戳:2023-05-23 14:23:13
2023-05-23 14:28:04.163 9020-9020 zh com.xx.dev E 最后使用时间:1970-01-01 08:00:00
查询给定范围内的所有统计数据(使用该范围的最佳间隔)
这里使用的是queryAndAggregateUsageStats方法,这个方法里不需要传入时间间隔参数,并且返回的是map集合。
代码
fun query(context: Context) {
//查询的开始时间
val startCalendar = Calendar.getInstance()
startCalendar.set(Calendar.HOUR_OF_DAY, 0)
startCalendar.set(Calendar.MINUTE, 0)
startCalendar.set(Calendar.SECOND, 0)
//查询的结束时间
val endCalendar = Calendar.getInstance()
endCalendar.set(Calendar.HOUR_OF_DAY, 23)
endCalendar.set(Calendar.MINUTE, 59)
endCalendar.set(Calendar.SECOND, 59)
val simpleDateFormat = SimpleDateFormat("yyyy-MM-dd HH:mm:ss")
var usageStatsManager: UsageStatsManager = context.getSystemService(Context.USAGE_STATS_SERVICE) as UsageStatsManager
val map = usageStatsManager.queryAndAggregateUsageStats(startCalendar.timeInMillis, System.currentTimeMillis())
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
map.forEach { key, value ->
Log.e("zh", "包名:${key}")
Log.e("zh", "开始时间:${simpleDateFormat.format(value.firstTimeStamp)}")
Log.e("zh", "上次使用时间戳:${simpleDateFormat.format(value.lastTimeStamp)}")
Log.e("zh", "最后使用时间:${simpleDateFormat.format(value.lastTimeUsed)}")
Log.e("zh", "前台总的时间:${value.totalTimeInForeground}")
}
}
}
结果
2023-05-23 14:38:09.392 11063-11063 zh com.xx.dev E 包名:net.huanci.hsj
2023-05-23 14:38:09.392 11063-11063 zh com.xx.dev E 开始时间:2023-05-23 09:44:08
2023-05-23 14:38:09.392 11063-11063 zh com.xx.dev E 上次使用时间戳:2023-05-23 14:23:13
2023-05-23 14:38:09.392 11063-11063 zh com.xx.dev E 最后使用时间:2023-05-23 11:10:10
2023-05-23 14:38:09.392 11063-11063 zh com.xx.dev E 前台总的时间:11449
2023-05-23 14:38:09.392 11063-11063 zh com.xx.dev E 包名:com.android.smspush
2023-05-23 14:38:09.392 11063-11063 zh com.xx.dev E 开始时间:2023-05-22 09:38:07
2023-05-23 14:38:09.392 11063-11063 zh com.xx.dev E 上次使用时间戳:2023-05-23 14:23:13
2023-05-23 14:38:09.392 11063-11063 zh com.xx.dev E 最后使用时间:1970-01-01 08:00:23
2023-05-23 14:38:09.392 11063-11063 zh com.xx.dev E 前台总的时间:0
2023-05-23 14:38:09.392 11063-11063 zh com.xx.dev E 包名:com.android.settings
2023-05-23 14:38:09.392 11063-11063 zh com.xx.dev E 开始时间:2023-05-22 09:38:07
2023-05-23 14:38:09.392 11063-11063 zh com.xx.dev E 上次使用时间戳:2023-05-23 09:38:07
2023-05-23 14:38:09.393 11063-11063 zh com.xx.dev E 最后使用时间:2023-05-23 09:33:18
2023-05-23 14:38:09.393 11063-11063 zh com.xx.dev E 前台总的时间:3328776
时间间隔类型
在上面的方法中,有要求输入查询时间的间隔类型,下面一共提供了4种间隔类型。
/**
* 跨越一天的间隔类型。参见{@link queryUsageStats(int, long, long)}。
*/
public static final int INTERVAL_DAILY = 0;
/**
* 跨越一周的间隔类型。参见{@link queryUsageStats(int, long, long)}。
*/
public static final int INTERVAL_WEEKLY = 1;
/**
* 跨越一个月的间隔类型。参见{@link queryUsageStats(int, long, long)}。
*/
public static final int INTERVAL_MONTHLY = 2;
/**
* 跨越一年的间隔类型。参见{@link queryUsageStats(int, long, long)}。
*/
public static final int INTERVAL_YEARLY = 3;
/**
* 一种间隔类型,它将使用给定时间范围的最佳拟合间隔。参见{@link queryUsageStats(int, long, long)}。
*/
public static final int INTERVAL_BEST = 4;
查询当前应用是否活跃
代码
@RequiresApi(Build.VERSION_CODES.M)
fun isAppInactive(context: Context, packageName:String):Boolean {
val usageStatsManager: UsageStatsManager = context.getSystemService(Context.USAGE_STATS_SERVICE) as UsageStatsManager
return usageStatsManager.isAppInactive(packageName)
}
其他api
queryConfigurations(int intervalType, long beginTime, long endTime) 获取指定时间区间内硬件配置信息统计数据。
end
标签:zh,05,23,xx,应用,2023,Android,com,UsageStatsManager From: https://www.cnblogs.com/guanxinjing/p/17425191.html