Android 13 Photo Picker抛出FileNotFoundException问题求助
解决Android Photo Picker跨组件访问Uri导致的FileNotFoundException
问题原因
Android 11及以上版本中,通过Photo Picker获取的Uri默认仅拥有临时读取权限,权限有效期仅限当前发起Picker的Fragment/Activity生命周期内。当你把这个Uri传递到其他Fragment/Activity中访问时,临时权限已经失效,就会触发FileNotFoundException。你的怀疑完全正确,缺失持久化Uri权限的申请是核心问题。
解决方案
在获取到Photo Picker返回的Uri后,立即申请持久化读取权限,确保跨组件访问时权限依然有效。
修改Fragment中的Picker回调代码
val launcher = rememberLauncherForActivityResult(ActivityResultContracts.PickVisualMedia()) { uri -> uri?.let { pickedUri -> // 申请持久化读取权限 val persistFlags = Intent.FLAG_GRANT_READ_URI_PERMISSION context?.contentResolver?.takePersistableUriPermission(pickedUri, persistFlags) // 再传递Uri到Adapter passToAdapter(pickedUri) } }
额外注意事项
- 持久化权限会一直保留,直到用户卸载应用、清除应用数据,或者你主动调用
releasePersistableUriPermission释放权限。 - 只有scheme为
content://的系统媒体Uri(Photo Picker返回的Uri符合这个要求)才能申请持久化权限,本地文件Uri不需要此操作。 - 如果只是临时跨组件传递Uri(比如启动一个Activity处理图片后就不再使用),也可以通过Intent添加
Intent.FLAG_GRANT_READ_URI_PERMISSION临时传递权限,但这种方式权限会随Intent接收方的生命周期结束而失效,不如持久化权限可靠。
验证效果
修改后,在不同Fragment/Activity中调用contentResolver.openInputStream(uri)时,就不会再触发FileNotFoundException了。
内容的提问来源于stack exchange,提问作者user14552676
相关产品推荐
相关产品推荐

