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

Android13照片选择器选图后OkHttp发送报EFAULT(Bad address)错误

问题描述
  • 仅在Android 13系统使用Photo Picker选择图片时出现错误,无Photo Picker的版本运行正常。
  • 代码逻辑:用户通过Photo Picker选图后获取图片Uri,调用getFileFromUri方法转换为File对象的步骤正常;但使用Retrofit将该File作为multipart请求体发送时,LogCat出现警告/sdcard/.transforms/synthetic/picker/...: open failed: EFAULT (Bad address),随后Retrofit/OkHttp抛出异常。
  • 当前配置:Retrofit版本为com.squareup.retrofit2:retrofit:2.9.0;AndroidManifest中已配置WRITE_EXTERNAL_STORAGE、READ_EXTERNAL_STORAGE、READ_MEDIA_IMAGES权限,application节点设置android:requestLegacyExternalStorage="true";权限申请逻辑为Android 13及以上请求READ_MEDIA_IMAGES,其他版本请求READ_EXTERNAL_STORAGE。
  • 疑问:能否不使用MANAGE_EXTERNAL_STORAGE权限解决该问题?是否需要将图片复制到应用内部存储目录?
解决方案
  • 不需要申请MANAGE_EXTERNAL_STORAGE权限,该权限属于系统严格管控的特殊权限,你的场景完全可以通过常规方式解决。
  • 必须将图片复制到应用内部存储目录。Android 13的Photo Picker返回的是虚拟Uri,对应的文件路径是系统生成的临时合成路径,应用没有直接读取该文件的完整权限,即便成功转换为File对象,实际访问时仍会触发权限异常。
  • 具体操作步骤:
    1. 拿到Photo Picker返回的Uri后,通过ContentResolver读取文件输入流。
    2. 将输入流复制到应用内部存储目录(比如getCacheDir()或getFilesDir()下的子目录),生成新的File对象。
    3. 使用内部存储的File对象作为Retrofit的multipart请求体,即可正常完成文件上传。
  • 额外注意:上传完成后,记得在合适的时机清理内部存储中的临时图片文件,避免占用过多设备存储空间。

内容的提问来源于stack exchange,提问作者Yoko999

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.17 09:02:38