Как работать с разрешениями хранения в Android 13
В Android 13 доступ к мультимедиа стал гранулированным: вместо общего READ_EXTERNAL_STORAGE используются READ_MEDIA_IMAGES/VIDEO/AUDIO; для единичного выбора файлов предпочтителен Photo Picker; MANAGE_EXTERNAL_STORAGE — только для реальных «all files» кейсов.
Что именно изменилось в Android 13
Android 13 ввёл три отдельных runtime‑permissions для чтения медиа: READ_MEDIA_IMAGES, READ_MEDIA_VIDEO и READ_MEDIA_AUDIO. Scoped storage остаётся базовой моделью: приложение по‑умолчанию видит только свои директории. Для выбора отдельных файлов рекомендован системный Photo Picker, который даёт URI без запроса runtime‑permissions. MANAGE_EXTERNAL_STORAGE остаётся опцией «всё сразу», но её выдача строго контролируется и требует обоснования при публикации.
Если задача — позволить пользователю выбрать одно или несколько фото/видео — используйте Photo Picker или SAF: это проще и безопаснее, чем просить глобальные разрешения.
Когда какое разрешение или инструмент использовать
Сравнение способов доступа к медиа
| Задача | Инструмент / permission | Когда использовать |
|---|---|---|
| Разовый выбор фото/видео | Photo Picker / ACTION_OPEN_DOCUMENT | Всегда, если нужно, чтобы пользователь сам выбрал файлы |
| Массовое чтение изображений | READ_MEDIA_IMAGES | Галерея, анализ фото, таргет API 33+ |
| Массовое чтение видео | READ_MEDIA_VIDEO | Просмотр/обработка видео‑библиотеки |
| Массовое чтение аудио | READ_MEDIA_AUDIO | Плееры, анализ аудио |
| Доступ ко всем файлам | MANAGE_EXTERNAL_STORAGE | Файловые менеджеры, бэкапы — только при отсутствии альтернатив |
Практическое правило: минимизируйте набор разрешений — запрашивайте только то, что действительно нужно.
Практическая миграция: что сделать пошагово
- Поднимите targetSdkVersion до 33+ и прогоните тесты: поведение старых storage permissions изменится.
- Проанализируйте кейсы доступа: разовый выбор vs массовая работа vs полный доступ.
- Реализуйте Photo Picker / SAF для выбора файлов — это снижает требования к permission‑логике.
- Если нужно массовое чтение медиа — добавьте в манифест соответствующие READ_MEDIA_* и запрашивайте их динамически. Объясняйте пользователю причину запроса.
- Для записи используйте MediaStore.insert/update или ACTION_CREATE_DOCUMENT; избегайте WRITE_EXTERNAL_STORAGE.
- MANAGE_EXTERNAL_STORAGE — применять только если невозможно обойтись SAF/MediaStore; подготовьте документированное обоснование для Play Console.
Пример простого запроса разрешения (Kotlin):
// регистрация
val request = registerForActivityResult(ActivityResultContracts.RequestPermission()) { ok ->
if (ok) { /* доступ есть */ } else { /* показать подсказку или вести в Settings */ }
}
if (ContextCompat.checkSelfPermission(this, Manifest.permission.READ_MEDIA_IMAGES)
!= PackageManager.PERMISSION_GRANTED) {
request.launch(Manifest.permission.READ_MEDIA_IMAGES)
}
Пример вызова Photo Picker:
val pick = registerForActivityResult(ActivityResultContracts.PickVisualMedia()) { uri ->
uri?.let {
contentResolver.takePersistableUriPermission(it, Intent.FLAG_GRANT_READ_URI_PERMISSION)
// обработка
}
}
pick.launch(PickVisualMediaRequest(ActivityResultContracts.PickVisualMedia.ImageAndVideo))
Частые ошибки
- Запрашивают WRITE_EXTERNAL_STORAGE на API 33+ — диалог может не появиться; используйте READ_MEDIA_* или Photo Picker.
- Предполагают, что один granted READ_EXTERNAL_STORAGE перекрывает все — теперь права гранулированы.
- Не обрабатывают кейс «пользователь дважды отказал» — предложите ясный маршрут в настройки.
- Не проверяют availability Photo Picker на старых/нестандартных прошивках — делайте fallback на SAF.
Не запрашивайте MANAGE_EXTERNAL_STORAGE без крайней необходимости: повышенный риск отклонения в модерации и потеря доверия пользователей.
FAQ
- Нужен ли WRITE_EXTERNAL_STORAGE для записи в публичную медиатеку?
Нет. Для записи используйте MediaStore API или ACTION_CREATE_DOCUMENT; WRITE_EXTERNAL_STORAGE устарел для scoped storage. - Что делать, если нужно показать мини‑галерею с быстрым доступом к медиа?
Запросите соответствующие READ_MEDIA_* (только те, что нужны) и объясните пользователю цель. - Photo Picker доступен на всех устройствах?
На современных устройствах да; для старых OEM‑прошивок делайте fallback на SAF или собственный picker.
Контрольный чек‑лист миграции
- [ ] Разделили кейсы: выбор vs массовая работа vs полный доступ.
- [ ] Везде, где возможно, внедрён Photo Picker/SAF.
- [ ] В манифесте только нужные READ_MEDIA_* указаны и запрашиваются динамически.
- [ ] Для записи используется MediaStore или ACTION_CREATE_DOCUMENT.
- [ ] Если нужен MANAGE_EXTERNAL_STORAGE — подготовлены объяснение и privacy policy.
Если нужно, могу подготовить патч для вашего модуля доступа к файлам или тест‑план для проверки на Android 11–14 и популярных устройствах.