Android 使用的文件系统与在其他平台上的基于磁盘的文件系统类似。系统提供多种选项供您保存应用数据:
- 应用专属存储空间:存储仅供您的应用使用的文件,既可以存储在内部存储卷中的专用目录中,也可以存储在外部存储中的不同专用目录中。使用内部存储中的目录保存其他应用不应访问的敏感信息。
- 共享存储空间:存储您的应用打算与其他应用共享的文件,包括媒体、文档和其他文件。
- 偏好设置:以键值对的形式存储私有、基本数据。
- 数据库:使用 Room 持久性库在私有数据库中存储结构化数据。
这些选项的特征总结在下表中:
内容类型 | 访问方法 | 所需权限 | 其他应用可以访问吗? | 应用卸载时文件会删除吗? | |
---|---|---|---|---|---|
应用专属文件 | 仅供您的应用使用的文件 | 从内部存储,getFilesDir() 或 getCacheDir() 从外部存储, getExternalFilesDir() 或 getExternalCacheDir() |
内部存储绝不需要 当您的应用在运行 Android 4.4 (API level 19) 或更高版本的设备上使用时,外部存储不需要 |
否 | 是 |
媒体 | 可共享媒体文件(图片、音频文件、视频) | MediaStore API |
在 Android 11 (API level 30) 或更高版本上访问其他应用文件时,需要 READ_EXTERNAL_STORAGE 在 Android 10 (API level 29) 上访问其他应用文件时,需要 READ_EXTERNAL_STORAGE 或 WRITE_EXTERNAL_STORAGE 在 Android 9 (API level 28) 或更低版本上,所有文件都需要权限 |
是,但其他应用需要 READ_EXTERNAL_STORAGE 权限 |
否 |
文档及其他文件 | 其他类型的可共享内容,包括下载的文件 | 存储访问框架 | 无 | 是,通过系统文件选择器 | 否 |
应用偏好设置 | 键值对 | Jetpack Preferences 库 | 无 | 否 | 是 |
数据库 | 结构化数据 | Room 持久性库 | 无 | 否 | 是 |
您选择的解决方案取决于您的具体需求:
- 您的数据需要多少空间?
- 内部存储空间对于应用专属数据来说是有限的。如果您需要保存大量数据,请使用其他类型的存储。
- 数据访问的可靠性要求有多高?
- 如果您的应用的基本功能需要某些数据,例如在应用启动时,请将数据放在内部存储目录或数据库中。存储在外部存储中的应用专属文件并非始终可访问,因为某些设备允许用户移除与外部存储对应的物理设备。
- 您需要存储什么类型的数据?
- 如果您有只对您的应用有意义的数据,请使用应用专属存储。对于可共享的媒体内容,请使用共享存储,以便其他应用可以访问该内容。对于结构化数据,请使用偏好设置(用于键值数据)或数据库(用于包含两列以上的数据)。
- 数据应该对您的应用私有吗?
- 存储敏感数据(其他任何应用都无法访问的数据)时,请使用内部存储、偏好设置或数据库。内部存储的额外好处是数据对用户隐藏。
存储位置类别
Android 提供两种物理存储位置:内部存储和外部存储。在大多数设备上,内部存储小于外部存储。但是,内部存储在所有设备上始终可用,使其成为放置您的应用所依赖数据的更可靠的地方。
可移动卷(例如 SD 卡)在文件系统中显示为外部存储的一部分。Android 使用路径(例如 /sdcard
)表示这些设备。
应用本身默认存储在内部存储中。但是,如果您的 APK 大小非常大,您可以在应用的清单文件中指明偏好,改为将应用安装到外部存储上。
<manifest ... android:installLocation="preferExternal"> ... </manifest>
权限和外部存储访问
Android 定义了以下与存储相关的权限:READ_EXTERNAL_STORAGE
、WRITE_EXTERNAL_STORAGE
和 MANAGE_EXTERNAL_STORAGE
。
在早期版本的 Android 中,应用需要声明 READ_EXTERNAL_STORAGE
权限才能访问外部存储上 应用专属目录之外的任何文件。此外,应用需要声明 WRITE_EXTERNAL_STORAGE
权限才能写入应用专属目录之外的任何文件。
较新版本的 Android 更侧重于文件的用途而非位置,来确定应用访问和写入给定文件的能力。特别是,如果您的应用以 Android 11 (API level 30) 或更高版本为目标平台,则 WRITE_EXTERNAL_STORAGE
权限对您应用访问存储空间没有任何影响。这种基于用途的存储模型提高了用户隐私,因为应用仅被授予对设备文件系统实际使用的区域的访问权限。
Android 11 引入了 MANAGE_EXTERNAL_STORAGE
权限,该权限提供对应用专属目录和 MediaStore
之外的文件的写入权限。要了解有关此权限以及为何大多数应用不需要声明此权限即可满足其用例的更多信息,请参阅有关如何在存储设备上管理所有文件的指南。
分区存储
为了让用户更好地控制其文件并限制文件混乱,默认情况下,以 Android 10 (API level 29) 及更高版本为目标平台的应用被授予对外部存储的分区访问权限,即分区存储。此类应用只能访问外部存储上的应用专属目录,以及应用创建的特定类型的媒体。
除非您的应用需要访问存储在应用专属目录之外以及 MediaStore
API 无法访问的目录之外的文件,否则请使用分区存储。如果您将应用专属文件存储在外部存储中,可以通过将这些文件放置在外部存储上的应用专属目录中来更轻松地采用分区存储。这样,当启用分区存储时,您的应用仍能访问这些文件。
为了使您的应用适应分区存储,请查看存储用例和最佳实践指南。如果您的应用有分区存储未涵盖的其他用例,请提交功能请求。您可以暂时选择退出使用分区存储。
查看设备上的文件
要查看设备上存储的文件,请使用 Android Studio 的设备文件浏览器。
其他资源
有关数据存储的更多信息,请查阅以下资源。