React Native自定义UsageStatsManager模块始终返回空列表求助
排查React Native Android模块获取应用使用统计返回空列表的思路
1. 确认特殊权限是否真正开启
android.permission.PACKAGE_USAGE_STATS 属于特殊权限,仅在Manifest中声明无效,必须引导用户手动开启:
- 原生代码中添加跳转至权限设置页的逻辑:
val intent = Intent(Settings.ACTION_USAGE_ACCESS_SETTINGS) intent.flags = Intent.FLAG_ACTIVITY_NEW_TASK reactApplicationContext.startActivity(intent)
- 调用统计接口前先校验权限状态:
val appOpsManager = reactApplicationContext.getSystemService(Context.APP_OPS_SERVICE) as AppOpsManager val mode = appOpsManager.checkOpNoThrow(AppOpsManager.OPSTR_GET_USAGE_STATS, android.os.Process.myUid(), reactApplicationContext.packageName) val hasPermission = mode == AppOpsManager.MODE_ALLOWED if (!hasPermission) { successCallback.invoke(WritableNativeArray().apply { pushString("Error: 需要开启应用使用权限") }) return }
2. 修正查询时间区间的有效性
queryUsageStats的时间区间必须与指定的INTERVAL_*参数匹配:
- 使用
INTERVAL_DAILY时,起始时间需对齐到当天0点,否则可能返回空数据。调整时间区间示例:
val calendar = Calendar.getInstance() calendar.set(Calendar.HOUR_OF_DAY, 0) calendar.set(Calendar.MINUTE, 0) calendar.set(Calendar.SECOND, 0) val endTime = System.currentTimeMillis() val startTime = calendar.timeInMillis - 7 * 24 * 60 * 60 * 1000 // 最近7天的0点至当前时间
- 避免直接使用
Date().getTime() - 7*24*60*60*1000,非边界时间可能导致系统无法匹配到统计区间。
3. 通过Android日志定位核心问题
利用你已添加的Log.d("a", "a : " + usageStatsList.size),通过Android Studio的Logcat查看:
- 过滤标签
a,确认usageStatsList的实际大小。若为0,说明queryUsageStats本身未返回数据;若大于0但RN端为空,再排查回调逻辑。 - 同步查看是否有权限相关的警告/错误日志,比如
SecurityException或AppOpsManager相关提示。
4. 过滤无效的统计数据
部分应用的totalTimeInForeground可能为0,需过滤后再排序:
val filteredStats = usageStatsList.filter { it.totalTimeInForeground > 0 } filteredStats.sortByDescending { it.totalTimeInForeground } // 从filteredStats中提取前5个应用
5. 验证API兼容性
UsageStatsManager仅在Android 5.0(API 21)及以上版本可用,确保测试设备系统版本符合要求。- Android 10+对应用权限限制更严格,需确保应用处于前台时调用接口(主动触发场景影响较小,但需注意后台限制)。
6. 检查RN端回调逻辑
- 确认异常捕获后的回调是否正确传递错误信息,RN端可打印完整返回值排查:
UsageStatsModule.getUsageData(Number(startTime), Number(endTime), (topApps : any) => { console.log('Full response:', topApps); if (topApps[0]?.startsWith('Error:')) { console.error('Fetch error:', topApps[0]); } else { console.log('Top 5 apps:', topApps.slice(0,5)); } });
7. 更换测试环境验证
- 优先使用真机测试,模拟器可能缺乏真实应用使用数据,或权限模拟存在偏差。
- 测试前手动打开多个应用停留几分钟,确保设备有可被统计的应用使用记录。
内容的提问来源于stack exchange,提问作者vincent clerc
相关产品推荐
相关产品推荐

