Внешнее хранилище на мобильных устройствах — это сменный носитель данных, доступ к которому может получить любое приложение с соответствующими разрешениями. По данным Android Open Source Project, 2026, начиная с Android 10 Google внедрил Scoped Storage — модель, которая ограничивает прямой доступ к файловой системе и требует использования MediaStore API для работы с общими медиафайлами. Такой подход повышает безопасность пользовательских данных и предотвращает утечку информации между приложениями.
Главное
READ_EXTERNAL_STORAGE и WRITE_EXTERNAL_STORAGE обязательны для Android 9 и нижеВнешнее хранилище — это область памяти, которая не входит в защищённую песочницу приложения и доступна другим программам. На Android под этим термином обычно понимают SD-карту, но к внешнему хранилищу также относятся USB-накопители, подключённые через OTG-адаптер, и облачные диски, интегрированные на уровне файловой системы. Главное отличие от Internal Storage — отсутствие изоляции: файлы во внешнем хранилище может читать и изменять любое приложение, получившее соответствующие разрешения.
На Android внешнее хранилище представлено двумя основными режимами: переносное (portable) и внутреннее (adoptable). При форматировании SD-карты как переносного хранилища она остаётся съёмной и форматируется в FAT32 или exFAT. В режиме adoptable storage карта форматируется в ext4 и шифруется с использованием AES-128, после чего система воспринимает её как расширение внутренней памяти. Режим adoptable доступен начиная с Android 6.0 Marshmallow, но производители устройств часто отключают эту возможность в своих прошивках. Согласно статистике Google Play Console, только около 12% Android-устройств поддерживают adoptable storage, поэтому полагаться на расширение внутренней памяти через SD-карту в качестве единственного варианта не рекомендуется.
На iOS традиционных SD-карт нет. Apple использует закрытую архитектуру, где всё хранение строится на внутренней флеш-памяти и iCloud. Внешние накопители поддерживаются через Lightning или USB-C порт, но доступ к ним ограничен системным файловым менеджером Files и приложениями, которые интегрируются с Document Picker. Пользователь сам решает, какие файлы открывать из внешнего источника — приложение не может сканировать подключённый накопитель без явного согласия.
Выбор внешнего носителя зависит от требований к скорости, объёму и портативности. Разные типы носителей имеют различные скоростные характеристики, файловые системы и сценарии использования в мобильных приложениях.
| Тип носителя | Макс. объём | Скорость чтения | Файловая система |
|---|---|---|---|
| SD UHS-I | 2 ТБ | до 104 МБ/с | exFAT / FAT32 |
| SD UHS-II | 2 ТБ | до 312 МБ/с | exFAT / FAT32 |
| USB 3.0 OTG | 2 ТБ | до 400 МБ/с | exFAT / NTFS / FAT32 |
| USB-C SSD | 4 ТБ | до 1000 МБ/с | exFAT / APFS / NTFS |
SD-карты классифицируются по скорости записи: Class 10 (10 МБ/с), U1 (10 МБ/с), U3 (30 МБ/с), V30 (30 МБ/с) и V90 (90 МБ/с). Для записи видео 4K требуется карта не ниже U3 или V30. Для мобильных приложений, работающих с большими медиафайлами (обработка фото, видеомонтаж), рекомендуется использовать карты класса U3 и выше. Скорость карты напрямую влияет на производительность приложения: запись 4K-видео на карту Class 10 может вызывать пропуск кадров из-за недостаточной пропускной способности. При выборе SD-карты для приложения обращайте внимание не только на класс скорости, но и на рейтинг Application Performance Class: A1 и A2 указывают на минимальную производительность случайного чтения и записи, критичную для работы баз данных и кэша приложений.
USB-OTG (On-The-Go) позволяет подключать к мобильному устройству внешние USB-накопители через переходник. Android поддерживает OTG начиная с версии 3.1, но для монтирования накопителя требуется ядро с поддержкой файловой системы. FAT32 и exFAT поддерживаются из коробки, NTFS — только на устройствах с кастомным ядром или через библиотеку Paragon. На iOS поддержка USB-накопителей появилась в iOS 13 вместе с приложением Files. Для работы с накопителем приложение должно использовать UIDocumentPickerViewController, который открывает доступ только к выбранным пользователем файлам — полный доступ к файловой системе накопителя iOS не предоставляет.
Облачные сервисы — iCloud, Google Drive, Dropbox — могут интегрироваться в файловую систему устройства через системные провайдеры. На iOS iCloud Drive является частью Sandbox-контейнера приложения, и файлы автоматически синхронизируются между устройствами пользователя. На Android Google Drive предоставляет API для чтения и записи файлов, но прямого монтирования в файловую систему не происходит. Для мобильных приложений, работающих с большими объёмами данных, облачное хранилище может служить альтернативой SD-карте, особенно на устройствах без слота расширения.
Работа с внешним хранилищем на Android зависит от версии операционной системы и модели Scoped Storage. Процесс доступа к файлам различается для Android 9 и ниже, Android 10–12 и Android 13+.
Начиная с Android 10, основной способ доступа к общим медиафайлам — MediaStore API. Этот API предоставляет унифицированный интерфейс для чтения и записи изображений, видео и аудиофайлов в общем хранилище. Приложение не требует разрешения READ_EXTERNAL_STORAGE для доступа к собственным файлам, но для чтения файлов других приложений по-прежнему нужно явное разрешение пользователя. MediaStore автоматически индексирует медиафайлы и предоставляет ContentResolver для их запроса.
val collection = if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q) {
MediaStore.Images.Media.getContentUri(MediaStore.VOLUME_EXTERNAL_PRIMARY)
} else {
MediaStore.Images.Media.EXTERNAL_CONTENT_URI
}
val projection = arrayOf(
MediaStore.Images.Media._ID,
MediaStore.Images.Media.DISPLAY_NAME
)
val cursor = contentResolver.query(collection, projection, null, null, null)
После выполнения запроса вы получаете Cursor, содержащий URI файлов. Для чтения файла откройте InputStream через contentResolver.openInputStream(uri). Запись выполняется аналогично через contentResolver.openOutputStream(uri). MediaStore автоматически обрабатывает конфликты имён и предоставляет возможность вставки новых файлов через contentResolver.insert(uri, values), который возвращает URI созданного файла.
Storage Access Framework (SAF) — рекомендованный способ доступа к произвольным файлам на Android 10+. SAF предоставляет системный диалог выбора файлов, через который пользователь даёт приложению доступ к конкретному файлу или директории. Приложение получает URI доступа, который действует до перезагрузки устройства или до явного отзыва разрешения через настройки. SAF не требует разрешений READ_EXTERNAL_STORAGE или WRITE_EXTERNAL_STORAGE, что упрощает публикацию в Google Play и снижает количество запросов разрешений.
val requestCode = 42
val intent = Intent(Intent.ACTION_OPEN_DOCUMENT_TREE)
intent.addFlags(
Intent.FLAG_GRANT_READ_URI_PERMISSION
or Intent.FLAG_GRANT_WRITE_URI_PERMISSION
)
startActivityForResult(intent, requestCode)
На iOS работа с внешними файлами строится через UIDocumentPickerViewController, который пользователь открывает для выбора конкретных файлов или директорий. Приложение не имеет прямого доступа к файловой системе внешнего накопителя — только к тем файлам, которые пользователь явно выбрал. После выбора файла приложение получает временный URL-адрес в Sandbox-контейнере и может работать с файлом через FileManager.
UIDocumentPickerViewController позволяет пользователю выбрать один или несколько файлов из любого доступного источника: iCloud Drive, подключённого USB-накопителя, стороннего облачного сервиса. После выбора контроллер возвращает массив URL-адресов, которые приложение может прочитать в течение сессии. Для сохранения доступа после закрытия приложения необходимо вызвать startAccessingSecurityScopedResource() и сохранить security-scoped bookmark в UserDefaults.
let picker = UIDocumentPickerViewController(
forOpeningContentTypes: [.data, .image],
asCopy: true
)
picker.delegate = self
func documentPicker(
controller: UIDocumentPickerViewController,
didPickDocumentsAt urls: [URL]
) {
guard let url = urls.first else { return }
let data = try Data(contentsOf: url)
}
Параметр asCopy: true означает, что iOS скопирует файл в Sandbox-контейнер приложения, и приложение получит собственную копию, независимую от исходного файла. Если указать asCopy: false, приложение получает ссылку на оригинальный файл, но для доступа к нему необходимо вызвать url.startAccessingSecurityScopedResource(). Без этого вызова чтение файла вызовет исключение. После завершения работы с файлом обязательно вызовите url.stopAccessingSecurityScopedResource(), чтобы закрыть ресурс и предотвратить утечку дескрипторов.
Безопасность внешнего хранилища ниже, чем у Internal Storage, поскольку файлы доступны другим приложениям. Любое приложение с разрешением READ_EXTERNAL_STORAGE может прочитать все файлы на SD-карте, включая те, которые ваше приложение создало для временного хранения конфиденциальных данных. Злоумышленное приложение может просканировать SD-карту и извлечь пользовательские данные, если они не зашифрованы. Поэтому категорически не рекомендуется хранить токены аутентификации, пароли или персональные данные пользователя во внешнем хранилище в открытом виде.
На Android 10+ Scoped Storage существенно ограничивает возможности приложений по доступу к общей файловой системе. Приложение может без разрешения читать только файлы, созданные им самим, а для доступа к файлам других приложений требуется явное согласие пользователя через SAF-диалог. Однако это ограничение не распространяется на приложения с целевой версией SDK ниже 29 — они продолжают работать по старой модели, что создаёт риск для пользователей, не обновивших приложения. Google Play с 2021 года требует targetSdkVersion 29+ для всех новых и обновляемых приложений.
Форматирование и шифрование — ещё один важный аспект безопасности. SD-карта, отформатированная как переносное хранилище, не шифруется системой по умолчанию. Даже при использовании adoptable storage шифрование активируется только если производитель устройства включил эту возможность в прошивке. Для защиты конфиденциальных данных, сохраняемых на внешнем хранилище, используйте библиотеку EncryptedFile из AndroidX Security, которая шифрует каждый файл отдельно с использованием AES256-GCM, независимо от системного шифрования.
Эффективное использование внешнего хранилища требует баланса между доступностью данных и безопасностью. Придерживайтесь следующих правил для обеспечения надёжного хранения пользовательских файлов.
Environment.getExternalStorageState() для проверки состояния SD-карты. Карта может быть извлечена, повреждена или недоступна для записиВажно помнить, что внешнее хранилище не гарантирует сохранность данных при сбоях. SD-карты имеют ограниченный ресурс циклов перезаписи, особенно бюджетные модели класса Class 4 и Class 6. При интенсивной записи (например, логирование или кэширование потоковых данных) карта может выйти из строя в течение нескольких месяцев. Для таких сценариев используйте внутреннюю память или облачное хранилище, а на внешнем хранилище сохраняйте только файлы, потерю которых пользователь сочтёт приемлемой. Регулярно проверяйте состояние SD-карты через StatFs и сообщайте пользователю о критических ошибках файловой системы.
Часто задаваемые вопросы
На Android 13+ разрешение READ_EXTERNAL_STORAGE заменено на более гранулярные: READ_MEDIA_IMAGES, READ_MEDIA_VIDEO и READ_MEDIA_AUDIO. Для доступа к другим типам файлов используйте SAF.
Да, функция adoptable storage доступна на Android 6.0+. Карта форматируется в ext4 с шифрованием AES-128. Однако многие производители отключают эту опцию, и около 88% устройств не поддерживают adoptable storage.
Используйте метод Environment.getExternalStorageState(), который возвращает строку состояния. Значение MEDIA_MOUNTED означает, что карта доступна для чтения и записи. Другие значения указывают на ошибки или отсутствие карты.
Scoped Storage ограничивает приложение его собственным контейнером и общими медиатеками MediaStore. Полный доступ разрешает чтение любых файлов на устройстве. Scoped Storage повышает безопасность пользовательских данных и обязателен для новых приложений.
Запустите Intent с действием ACTION_OPEN_DOCUMENT_TREE, который откроет системный диалог выбора директории. После выбора вы получите URI-разрешение, действующее до перезагрузки. Сохраните этот URI в SharedPreferences для последующего использования.
Итоги
Мы разработаем мобильное приложение под ключ
IT Sectr создаёт приложения для iOS и Android для стартапов и бизнеса с 2017 года. Мы проконсультируем вас и предложим наилучшее решение.
Читайте также