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

如何处理Android分区存储向后兼容 解决低版本图库保存失败问题

问题根因

Android系统存储权限机制随版本迭代存在差异:

  • Android 10(API 29)及以上版本启用分区存储模式,通过MediaStore向公共图库写入文件不需要申请存储权限,所以你的代码在Android10、11上运行正常
  • Android 9(API 28)及以下版本,向公共存储写入文件必须申请WRITE_EXTERNAL_STORAGE危险权限,你当前清单没有声明权限、也没有动态申请逻辑,所以触发权限拒绝报错。

修复步骤

1. 声明Manifest权限

在AndroidManifest.xml中添加适配多版本的权限声明:

<!-- 安卓9及以下需要的写存储权限,安卓10+系统会自动忽略该权限申请 -->
<uses-permission
    android:name="android.permission.WRITE_EXTERNAL_STORAGE"
    android:maxSdkVersion="28" />

加上maxSdkVersion=28是为了避免在高版本系统上出现不必要的权限申请提示

2. 添加动态权限申请逻辑

WRITE_EXTERNAL_STORAGE属于危险权限,安卓6.0(API23)到安卓9的版本,需要用户手动授权后才能调用存图逻辑,存图前先做权限判断:

// 存图执行前先校验权限
if (Build.VERSION.SDK_INT < Build.VERSION_CODES.Q &&
    ContextCompat.checkSelfPermission(mContext, Manifest.permission.WRITE_EXTERNAL_STORAGE)
    != PackageManager.PERMISSION_GRANTED) {
    // 无权限,先发起权限申请,REQUEST_CODE_WRITE_STORAGE可自定义为任意int值
    ActivityCompat.requestPermissions(
        mContext,
        arrayOf(Manifest.permission.WRITE_EXTERNAL_STORAGE),
        REQUEST_CODE_WRITE_STORAGE
    )
    return
}
// 已有权限,直接调用存图方法
saveImageToStorage(mContext, bitmap, filename)

在DisplayActivity中重写onRequestPermissionsResult接收授权结果,用户同意授权后再执行存图操作即可。

3. 兼容低版本的ContentValues参数

MediaStore.Images.Media.RELATIVE_PATH是API29才新增的字段,安卓9及以下系统无法识别,需要做版本判断,避免低版本出现未知异常:

val values = ContentValues().apply {
    put(MediaStore.Images.Media.DISPLAY_NAME, filename)
    put(MediaStore.Images.Media.MIME_TYPE, mimeType)
    // 仅API29及以上添加RELATIVE_PATH字段
    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q) {
        put(MediaStore.Images.Media.RELATIVE_PATH, directory)
    }
}

低版本系统会自动把图片存在公共图库的默认路径下,不影响最终保存结果

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.07 12:57:00