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
相关产品推荐
相关产品推荐

