尝试反射仍无法获取UsageStats的mAppLaunchCount字段,求帮助
解决UsageStats中mAppLaunchCount字段无法获取的问题
问题核心原因
你用getField()获取mAppLaunchCount失败的关键在于:该字段是UsageStats类的私有成员变量,而getField()仅能访问类的公共(public)字段,私有字段必须通过getDeclaredField()获取,同时需要手动开启访问权限。
解决方案步骤
- 替换字段获取方法:使用
getDeclaredField()替代getField(),获取私有字段的引用。 - 开启私有字段访问权限:调用
Field.setAccessible(true),绕过Java的访问权限检查。 - 确保权限配置完整:必须在
AndroidManifest.xml中声明PACKAGE_USAGE_STATS权限,且引导用户在系统设置中为应用开启「应用使用情况访问权限」。
修正后的反射代码
// 遍历UsageStats列表,逐个获取应用启动次数 for (UsageStats usageStats : queryUsageStats) { try { // 获取私有字段mAppLaunchCount Field launchCountField = UsageStats.class.getDeclaredField("mAppLaunchCount"); // 开启私有字段的访问权限 launchCountField.setAccessible(true); // 读取字段值 int launchCount = (Integer) launchCountField.get(usageStats); Log.d("TAG", String.format("包名:%s,启动次数:%d", usageStats.getPackageName(), launchCount)); } catch (NoSuchFieldException e) { Log.e("TAG", "字段mAppLaunchCount不存在", e); } catch (IllegalAccessException e) { Log.e("TAG", "无法访问字段mAppLaunchCount", e); } }
权限配置说明
- 在
AndroidManifest.xml中添加权限声明:
<uses-permission android:name="android.permission.PACKAGE_USAGE_STATS" tools:ignore="ProtectedPermissions" />
- 引导用户手动开启权限(无权限时跳转设置页):
// 检查是否拥有应用使用情况权限 private boolean hasUsageStatsPermission(Context context) { AppOpsManager appOps = (AppOpsManager) context.getSystemService(Context.APP_OPS_SERVICE); int mode = appOps.checkOpNoThrow(AppOpsManager.OPSTR_GET_USAGE_STATS, android.os.Process.myUid(), context.getPackageName()); return mode == AppOpsManager.MODE_ALLOWED; } // 无权限时跳转设置页 if (!hasUsageStatsPermission(this)) { Intent intent = new Intent(Settings.ACTION_USAGE_ACCESS_SETTINGS); startActivity(intent); }
版本兼容性提示
部分Android版本可能对mAppLaunchCount字段做了调整,比如将类型改为long,若遇到ClassCastException,可尝试强转为Long后再转换:
long launchCountLong = (Long) launchCountField.get(usageStats); int launchCount = (int) launchCountLong;
内容的提问来源于stack exchange,提问作者shyam sojitra
相关产品推荐
相关产品推荐

