自 2025 年 3 月 27 日起,我们建议您使用 android-latest-release
而非 aosp-main
构建 AOSP 并为其做出贡献。如需了解详情,请参阅 AOSP 的变更。
MediaProvider 模块
使用集合让一切井井有条
根据您的偏好保存内容并对其进行分类。
MediaProvider 模块可优化编入索引的元数据(来自 SD 卡和 USB 设备的音频、视频和图片),并通过 MediaStore 公共 API 将这些数据提供给应用。为了维护用户隐私,MediaProvider 模块强制采用 Android 10 中引入的分区存储安全模型,其中包括隐去敏感的位置元数据。此模块是可更新的,因此 Android 可以更快地应对安全问题(保护敏感的用户数据),而且还能更快地添加新媒体格式(为用户和开发者提供一致性)。
Android 10 中的变化
Android 10 引入了几项与识别和提取媒体文件中的数据相关的改进,具体说明如下:
使用文件的 MIME 类型的第一部分来确定文件内容类型。例如,操作系统知道 image/png
和 image/x-newly-invented-format
都是图片,因此可以准确地向最终用户描述相关权限。
仅使用文件扩展名来确定 MIME 类型(而不使用内容嗅探功能,以避免安全问题)。
使用上游 Debian Linux 和 Android 映射的组合来确定任意文件的 MIME 类型。
从 video/*
和 audio/*
文件(通过 MediaMetadataRetriever
)以及 image/*
文件(通过 ExifInterface
)返回相关数据。
Android 11 中的变化
在 Android 11 中,MediaProvider 模块基于在 Android 10 中做出的更改构建,并且进行了以下改进:
改进了索引编制。现在,MediaProvider 模块通过对照 MediaStore 公共 API 协调可用的元数据来将元数据编入索引。更改包括:
新增了 is_favorite
列和 QUERY_ARG_MATCH_FAVORITE
参数,可让图库式应用根据此列快速过滤媒体。
将颜色空间元数据编入索引。
新增了“is_trashed”列和 QUERY_ARG_MATCH_TRASHED
参数,可让图库式应用根据此列过滤。
新增了 API,支持通过单个用户对话框提示来批量修改多项内容,包括 createDeleteRequest()
、createFavoriteRequest()
、createTrashRequest()
和 createWriteRequest()
。
新增了 GENERATION_ADDED
和 GENERATION_MODIFIED
列,用于快速可靠地检测自上一个同步点以来发生的更改。
新增了 GROUP BY
公共 API,用于上文未提及的其他元数据列。
改进了 ExifInterface
,以从 PNG 和 WebP 容器中提取元数据。
改进了 SystemUI
,以将 DateTimeOriginal
元数据写入屏幕截图。
此外,您现在还可以自定义 MediaProvider,方法是添加新的媒体格式、标记应将哪些存储设备编入索引,甚至替换 MTP 堆栈。如需了解详情,请参阅自定义。
模块边界
Android 11 将 packages/providers/MediaProvider
中的所有代码迁移到了一个新位置,但与 MTP 相关的逻辑是一个值得注意的特例。此外,frameworks/base/core/java/android/provider/MediaStore.java
现在位于 packages/providers/MediaProvider
处的模块边界内。
MediaProvider 模块采用“APEX 中的 APK”格式。
依赖项
MediaProvider 依赖项与自定义相关(也就是说,如果您自定义 MediaProvider,则必须确保实现满足与自定义关联的依赖项要求)。
使用自定义或非标准媒体文件格式(例如,由供应商专属相机应用生成的格式)时,您必须向 MimeUtils
和媒体提取器模块注册每种自定义格式,以便让 MediaProvider 将相应内容编入索引。
如需确保 MediaProvider 将 StorageManagerService
实现中使用的一组自定义存储设备(如 SD 卡插槽和 USB 端口)编入索引,请设置 VolumeInfo.MOUNT_FLAG_INDEXABLE
标志。
使用自定义(非 AOSP)MTP 实现时,请确保该实现仅依赖于公共 API 和系统 API,以使其能够与 MediaStore 进行交互。
自定义
您现在可以添加新的媒体格式、控制将哪些存储设备编入索引,以及替换 MTP 堆栈。
自定义媒体格式 - 对于每种新的自定义媒体格式,您必须提供从唯一文件扩展名到 MIME 类型的映射。我们强烈建议您遵循 IANA 注册流程。
您无法重新定义已在 AOSP 中定义的扩展名或 MIME 类型。
对于 video/*
和 audio/*
文件,MediaProvider 继续咨询 MediaMetadataRetriever
。您可以使用 Android 10 媒体提取器返回自定义格式的元数据。
对于 image/*
文件,MediaProvider 继续对 Exif
元数据进行标准化。您可以扩展 android.media.ExifInterface
以提取并返回任何自定义图片格式的 Exif
元数据。
存储设备编入索引标志 - MediaProvider 会将 StorageManager.getStorageVolumes()
返回的所有卷(其中,StorageVolume.getMediaStoreVolumeName()
为非 null 值)编入索引。您可以自定义返回的卷列表以控制将哪些卷编入索引,但我们建议不要包含瞬态卷(如 USB OTG 驱动器)。
MTP 堆栈替换 - Android 11 将 MTP 堆栈完全放置在模块边界之外,并确保它对照公共 API 运行。
测试
您可以使用以下测试来验证 MediaProvider 的功能:
如需同时运行这两组测试,请使用以下 atest
命令:
atest --test-mapping packages/providers/MediaProvider
本页面上的内容和代码示例受内容许可部分所述许可的限制。Java 和 OpenJDK 是 Oracle 和/或其关联公司的注册商标。
最后更新时间 (UTC):2025-03-26。
[[["易于理解","easyToUnderstand","thumb-up"],["解决了我的问题","solvedMyProblem","thumb-up"],["其他","otherUp","thumb-up"]],[["没有我需要的信息","missingTheInformationINeed","thumb-down"],["太复杂/步骤太多","tooComplicatedTooManySteps","thumb-down"],["内容需要更新","outOfDate","thumb-down"],["翻译问题","translationIssue","thumb-down"],["示例/代码问题","samplesCodeIssue","thumb-down"],["其他","otherDown","thumb-down"]],["最后更新时间 (UTC):2025-03-26。"],[],[],null,["# MediaProvider module\n\nThe MediaProvider module optimizes indexed metadata (audio, video, and images\nfrom SD cards and USB devices) and makes that data available to apps through the\n[MediaStore public\nAPIs](https://developer.android.com/reference/android/provider/MediaStore).\nTo maintain user privacy, the MediaProvider module enforces the [scoped storage\nsecurity\nmodel](https://developer.android.com/training/data-storage/files/external-scoped)\nintroduced in Android 10, which includes redacting sensitive location metadata.\nThis module is updatable, enabling Android to respond faster to security issues\n(keeping sensitive user data protected) and add new media formats quicker\n(providing consistency to both users and developers).\n\nChanges in Android 10\n---------------------\n\nAndroid 10 introduced several improvements related to identifying and extracting\ndata from media files, specifically:\n\n- Determining the file content type using the first part of a file's MIME type.\n For example, the OS knows that both `image/png` and\n `image/x-newly-invented-format` are images, and can thus accurately describe\n relevant permissions to the end user.\n\n- Determining the MIME type using only the file extension (and without using\n [content sniffing](https://en.wikipedia.org/wiki/Content_sniffing)\n to avoid security issues).\n\n- Determining the MIME type of an arbitrary file using a combination of\n [upstream Debian Linux and Android\n mappings](https://android-review.googlesource.com/c/platform/libcore/+/735506).\n\n- Returning relevant data from `video/*` and `audio/*` files (via\n `MediaMetadataRetriever`) and `image/*` files (via `ExifInterface`).\n\nChanges in Android 11\n---------------------\n\nIn Android 11, the MediaProvider module builds on the\nchanges made in Android 10 with the following improvements:\n\n- Improvements to indexing. The MediaProvider module now indexes metadata by\n reconciling available metadata against MediaStore public APIs. Changes\n include:\n\n - New `is_favorite` column and `QUERY_ARG_MATCH_FAVORITE` argument to enable\n gallery-style apps to quickly filter media based on this column.\n\n - Indexing color space metadata.\n\n - New 'is_trashed' column and `QUERY_ARG_MATCH_TRASHED` argument to enable\n gallery-style apps to filter based on this column.\n\n - New APIs that enable bulk-modification of multiple items with a single user\n dialog prompt, including `createDeleteRequest()`, `createFavoriteRequest()`,\n `createTrashRequest()`, and `createWriteRequest()`.\n\n - New `GENERATION_ADDED` and `GENERATION_MODIFIED` columns for use in quickly\n and reliably detecting changes that have occurred since a previous\n synchronization point.\n\n - New `GROUP BY` public API for use with additional metadata columns not\n mentioned above.\n\n- Improvement to `ExifInterface` to extract metadata from PNG and WebP\n containers.\n\n- Improvements to `SystemUI` to write `DateTimeOriginal` metadata in screen\n captures.\n\nIn addition, you can now customize MediaProvider by adding new media formats,\nmarking which storage devices should be indexed, and even replacing the MTP\nstack. For details, see [Customization](#customization).\n\nModule boundary\n---------------\n\nAndroid 11 migrates all code in\n`packages/providers/MediaProvider` to a new location, with the notable exception\nof MTP-related logic. In addition,\n`frameworks/base/core/java/android/provider/MediaStore.java` is now *inside* the\nmodule boundary at `packages/providers/MediaProvider`.\n\nPackage format\n--------------\n\nThe MediaProvider module is in APK-in-APEX format.\n\nDependencies\n------------\n\nMediaProvider dependencies are related to [customizations](#customization) (that\nis, if you customize MediaProvider, you must ensure your implementation meets\nthe dependency associated with your customization).\n\n- When using custom or nonstandard media file formats (for example, a format\n generated by a vendor-specific Camera app), you must register each custom\n format with `MimeUtils` and the Media Extractor module to enable indexing by\n MediaProvider.\n\n- To ensure MediaProvider indexes a custom set of storage devices (such SD card\n slots and USB ports) used in a `StorageManagerService` implementation, set the\n `VolumeInfo.MOUNT_FLAG_INDEXABLE` flag.\n\n- When using a custom (non-AOSP) MTP implementation, ensure the implementation\n relies solely on public and system APIs to enable the implementation to\n interact with MediaStore.\n\nCustomization\n-------------\n\nYou can now add new media formats, influence which storage devices are indexed,\nand replace the MTP stack.\n\n- **Custom media formats.** For each new custom media format, you must provide a\n mapping from the unique file extension to a MIME type. We strongly encourage\n you to follow the [IANA registration\n process](https://www.iana.org/assignments/media-types/media-types.xhtml).\n\n - You can't redefine an extension or MIME type that's already defined in AOSP.\n\n - For `video/*` and `audio/*` files, MediaProvider continues consulting\n `MediaMetadataRetriever`. Use the Android 10 Media Extractors to return\n metadata for custom formats.\n\n - For `image/*` files, MediaProvider continues standardizing on `Exif` for\n metadata. You can extend `android.media.ExifInterface` to extract and return\n `Exif` metadata for any custom image formats.\n\n- **Storage devices indexing flag.** MediaProvider indexes all volumes returned\n by `StorageManager.getStorageVolumes()` where\n `StorageVolume.getMediaStoreVolumeName()` is non-null. You can customize the\n list of volumes returned to influence what is indexed, but we advise against\n including transient volumes (such as USB OTG drives).\n\n- **MTP stack replacement.** Android 11 places the MTP\n stack entirely outside the module boundary and ensures that it works against\n public APIs.\n\nTesting\n-------\n\nYou can verify the functionality of MediaProvider using the following tests:\n\n- To verify the functionality of MediaStore public APIs, use tests in the\n `CtsProviderTestCases` package of the Android Compatibility Test Suite (CTS).\n\n- To verify the functionality of MediaProvider internals, use tests in\n `MediaProviderTests`.\n\nTo run both sets of tests together, use the following `atest` command: \n\n atest --test-mapping packages/providers/MediaProvider"]]