You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.27 05:33:20