LibChecker 权限体验优化
出息了,给 6.1K start 的 LibChecker提交代码
https://github.com/LibChecker/LibChecker/pull/1783
先看效果
修复前:

修复后:

修复说明
问题现状
- 如果用户第一次未授予
已安装应用列表权限,那么用户就没有办法再在 app 内调起权限授予窗 - 即使在设置选项中开启了相应权限,再重新回到 app,也没有继续下一步扫描应用,需要强制关闭 app 后重新打开才会继续扫描
问题修复
- 未获取权限的情况下,加个按钮去申请
已安装应用列表权限 - 任何情况授予权限后,自动执行读取应用
背景与问题
在国内上架应用时,监管部门要求开发者获取 GET_INSTALLED_APPS权限才能读取已安装应用列表,否则将无法提供完整的应用信息。LibChecker 早期版本没有为该权限设计合理的申请流程:
- 点击按钮却不弹申请框 – 由于没有注册对应的
ActivityResultLauncher,当用户点击“拒绝”页上的按钮时,应用并不会请求GET_INSTALLED_APPS权限。 - 授权后流程中断 – 如果用户跳转到系统设置手动授予权限,再回到 LibChecker,应用仍然停留在拒绝页,无法继续读取应用列表。
这些问题不仅违背了工信部合规要求,也导致了不良的用户体验,需要在代码层面进行修复。
改动内容
此次 PR 的核心改动可分为四点:
1. 常量声明
在 Constants.kt 中新增了 GET_INSTALLED_APPS 字符串常量,用于引用系统权限名称 patch-diff.githubusercontent.com。
// Constants.kt
const val GET_INSTALLED_APPS = "com.android.permission.GET_INSTALLED_APPS"
2. AppListFragment:注册权限请求并在拒绝页触发
- 在
AppListFragment中声明新的ActivityResultLauncher<String>——queryAllPackagesPermissionLauncher - 当用户处于拒绝页时,点击
rejectView会调用queryAllPackagesPermissionLauncher.launch(Constants.GET_INSTALLED_APPS),弹出权限申请框 - 注册回调时,若权限授予成功,则重置
homeViewModel.checkPackagesPermission并调用initApps()重新加载应用列表 - 在
flip(page)方法中,当显示页切换为拒绝页时,将checkPackagesPermission标记为true,便于后续检测
这一系列改动保证了用户点击按钮时能看到系统权限弹窗,并在授权成功后立即回调业务逻辑。
3. HomeViewModel:新增状态标记
在 HomeViewModel 中增加了 checkPackagesPermission 布尔变量。它用于标记当前是否需要在 Activity 恢复时重新检查权限,避免在未申请或未授权情况下无意义地调用初始化逻辑。
4. MainActivity:在 onResume 中重新检测并继续流程
在 MainActivity 的 onResume() 方法中新增如下逻辑
override fun onResume() {
super.onResume()
if (appViewModel.checkPackagesPermission) {
val granted = ContextCompat.checkSelfPermission(
this,
Constants.GET_INSTALLED_APPS
) == PackageManager.PERMISSION_GRANTED
if (granted) {
appViewModel.checkPackagesPermission = false
appViewModel.initItems() // 重新加载应用列表
}
}
}
如果从系统设置返回时检测到用户已授权,则清除标记并重新初始化应用列表。这样即使用户离开应用去授权,也能获得无缝体验。
效果与意义
通过上述改造,LibChecker 的权限申请流程更加完善:
- 合规:在用户点击拒绝页时主动请求
GET_INSTALLED_APPS权限,符合国内应用商店的合规要求 - 体验优化:授权后返回应用会立即检测并继续加载应用列表,不会停留在拒绝页
- 代码解耦:利用
ActivityResultLauncher与HomeViewModel的标记解耦了 UI 和业务逻辑,代码更易维护
后续思考
这一改动只是合规性的开始。国内隐私规范日益严格,未来可能还会要求对“查询已安装应用列表”进行最小化采集或匿名化处理。在后续版本中,可以进一步结合隐私沙盒或动态权限分级策略,确保在满足功能需求的同时最大化地保护用户隐私。
© 2025 Yuuou.
本站原创内容遵循 CC BY-NC-SA 4.0 知识共享许可协议。
欢迎非商业转载与引用,请注明出处
本站旨在记录技术探索与安全研究,所有内容仅代表作者个人观点
「让知识自由流动,而非被囚禁」