Android 11一加设备调用PackageManager查询应用信息崩溃怎么修复?
问题产生原因
- 崩溃的直接诱因是代码调用
getApplicationInfo时传入的包名com.mi.android.globalfileexplorer在当前一加设备上不存在,原生Android逻辑下该接口会直接抛出PackageManager.NameNotFoundException,你的代码没有做异常捕获,导致应用直接闪退。 - 仅在一加设备复现的原因是一加的氧/氢OS接近原生AOSP逻辑,没有对该异常做额外的空值兜底处理,而你其他测试的设备要么刚好预装/安装了小米文件管理器,要么厂商定制系统对该异常做了兼容处理,返回空值而非抛出崩溃。
- 额外排查点:即便设备安装了对应应用,Android 11引入的包可见性规则下,如果你未申请到
QUERY_ALL_PACKAGES权限、或者没有在<queries>节点声明对应包的查询权限,也会触发该异常。
修复方案
1. 核心修复:增加异常捕获逻辑
直接在调用getApplicationInfo的位置增加try-catch捕获异常,不存在的包直接跳过处理即可,修改后的代码如下:
private fun setMenuItems(apps: MutableList<String>, menu: Menu) { menu.clear() val pm = requireContext().packageManager apps.forEachIndexed { index, packageName -> // 增加异常捕获,避免包不存在/无查询权限时崩溃 try { val appInfo = pm.getApplicationInfo( packageName, PackageManager.GET_META_DATA ) menu.add( 0, index, Menu.NONE, pm.getApplicationLabel(appInfo) ).icon = pm.getApplicationIcon(packageName) } catch (e: PackageManager.NameNotFoundException) { // 包不存在或者无权限查询时直接跳过该应用 e.printStackTrace() } } if (menu is MenuBuilder) { menu.setOptionalIconsVisible(true) } }
注意原代码里setOptionalIconsVisible的调用放在循环外面即可,不需要每次循环都执行。
2. 可选优化:包可见性规则适配
如果你不需要查询设备上所有应用,建议不要申请QUERY_ALL_PACKAGES权限(该权限上架Google Play需要单独审核),把你需要查询的目标包名直接加到清单文件的<queries>节点即可,示例如下:
<queries> <intent> <action android:name="android.intent.action.PICK" /> <data android:mimeType="video/*, image/*" /> </intent> <!-- 单独声明需要查询的包名 --> <package android:name="com.mi.android.globalfileexplorer" /> <!-- 其他你需要查询的包名可以继续在这里加 --> </queries>
3. 前置处理优化
如果你的apps列表是动态获取的,可以在获取列表的阶段就过滤掉当前设备不存在的包,减少构建菜单时的异常处理逻辑。
内容的提问来源于stack exchange,提问作者Mohan K
相关产品推荐
相关产品推荐

