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

Android Q(10) 系统下如何使用 MediaStore 实现图片保存功能?

Android 10(Q)使用MediaStore保存图片完整实现方案

前置说明

Android 10开始默认启用分区存储机制,向公共媒体目录(如Pictures、DCIM)保存图片时,不需要申请WRITE_EXTERNAL_STORAGE权限,你提供的代码是整个流程中的核心配置步骤,完整实现需要补全文件写入、状态更新等逻辑。

完整实现代码

以下为将Bitmap保存到系统Pictures目录下自定义文件夹的完整示例:

import android.content.ContentValues
import android.provider.MediaStore
import android.graphics.Bitmap
import android.os.Build
import android.content.Context
import android.os.Environment
import java.io.OutputStream

fun saveImageToGallery(context: Context, bitmap: Bitmap, fileName: String, folderName: String = "MyCustomImages"): Boolean {
    // 构造图片存储参数
    val contentValues = ContentValues().apply {
        put(MediaStore.Images.Media.DISPLAY_NAME, fileName)
        put(MediaStore.Images.Media.MIME_TYPE, "image/jpeg")
        // RELATIVE_PATH为Android 10新增字段,指定相对公共目录的路径
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q) {
            put(MediaStore.Images.Media.RELATIVE_PATH, "${Environment.DIRECTORY_PICTURES}/${folderName}")
            // 标记文件正在写入,避免其他应用提前访问
            put(MediaStore.Images.Media.IS_PENDING, 1)
        }
    }

    val contentResolver = context.contentResolver
    // 插入到外部存储图片的公共Uri
    val imageUri = contentResolver.insert(MediaStore.Images.Media.EXTERNAL_CONTENT_URI, contentValues) ?: return false

    var outputStream: OutputStream? = null
    return try {
        outputStream = contentResolver.openOutputStream(imageUri)
        // 把Bitmap写入输出流,质量可自定义0-100
        bitmap.compress(Bitmap.CompressFormat.JPEG, 90, outputStream)
        // 写入完成后更新pending状态,通知系统媒体库扫描
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q) {
            contentValues.clear()
            contentValues.put(MediaStore.Images.Media.IS_PENDING, 0)
            contentResolver.update(imageUri, contentValues, null, null)
        }
        true
    } catch (e: Exception) {
        e.printStackTrace()
        // 写入失败删除无效的Uri记录
        contentResolver.delete(imageUri, null, null)
        false
    } finally {
        outputStream?.close()
    }
}

注意事项

  • 如果需要兼容Android 9及更低版本,需要在AndroidManifest.xml中声明WRITE_EXTERNAL_STORAGE权限,同时可以在application节点添加android:requestLegacyExternalStorage="true"开启legacy存储模式做过渡
  • 文件名建议添加后缀(如xxx.jpg),避免部分系统识别格式异常
  • 不要在RELATIVE_PATH开头或末尾加多余的文件分隔符,防止部分机型出现路径异常
  • 如果插入返回的Uri为null,可检查文件夹名是否包含特殊字符,或当前应用是否有媒体存储权限异常

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.12 13:36:03