Как работать с разрешениями хранения в 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Файловые менеджеры, бэкапы — только при отсутствии альтернатив

Практическое правило: минимизируйте набор разрешений — запрашивайте только то, что действительно нужно.

Практическая миграция: что сделать пошагово

  1. Поднимите targetSdkVersion до 33+ и прогоните тесты: поведение старых storage permissions изменится.
  2. Проанализируйте кейсы доступа: разовый выбор vs массовая работа vs полный доступ.
  3. Реализуйте Photo Picker / SAF для выбора файлов — это снижает требования к permission‑логике.
  4. Если нужно массовое чтение медиа — добавьте в манифест соответствующие READ_MEDIA_* и запрашивайте их динамически. Объясняйте пользователю причину запроса.
  5. Для записи используйте MediaStore.insert/update или ACTION_CREATE_DOCUMENT; избегайте WRITE_EXTERNAL_STORAGE.
  6. 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 и популярных устройствах.