自 2025 年 3 月 27 日起,我们建议您使用 android-latest-release
而非 aosp-main
构建 AOSP 并为其做出贡献。如需了解详情,请参阅 AOSP 的变更。
传统存储设备
使用集合让一切井井有条
根据您的偏好保存内容并对其进行分类。
Android 支持采用传统存储的设备,传统存储是指具有不可变 POSIX 权限类和模式且不区分大小写的文件系统。传统存储设备的概念包括模拟和便携式存储设备。便携式存储设备是指系统未合并的任何外部存储设备,因此,未经格式化、加密或绑定到特定设备。由于传统的外部存储设备对存储的数据提供最低限度的保护,因此系统代码不应将敏感数据存储到外部存储设备中。具体来说,只能将配置和日志文件存储到可为其提供妥善保护的内部存储设备中。
多用户外部存储设备
从 Android 4.2 开始,设备可以支持多用户,且外部存储设备必须满足以下限制条件:
- 每个用户都必须有各自的独立主要外部存储设备,且不得访问其他用户的主要外部存储设备。
/sdcard
路径必须根据运行进程的用户身份解析到特定于该用户的正确主要外部存储设备。
Android/obb
目录中较大的 OBB 文件的存储可以在多个用户之间共享,以实现优化。
- 应用不得在次要外部存储设备写入内容,除非是在应用的软件包专属目录中(因为有合成权限)。
此功能的默认平台实现利用 Linux 内核命名空间,为每个由 Zygote 生成分支的进程创建独立的装载表,然后使用绑定装载向私有命名空间提供特定于用户的正确主要外部存储设备。
启动时,系统会在 EMULATED_STORAGE_SOURCE
(应用不可见)装载一个模拟的外部存储设备 FUSE 守护程序。Zygote 在创建分支之后,它会将 FUSE 守护程序下对应的用户专用子目录绑定装载到 EMULATED_STORAGE_TARGET
,以便应用能够正确访问外部存储路径。由于应用无法访问其他用户存储的装载点,它们只能访问启动该应用的用户存储空间。
该实现还使用共享的子树内核功能将装载事件从默认的根命名空间传播到应用命名空间中,从而确保 ASEC 容器和 OBB 装载等功能继续正常运行。它通过将 rootfs 装载为共享模式,然后在每个 Zygote 命名空间都创建好后重新将其装载为从属模式来实现。
多个外部存储设备
从 Android 4.4 开始,多个外部存储设备通过 Context.getExternalFilesDirs()
、Context.getExternalCacheDirs()
和 Context.getObbDirs()
提供给开发者。
通过这些 API 提供的外部存储设备必须是设备的半永久部件(如电池盒中的 SD 卡插槽)。开发者希望存储在这些位置的数据可供长期使用。因此,瞬态存储设备(如 USB 大容量存储驱动器)不应通过这些 API 提供。
WRITE_EXTERNAL_STORAGE
权限必须仅向在设备上的主要外部存储设备授予写入权限。不允许应用写入次要外部存储设备,除非是在应用的软件包专属目录中(因为有合成权限)。以这种方式限制写入可确保系统在应用被卸载时将文件清理干净。
Android 6.0 支持只需短时间内连接到设备的便携式存储设备,如 U 盘。当用户插入新的便携式设备时,该平台会显示一条通知,以让用户复制或管理相应设备上的内容。
在 Android 6.0 中,任何未合并的设备均被视为便携式设备。由于便携式存储设备只能短时间连接到设备,因此 Android 平台会避免执行媒体扫描之类的繁重操作。第三方应用必须通过存储访问框架与便携式存储设备中的文件进行交互;出于隐私和安全考虑,明确禁止直接访问。
本页面上的内容和代码示例受内容许可部分所述许可的限制。Java 和 OpenJDK 是 Oracle 和/或其关联公司的注册商标。
最后更新时间 (UTC):2025-07-27。
[[["易于理解","easyToUnderstand","thumb-up"],["解决了我的问题","solvedMyProblem","thumb-up"],["其他","otherUp","thumb-up"]],[["没有我需要的信息","missingTheInformationINeed","thumb-down"],["太复杂/步骤太多","tooComplicatedTooManySteps","thumb-down"],["内容需要更新","outOfDate","thumb-down"],["翻译问题","translationIssue","thumb-down"],["示例/代码问题","samplesCodeIssue","thumb-down"],["其他","otherDown","thumb-down"]],["最后更新时间 (UTC):2025-07-27。"],[],[],null,["# Traditional storage\n\nAndroid supports devices with traditional storage, which is defined to be a\ncase-insensitive filesystem with immutable POSIX permission classes and modes.\nThe notion of traditional storage encompasses emulated and portable storage.\nPortable storage is defined as any external storage that is not [adopted](/docs/core/storage/adoptable) by the\nsystem and therefore not formatted and encrypted or tied to a specific device.\nBecause traditional external storage offers minimal protection for stored data,\nsystem code should not store sensitive data on external storage. Specifically,\nconfiguration and log files should only be stored on internal storage where\nthey can be effectively protected.\n\nMulti-user external storage\n---------------------------\n\nStarting in Android 4.2, devices can support multiple users, and external\nstorage must meet the following constraints:\n\n- Each user must have their own isolated primary external storage, and must not have access to the primary external storage of other users.\n- The `/sdcard` path must resolve to the correct user-specific primary external storage based on the user a process is running as.\n- Storage for large OBB files in the `Android/obb` directory may be shared between multiple users as an optimization.\n- Secondary external storage must not be writable by apps, except in package-specific directories as allowed by synthesized permissions.\n\nThe default platform implementation of this feature leverages Linux kernel\nnamespaces to create isolated mount tables for each Zygote-forked process,\nand then uses bind mounts to offer the correct user-specific primary external\nstorage into that private namespace.\n\nAt boot, the system mounts a single emulated external storage FUSE daemon\nat `EMULATED_STORAGE_SOURCE`, which is hidden from apps. After\nthe Zygote forks, it bind mounts the appropriate user-specific subdirectory\nfrom under the FUSE daemon to `EMULATED_STORAGE_TARGET` so that\nexternal storage paths resolve correctly for the app. Because an app lacks\naccessible mount points for other users' storage, they can only access\nstorage for the user it was started as.\n\nThis implementation also uses the shared subtree kernel feature to\npropagate mount events from the default root namespace into app namespaces,\nwhich ensures that features like ASEC containers and OBB mounting continue\nworking correctly. It does this by mounting the rootfs as shared, and then\nremounting it as slave after each Zygote namespace is created.\n\nMultiple external storage devices\n---------------------------------\n\nStarting in Android 4.4, multiple external storage devices are surfaced\nto developers through `Context.getExternalFilesDirs()`,\n`Context.getExternalCacheDirs()`, and\n`Context.getObbDirs()`.\n\n\u003cbr /\u003e\n\nExternal storage devices surfaced through these APIs must be a semi-permanent part of the device (such as an SD card slot in a battery compartment). Developers expect data stored in these locations to be available over long periods of time. For this reason, transient storage devices (such as USB mass storage drives) should not be surfaced through these APIs.\n\n\u003cbr /\u003e\n\nThe `WRITE_EXTERNAL_STORAGE` permission must only grant write\naccess to the primary external storage on a device. Apps must not be\nallowed to write to secondary external storage devices, except in their\npackage-specific directories as allowed by synthesized\npermissions. Restricting writes in this way ensures the system can clean\nup files when applications are uninstalled.\n\nUSB media support\n-----------------\n\nAndroid 6.0 supports portable storage devices which are only connected to the\ndevice for a short period of time, like USB flash drives. When a user inserts a\nnew portable device, the platform shows a notification to let them copy or\nmanage the contents of that device.\n\nIn Android 6.0, any device that is not adopted is considered portable. Because\nportable storage is connected for only a short time, the platform avoids heavy\noperations such as media scanning. Third-party apps must go through the [Storage Access Framework](https://developer.android.com/guide/topics/providers/document-provider.html) to interact with files on portable storage; direct access is explicitly\nblocked for privacy and security reasons."]]