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 的功能:
如需验证 MediaStore 公共 API 的功能,请使用 Android 兼容性测试套件 (CTS) 的
CtsProviderTestCases
软件包中的测试。如需验证 MediaProvider 内部构件的功能,请使用
MediaProviderTests
中的测试。
如需同时运行这两组测试,请使用以下 atest
命令:
atest --test-mapping packages/providers/MediaProvider