Android R+设备中UsageStatsManager.queryEvents返回null问题求助
解决Android 11+上UsageStatsManager.queryEvents返回空结果的问题
核心原因
PACKAGE_USAGE_STATS是Android的系统特殊权限,仅在Manifest中声明权限不足以获取访问权限,必须让用户手动到系统设置中开启「允许查看应用使用情况」的授权。QUERY_ALL_PACKAGES权限仅用于查询已安装应用列表,和应用使用统计功能无关。
解决步骤
1. 检查是否已获取应用使用统计权限
执行查询前先确认权限状态:
fun hasUsageStatsPermission(context: Context): Boolean { val usageStatsManager = context.getSystemService(Context.USAGE_STATS_SERVICE) as UsageStatsManager // Android 11+ 直接用系统API判断 if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.R) { return usageStatsManager.isAppUsageAccessAllowed() } // 低版本用AppOpsManager校验 val appOps = context.getSystemService(Context.APP_OPS_SERVICE) as AppOpsManager val mode = appOps.checkOpNoThrow( AppOpsManager.OPSTR_GET_USAGE_STATS, android.os.Process.myUid(), context.packageName ) return mode == AppOpsManager.MODE_ALLOWED }
2. 引导用户到授权页面
未授权时跳转到系统设置页面开启权限:
fun requestUsageStatsPermission(context: Context) { val intent = Intent(Settings.ACTION_USAGE_ACCESS_SETTINGS) intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK) context.startActivity(intent) }
3. 优化查询代码
确认权限后再执行查询,同时调整时间范围避免无事件返回:
if (hasUsageStatsPermission(context)) { val usageStatsManager = context.getSystemService(Context.USAGE_STATS_SERVICE) as UsageStatsManager val currentTimeMillis = System.currentTimeMillis() // 扩大查询范围到1小时,确保能捕获到事件 val startTime = currentTimeMillis - (1000 * 60 * 60) val queryEvents = usageStatsManager.queryEvents(startTime, currentTimeMillis) val event = UsageEvents.Event() var currentPackage = "" if (!queryEvents.hasNextEvent()) { Timber.d("未获取到应用使用事件") return } while (queryEvents.hasNextEvent()) { queryEvents.getNextEvent(event) Timber.d("事件包名: ${event.packageName}, 类型: ${event.eventType}") if (event.eventType == UsageEvents.Event.ACTIVITY_RESUMED) { currentPackage = event.packageName } } Timber.d("当前前台应用包名: $currentPackage") } else { // 引导用户授权 requestUsageStatsPermission(context) }
额外注意事项
- 授权后系统可能不会立即返回事件,建议稍作延迟再查询。
- 部分定制ROM对该权限有额外限制,需确认用户确实在设置中开启了权限。
内容的提问来源于stack exchange,提问作者Pedif
相关产品推荐
相关产品推荐

