Android 11中使用ActivityResult选媒体文件仅返回RESULT_CANCELED如何解决
问题产生原因
- Android 11(API 30)新增了包可见性校验机制,应用默认只能识别到清单里显式声明查询规则的外部应用。你代码中用
Intent.createChooser()包裹ACTION_OPEN_DOCUMENT启动选择器时,系统需要先枚举可处理该Intent的应用,缺少对应查询规则的情况下系统无法找到文件选择器,会直接返回RESULT_CANCELED。 ACTION_OPEN_DOCUMENT本身是系统定向到内置文档选择器的Action,不需要额外通过createChooser创建选择弹窗,多余的包装在Android 11+上会触发额外的权限校验逻辑,导致请求直接被取消。
解决方法
方案1:移除createChooser包装(优先推荐)
直接启动原ACTION_OPEN_DOCUMENT intent即可,系统会自动唤起内置文件选择器,不需要额外封装,修改启动代码:
//Pick an image from storage Intent intent = new Intent(Intent.ACTION_OPEN_DOCUMENT); intent.setType(type); //Can be image/* or video/* intent.putExtra(Intent.EXTRA_ALLOW_MULTIPLE, true); // 移除Intent.createChooser包装,直接启动原intent activityResultLauncher.launch(intent);
方案2:保留选择器的情况下补充查询权限
如果业务需要自定义选择器的标题,需要在AndroidManifest.xml中添加对应的查询规则,让应用可以识别到系统文件选择器:
<manifest ...> <!-- Android 11+ 包可见性查询声明 --> <queries> <intent> <action android:name="android.intent.action.OPEN_DOCUMENT" /> <data android:mimeType="*/*" /> </intent> </queries> <application ...> ... </application> </manifest>
如果你的应用只需要选择图片/视频,也可以把mimeType拆分为image/*和video/*两个intent规则,缩小查询范围。
另外注意Android 11+使用ACTION_OPEN_DOCUMENT不需要申请READ_EXTERNAL_STORAGE等存储权限,错误声明过时的存储权限反而可能导致部分系统版本逻辑异常,可以直接移除相关权限声明。
内容的提问来源于stack exchange,提问作者Bitwise DEVS
相关产品推荐
相关产品推荐

