
随着时间的推移,Android 不断发展,现已支持各种存储设备类型和功能。所有 Android 版本均支持使用传统存储的设备,其中包括便携式存储和模拟存储。便携式存储可由物理介质(如 SD 卡或 USB 设备)提供,用于临时数据传输/文件存储。物理介质可能会在设备上保留较长时间,但它并非绑定到设备,可以移除。自 Android 1.0 起,SD 卡便已作为便携式存储提供;Android 6.0 添加了 USB 支持。模拟存储通过仿真层公开一部分内部存储空间来提供,并且自 Android 3.0 起便已提供。
从 Android 6.0 开始,Android 支持可采纳存储,这种存储由物理介质(如 SD 卡或 USB 设备)提供,经过加密和格式化后,其行为类似于内部存储空间。可采纳存储可以存储所有类型的应用数据。
权限
对外部存储空间的访问受各种 Android 权限的保护。从 Android 1.0 开始,写入权限受 WRITE_EXTERNAL_STORAGE
权限的保护。从 Android 4.1 开始,读取权限受 READ_EXTERNAL_STORAGE
权限的保护。
从 Android 4.4 开始,外部存储设备上文件的所有者、群组和模式现在根据目录结构合成。这使应用无需持有广泛的 WRITE_EXTERNAL_STORAGE
权限即可管理其在外部存储空间上的软件包专用目录。例如,软件包名称为 com.example.foo
的应用现在可以自由访问外部存储设备上的 Android/data/com.example.foo/
,而无需任何权限。这些合成权限是通过将原始存储设备封装在 FUSE 守护进程中来实现的。
从 Android 10 开始,以 Android 9 及更低版本为目标平台的应用默认使用旧版存储空间,并且可以选择启用隔离存储空间。以 Android 10 为目标平台且默认使用隔离存储空间的应用可以暂时选择停用隔离存储空间。使用清单属性 requestLegacyExternalStorage
(用于控制存储空间模型)来更改默认状态。
由于 READ_EXTERNAL_STORAGE
和 WRITE_EXTERNAL_STORAGE
权限均为软限制,因此,如果安装程序未将应用列入许可名单,则该权限仅控制对音频和视觉集合的访问权限,而无权访问 SD 卡。即使应用请求旧版存储空间,情况也是如此。如需详细了解硬限制和软限制,请参阅Android 10 中的硬限制和软限制。
如果安装程序将权限列入许可名单,则以旧版模式运行的应用将获得非隔离权限行为。该权限控制 SD 卡访问权限以及音频和视觉集合。当应用以 Android 9 或更低版本为目标平台且未选择启用隔离存储空间,或者以 Android 10 为目标平台且选择停用隔离存储空间时,就会发生这种情况。
许可名单状态只能在安装时指定,并且在应用安装后无法更改。
如需详细了解如何设置 READ_EXTERNAL_STORAGE
权限,请参阅 PackageInstaller.SessionParams 类中的 setWhitelistedRestrictedPermissions()
。
Android 13 引入了精细化媒体权限,以支持应用访问由其他应用创建的媒体文件。应用必须请求 精细化媒体权限中列出的一个或多个精细化媒体权限,而不是 READ_EXTERNAL_STORAGE
权限。
Android 14 基于精细化媒体权限构建,允许用户在应用请求媒体权限时授予对其视觉媒体库的部分访问权限。请参阅授予对照片和视频的部分访问权限以了解详情。
运行时权限
Android 6.0 引入了一种新的运行时权限模型,应用可在运行时根据需要请求功能。由于新模型包含 READ/WRITE_EXTERNAL_STORAGE
权限,因此平台需要动态授予存储空间访问权限,而无需终止或重启已在运行的应用。为此,平台会维护所有已装载存储设备的三种不同视图
/mnt/runtime/default
显示给没有特殊存储权限的应用,以及adbd
和其他系统组件所在的根命名空间。/mnt/runtime/read
显示给具有READ_EXTERNAL_STORAGE
的应用(为 Android 10 设置LEGACY_STORAGE
)/mnt/runtime/write
显示给具有WRITE_EXTERNAL_STORAGE
的应用
在 Zygote 分叉时,我们会为每个正在运行的应用创建一个装载命名空间,并将相应的初始视图绑定装载到位。稍后,当运行时权限获得授权后,vold
会跳转到已在运行的应用的装载命名空间中,并将升级后的视图绑定装载到位。请注意,权限降级始终会导致应用被终止。
用于实现此功能的 setns()
功能至少需要 Linux 3.8,但补丁程序已成功向后移植到 Linux 3.4。PermissionsHostTest
CTS 测试可用于验证内核行为是否正确。