MediaStore API — 是用于访问设备公共媒体文件(图片、视频、音频和文档)的 Android 接口。与直接文件访问不同,MediaStore 通过集中式媒体数据库和内容提供程序工作。根据 Android Developers Documentation (2025),从 Android 10 开始,该 API 取代了已过时的 READ_EXTERNAL_STORAGE,成为处理媒体的主要机制。开发者在图库、音乐播放器、相机和文件管理器中使用 MediaStore。
要点
MediaStore API — 是 Android 平台上的系统内容提供程序,用于索引、存储和提供对设备媒体文件的访问。该 API 是 Android SDK 的一部分,从 API Level 1 开始可用。
MediaStore 通过统一的媒体数据库工作,该数据库自动扫描设备并收集所有媒体文件的元数据。数据库 由系统更新 在添加、修改或删除文件时,因此应用程序无需手动扫描即可始终获取最新信息。
MediaStore 的主要表:Images(图片)、Video(视频)、Audio(音频)和 Files(通用文件)。每个表包含元数据列:名称、创建日期、大小、MIME 类型、GPS 坐标和其他属性。
在 Android 10 之前,开发者使用 READ_EXTERNAL_STORAGE 访问设备的所有文件。Android 10 (API 29) 引入了 Scoped Storage:应用程序只能访问自己的文件和通过 MediaStore 访问。Android 11 收紧了策略,完全阻止了共享目录的直接路径。
从 Android 13 (API 33) 开始,Google 用细粒度权限取代了 READ_EXTERNAL_STORAGE:READ_MEDIA_IMAGES、READ_MEDIA_VIDEO 和 READ_MEDIA_AUDIO。这允许用户只授予对特定媒体类型的访问权限,而无需暴露整个存储空间。
MediaStore 基于内容提供程序架构构建:每个应用程序通过 ContentResolver 和 Uri 访问它。系统媒体扫描器 — MediaScannerConnection — 在启动、USB 连接或重启时自动索引设备上的所有文件。
媒体数据库存储在系统数据库中,并为每个媒体文件包含记录。不同类型的列有所不同:图片有 ORIENTATION 和 DATE_TAKEN,视频有 DURATION,音频有 ARTIST 和 ALBUM。开发者可以通过带有 projection 和 selection 的 query 执行类似 SQL 的查询进行过滤。
val projection = arrayOf(
MediaStore.Images.Media._ID,
MediaStore.Images.Media.DISPLAY_NAME,
MediaStore.Images.Media.DATE_ADDED
)
val cursor = contentResolver.query(
MediaStore.Images.Media.EXTERNAL_CONTENT_URI,
projection,
null,
null,
MediaStore.Images.Media.DATE_ADDED + " DESC"
)
cursor?.use {
while (moveToNext()) {
val name = getString(getColumnIndexOrThrow(MediaStore.Images.Media.DISPLAY_NAME))
}
}
每个媒体文件由形式为 content://media/external/images/media/1234 的 Content URI 标识。外部 URI (external) 指向共享存储,内部 (internal) 指向系统媒体文件。使用 URI 代替文件路径 — MediaStore 的关键优势:应用程序不需要访问文件系统,而是通过安全的内容提供程序工作。
MediaStore 支持四种主要媒体类型,每种都有独立的表和元数据集。开发者根据应用程序处理的內容类型选择适当的表。
除了标准列之外,每个表还包含系统字段:_ID、DATA(已弃用)、SIZE、MIME_TYPE、DATE_ADDED、DATE_MODIFIED。从 Android 10 开始,DATA 字段被标记为 deprecated,开发者应通过根据 URI 打开 InputStream 来工作。
MediaStore 需要根据 Android 版本而不同的显式权限。在 Android 13 之前,使用单一的 READ_EXTERNAL_STORAGE 权限。从 Android 13 (API 33) 开始,Google 为每种媒体类型引入了细粒度权限。
| 媒体类型 | 权限 (API 33+) | 旧版 (API 29-32) |
|---|---|---|
| 图片 | READ_MEDIA_IMAGES | READ_EXTERNAL_STORAGE |
| 视频 | READ_MEDIA_VIDEO | READ_EXTERNAL_STORAGE |
| 音频 | READ_MEDIA_AUDIO | READ_EXTERNAL_STORAGE |
| 写入 | WRITE_EXTERNAL_STORAGE | WRITE_EXTERNAL_STORAGE |
写入 MediaStore 也需要 Android 9 及更低版本的 WRITE_EXTERNAL_STORAGE。从 Android 10 开始,应用程序可以在没有额外权限的情况下将自有文件写入 MediaStore — 系统在通过 ContentResolver.insert 插入记录时自动授予访问权限。
MediaStore 权限通过标准机制 ActivityResultContracts.RequestMultiplePermissions 请求。用户可能拒绝请求,应用程序应正确处理此场景。建议在每次访问 MediaStore 之前通过 ContextCompat.checkSelfPermission 检查权限是否存在。
MediaStore 不仅允许读取,还允许写入媒体文件。要写入图片或视频,开发者使用 ContentResolver.insert 并在返回的 URI 上打开 OutputStream。系统自动将文件添加到媒体数据库并索引它。
val values = ContentValues().apply {
put(MediaStore.Images.Media.DISPLAY_NAME, "photo_2025.jpg")
put(MediaStore.Images.Media.MIME_TYPE, "image/jpeg")
put(MediaStore.Images.Media.RELATIVE_PATH, "Pictures/MyApp")
}
val uri = contentResolver?.insert(
MediaStore.Images.Media.EXTERNAL_CONTENT_URI, values
)
uri?.let {
val outputStream = contentResolver?.openOutputStream(it)
outputStream?.use { stream ->
// 将字节写入流
}
}
删除通过 ContentResolver.delete 指定文件 URI 进行。系统检查访问权限:如果文件属于当前应用程序,删除无需额外权限。对于 Android 10+ 上其他应用程序的文件,需要通过系统对话框获得用户确认。
MediaStore API 与通过 File API 的直接文件访问有根本不同。使用 Content URI 代替文件路径,使用 ContentResolver 方法代替文件操作。这提供了三个关键优势:安全性、自动索引和统一接口。
在 Android 10+ 上,共享目录的直接文件访问 受到限制。MediaStore 仍然是从 Pictures、DCIM、Movies、Music 和 Download 读取媒体的唯一方式。对于应用程序自己的文件 (app-specific storage),直接访问仍保留 — 这些是 Android/data 和 Android/media 中的文件夹。
MediaStore 和直接访问之间的选择取决于内容类型。MediaStore 对于其他应用程序可访问的公共媒体文件是必需的。直接 File API 适用于应用程序内部文件和缓存。Storage Access Framework 用于通过系统选择器选择任意文档。
常见问题
MediaStore API — 是用于访问设备媒体文件(图片、视频、音频和文档)的 Android 系统内容提供程序。该 API 通过 ContentResolver 和自动索引所有文件的媒体数据库提供统一接口。
MediaStore 支持 Images(图片)、Video(视频)、Audio(音频)和 Files(文档)。每种类型都有独立的表和相关元数据集:图片有 ORIENTATION,视频有 DURATION,音频有 ARTIST。
在 Android 13+ 上使用细粒度权限:图片用 READ_MEDIA_IMAGES,视频用 READ_MEDIA_VIDEO,音频用 READ_MEDIA_AUDIO。用户可以只授予对特定媒体类型的访问权限。
要写入,创建带有名称和 MIME 类型的 ContentValues,调用 ContentResolver.insert 获取 URI,然后通过 ContentResolver.openOutputStream 打开 OutputStream。系统自动索引新文件。
MediaStore 通过媒体数据库提供对所有设备媒体文件的编程访问。Storage Access Framework 打开系统文件选择对话框并返回 URI — 用户选择特定文件或文件夹。
总结
我们将开发一款交钥匙移动应用程序
IT Sectr自2017年以来为初创企业和企业打造iOS和Android应用程序。我们将为您提供咨询并提出最佳解决方案。