用 Android 手机的朋友,对于微信选图发朋友圈的体验可能都颇有微词:缩略图的来源太多太杂了。取决于你手机的生态环境,微信照片选择器里的图片可能来自修图工具,也可能来自系统相机,甚至可能卡组是微博的图片保存路径、系统的下载目录……
当然,这个问题不只限于微信,在微博等很多常用应用中,情况也是类似。
那么,Android 照片选择器的这个问题是如何产生的,又是否能得到解决呢?这事还得从很久以前说起……
前 Android 10 时代:自由放任
在任何一台 Android 设备上打开文件管理器,你都会看到一些固定名称的目录,例如:
- 图片(包括照片和屏幕截图),对应
DCIM/
和Pictures/
目录; - 视频,对应
DCIM/
、Movies/
和Pictures/
目录; - 音频文件,对应
Alarms/
、Audiobooks/
、Music/
、Notifications/
、Podcasts/
和Ringtones/
目录; - 下载的文件,对应
Download/
目录。
从 Android 的最早时期起,系统就会索引这些固定路径。如果应用需要获取这些类型的文件列表,无需自己扫描,通过 MediaProvider 媒体模块和 MediaStore API 就能获得。
这套基于路径的媒体文件索引机制,是 Android 照片选择器的设计基石,除非——
根本没什么人用。
早年,大多数应用为了获取媒体文件,都选择「另辟蹊径」,申请整个外部存储空间的读写权限(READ_EXTERNAL_STORAGE
),然后自己从中提取文件。而当时,Android 的权限管理机制又很粗疏,外部存储空间的读写只有「全有」或「全无」两种状态。
这就导致了两个问题:
- 应用列出的媒体文件可能来自外部存储的各个角落,其中包含很多并不需要列出的内容,例如缓存的缩略图、应用资源等;
- 任何以访问媒体文件名义获得存储权限的应用,都变成了事实上的「文件管理器」,这给很多侵犯隐私的恶劣做法提供了温床,例如将敏感信息存放在外部存储中供另一应用取用。
Android 10—12:渐有起色
这种情况直到 Android 10 才开始好转。在 Android 10 开发者预览版中,Google 引入了一项称为分区存储(scoped storage)的「沙盒」机制,使得应用只能访问它们自己创建的外部存储路径中的文件,而不能随意访问其他应用的专用存储目录。相应地,「读写外部存储空间」权限也被更名为「访问文件和媒体」,媒体文件访问的规范化就此开始。