MediaProvider 模块

MediaProvider 模块优化了索引元数据(来自 SD 卡和 USB 设备的音频、视频和图片),并通过 MediaStore 公共 API 使这些数据可供应用使用。为了维护用户隐私,MediaProvider 模块强制执行 Android 10 中引入的作用域存储安全模型,其中包括编辑敏感的位置元数据。此模块是可更新的,使 Android 能够更快地响应安全问题(保持敏感用户数据受到保护)并更快地添加新的媒体格式(为用户和开发者提供一致性)。

Android 10 中的变化

Android 10 引入了与识别和提取媒体文件数据相关的多项改进,特别是:

  • 使用文件 MIME 类型的第一部分确定文件内容类型。例如,操作系统知道 image/pngimage/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_ADDEDGENERATION_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