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
元数据。
此外,您现在可以通过添加新的媒体格式、标记应编入索引的存储设备,甚至替换 MTP 堆栈来自定义 MediaProvider。有关详细信息,请参阅 自定义。
模块边界
Android 11 将 packages/providers/MediaProvider
中的所有代码迁移到一个新位置,但与 MTP 相关的逻辑除外。此外,frameworks/base/core/java/android/provider/MediaStore.java
现在位于 packages/providers/MediaProvider
的模块边界内。
软件包格式
MediaProvider 模块采用 APK-in-APEX 格式。
依赖项
MediaProvider 依赖项与自定义相关(也就是说,如果您自定义 MediaProvider,则必须确保您的实现满足与您的自定义相关的依赖项)。
当使用自定义或非标准媒体文件格式(例如,供应商特定的相机应用生成的格式)时,您必须向
MimeUtils
和媒体提取器模块注册每种自定义格式,以启用 MediaProvider 索引。要确保 MediaProvider 为
StorageManagerService
实现中使用的自定义存储设备集(例如 SD 卡插槽和 USB 端口)编制索引,请设置VolumeInfo.MOUNT_FLAG_INDEXABLE
标志。当使用自定义(非 AOSP)MTP 实现时,请确保该实现仅依赖于公共和系统 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 的功能
要验证 MediaStore 公共 API 的功能,请使用 Android 兼容性测试套件 (CTS) 的
CtsProviderTestCases
软件包中的测试。要验证 MediaProvider 内部的功能,请使用
MediaProviderTests
中的测试。
要一起运行这两组测试,请使用以下 atest
命令
atest --test-mapping packages/providers/MediaProvider