Как работать с файлами и документами на Android в 2026 году
Короткий ответ: используйте SAF (Storage Access Framework) для документов и общих файлов, MediaStore — для фото/видео/аудио, а Jetpack (DocumentFile + androidx.core) для кросс-версионной совместимости и упрощения кода.
Когда выбирать SAF, MediaStore и Jetpack
- SAF — когда пользователь выбирает/создаёт файлы через системные пикеры (ACTION_OPEN_DOCUMENT / ACTION_CREATE_DOCUMENT). Нет необходимости в READ_EXTERNAL_STORAGE, поддерживаются persistable permissions.
- MediaStore — для массовых операций с медиа (галерея, камера, аудио). Поддерживает Scoped Storage и флаги вроде setRequireOriginal().
- Jetpack (androidx.documentfile, androidx.core.content) — обёртки для старых/новых API, полезны при миграции и при поддержке множества версий Android.
Для подавляющего большинства кейсов комбинируйте SAF + MediaStore: SAF даёт безопасный доступ к документам, MediaStore — оптимизированную работу с медиа.
Практические приёмы и примеры кода
- Открытие документа (SAF):
val intent = Intent(Intent.ACTION_OPEN_DOCUMENT).apply {
addCategory(Intent.CATEGORY_OPENABLE)
type = "application/pdf"
}
startActivityForResult(intent, REQUEST_OPEN)
- Создание файла:
val create = Intent(Intent.ACTION_CREATE_DOCUMENT).apply {
addCategory(Intent.CATEGORY_OPENABLE)
type = "application/pdf"
putExtra(Intent.EXTRA_TITLE, "doc.pdf")
}
startActivityForResult(create, REQUEST_CREATE)
- Чтение содержимого:
contentResolver.openInputStream(uri)?.use { input ->
val bytes = input.readBytes()
// обработка
}
- DocumentFile для работы с деревом:
val doc = DocumentFile.fromSingleUri(context, uri)
doc?.createFile("application/pdf", "new.pdf")
- Работа с медиа через MediaStore:
- Используйте ContentValues и contentResolver.insert(...) для сохранения фото/видео.
- Включайте MediaStore.setRequireOriginal() чтобы избежать сжатия при необходимости.
Совместимость и роли (Scoped Storage и MANAGE_EXTERNAL_STORAGE)
- Scoped Storage обязателен с API 30; не полагайтесь на прямые пути (/storage/emulated/0/).
- Проверяйте Environment.isExternalStorageManager() только если вы реально нуждаетесь в MANAGE_EXTERNAL_STORAGE; Google Play ограничивает эту роль (файловые менеджеры — исключение).
- Для app-specific данных используйте getExternalFilesDirs() — это упрощает доступ без дополнительных разрешений.
Запрос MANAGE_EXTERNAL_STORAGE одобряется Play только для ограниченного круга приложений. Не просите его без веской причины — используйте SAF.
Инструменты и библиотеки
- androidx.documentfile и androidx.core — для обёрток SAF и совместимости.
- Glide/Coil — для загрузки и отображения изображений.
- Okio — удобные утилиты для потоков и работы с байтами.
- WorkManager + DownloadManager — для фоновых загрузок документов и устойчивости к рестарту.
Миграция с legacy-кода
- Откажитесь от File(path) для внешнего хранилища.
- Мигрируйте к SAF и MediaStore; используйте DocumentFile и ContentResolver.
- Для тестирования Scoped Storage симулируйте разные состояния через эмулятор и adb.
Частые ошибки
- Пытаться читать внешние файлы напрямую через File — приведёт к отказам на большинстве устройств.
- Просить MANAGE_EXTERNAL_STORAGE без обоснования — отклонение в Play.
- Не сохранять persistable permissions после ACTION_OPEN_DOCUMENT — потеря доступа при перезапуске.
- Игнорировать различия между документом (любые файлы) и медиа (MediaStore) — производительность и UX пострадают.
FAQ
- Нужно ли запрашивать READ_EXTERNAL_STORAGE?
- В большинстве случаев нет: SAF и MediaStore закрывают этот кейс. READ_EXTERNAL_STORAGE требуется только для legacy-сценариев на старых версиях.
- Как обеспечить долгий доступ к URI из SAF?
- Используйте takePersistableUriPermission и сохраняйте URI в защищённом хранилище (например, EncryptedSharedPreferences).
- Что делать с виртуальными файлами?
- На Android 14+ DocumentsProvider поддерживает виртуальные файлы; читайте через openTypedAssetFileDescriptor и stream.
- Можно ли комбинировать SAF и MediaStore?
- Да. SAF хорош для документов, MediaStore — для интеграции с галереей и системными медиапроцессами; вместе покрывают большинство случаев.