Storage

Значок HAL внешнего хранилища Android

Со временем Android стал поддерживать самые разные типы устройств хранения данных и их функции. Все версии Android поддерживают устройства с традиционным хранилищем, в том числе переносным и эмулируемым. Портативное хранилище может быть представлено физическими носителями, такими как SD-карта или USB-накопитель, которые предназначены для временной передачи данных или хранения файлов. Физический носитель может оставаться в устройстве в течение длительного времени, но он не привязан к устройству и может быть извлечен. SD-карты доступны в качестве съемного накопителя с Android 1.0, а поддержка USB-накопителей была добавлена в Android 6.0. Эмулируемое хранилище предоставляется путем предоставления части внутренней памяти через уровень эмуляции и доступно начиная с 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, рассказывается в разделе setWhitelistedRestrictedPermissions() класса PackageInstaller.SessionParams.

В Android 13 появились детализированные разрешения на доступ к медиаконтенту, которые позволяют приложениям получать доступ к медиафайлам, созданным другими приложениями. Приложения должны запрашивать одно или несколько детализированных разрешений на доступ к медиафайлам, перечисленных в разделе Детализированные разрешения на доступ к медиафайлам, вместо разрешения READ_EXTERNAL_STORAGE.

В Android 14 реализованы детализированные разрешения на доступ к медиаконтенту, которые позволяют пользователям предоставлять приложениям частичный доступ к своей библиотеке изображений и видео. Подробнее о том, как предоставить частичный доступ к фотографиям и видео…

Динамические разрешения

В Android 6.0 представлена новая модель разрешений во время выполнения, в которой приложения запрашивают доступ к функциям по мере необходимости. Поскольку новая модель включает разрешения READ/WRITE_EXTERNAL_STORAGE, платформе необходимо динамически предоставлять доступ к хранилищу, не завершая и не перезапуская уже запущенные приложения. Для этого используются три разных представления всех подключенных устройств хранения данных:

  • /mnt/runtime/default показывается приложениям без специальных разрешений на хранение данных, а также в корневом пространстве имен, где находятся adbd и другие системные компоненты.
  • /mnt/runtime/read показывается в приложениях с READ_EXTERNAL_STORAGE (установите LEGACY_STORAGE для Android 10).
  • /mnt/runtime/write показывается в приложениях с WRITE_EXTERNAL_STORAGE.

Во время разветвления Zygote мы создаем пространство имен для каждой запущенной программы и монтируем в него подходящее начальное представление. Когда разрешения на выполнение будут предоставлены, vold перейдет в пространство имен точки монтирования уже запущенных приложений и привяжет обновленное представление. Обратите внимание, что понижение уровня разрешений всегда приводит к принудительному закрытию приложения.

Для работы функции setns() требуется Linux 3.8 или более поздней версии, но исправления были успешно перенесены в Linux 3.4. Тест PermissionsHostTest CTS можно использовать для проверки правильности работы ядра.