Краткое руководство по приложениям на Android 11: разрешения, уведомления и совместимость

Android 11 усилил приватность: появились одноразовые разрешения и auto‑revoke, стал обязательным scoped storage для targetSdk≥30, добавлены Conversation/Bubbles и ужесточены правила MANAGE_EXTERNAL_STORAGE — ключевые действия: мигрировать на MediaStore/SAF/app‑specific, проверить логику запросов разрешений и привести уведомления к MessagingStyle/Person.

Разрешения и поведение системы

Что важно учесть сразу и как это реализовать:

  • Одноразовые разрешения: пользователь может дать доступ «только в этот раз». Проверяйте разрешение при каждом запуске критичной функциональности и готовьте понятный rationale.
  • Auto‑revoke: система сбрасывает чувствительные runtime‑права у неиспользуемых приложений. При старте функционала проверяйте и заново запрашивайте права.
  • Background‑location: запрашивайте сначала foreground‑location, затем — по необходимости — background; Google Play требует обоснования.

Практика

  • Всегда проверяйте ContextCompat.checkSelfPermission перед доступом.
  • При отказе показывайте объяснение и предлагаете deep link в системные настройки.
  • Для критичных фич (резервное копирование, менеджеры файлов) заранее объясняйте пользователю, зачем нужен доступ.

Если функциональность зависит от прав постоянно, реализуйте экран с объяснением и кнопкой «Открыть настройки», чтобы избежать потерь пользователя после auto‑revoke.

Scoped Storage и доступ к файлам — куда мигрировать и когда нужен All files access

Основной принцип: ограничить произвольный доступ в shared storage. Варианты работы с файлами:

Сравнение способов доступа к файлам

СпособЧто даётКогда использовать
App‑specific dirs (getExternalFilesDir)Полный доступ в приватной папке приложенияДля файлов, которыми оперирует только приложение
MediaStore APIЗапись/чтение медиаконтента через индексированную БДДля фото, видео, аудио — рекомендовано
Storage Access Framework (SAF)Доступ к выбранным пользователем папкам/файламДля документов и произвольных файлов, где нужен пользовательский выбор
MANAGE_EXTERNAL_STORAGEДоступ ко всей общей файловой системеТолько для файловых менеджеров/backup — с декларацией в Play Console

Практические шаги миграции

  1. Проведите аудит всех прямых обращений к Environment.getExternalStorageDirectory и Android/data; замените на app‑specific/MediaStore/SAF.
  2. Тестируйте массовые операции через batch‑методы MediaStore и выполняйте I/O вне UI‑потока.
  3. Если действительно нужен MANAGE_EXTERNAL_STORAGE, подготовьте декларацию для публикации и реализуйте понятный диалог включения разрешения. Для локальной отладки можно временно разрешить через adb: adb shell appops set <PACKAGE_NAME> MANAGE_EXTERNAL_STORAGE allow

Не добавляйте MANAGE_EXTERNAL_STORAGE «на всякий случай» — Google Play строго проверяет оправданность.

Уведомления: Conversations, Bubbles и поведение истории уведомлений

Что нужно поменять в реализации уведомлений:

  • Для попадания в Conversation section используйте Notification.MessagingStyle, подключайте объекты Person и shortcutId.
  • Чтобы поддержать Bubbles, формируйте Notification с корректным BubbleMetadata и не удаляйте уведомление сразу после создания пузыря (используйте флаги suppression по документации).
  • Ожидайте, что пользователи могут восстанавливать недавно закрытые уведомления через системную историю уведомлений; тестируйте поведение с media controls и quick settings.

Практические советы

  • Тестируйте уведомления на реальных устройствах с API 30+, проверяйте видимость в Conversation section и работу Bubbles.
  • При отправке сообщений обновляйте существующий notificationId, используйте PendingIntent с FLAG_UPDATE_CURRENT.

Частые ошибки

  • EACCES / Permission denied при File API: причина — scoped storage. Решение — мигрировать данные в app‑specific/MediaStore/SAF.
  • Замедление при массовых операциях: решение — использовать batch‑операции MediaStore и выполнять I/O в background.
  • Уведомления не становятся Conversation/Bubble: проверьте MessagingStyle, Person и shortcutId.
  • Функции «сломались» после длительного простоя: проверьте auto‑revoke и добавьте проверку прав при старте.
  • Отклонение в Play Console из‑за MANAGE_EXTERNAL_STORAGE: уберите его или подготовьте полноценную декларацию и описание кейсов.

FAQ

  • Нужно ли менять targetSdk на 30 немедленно? Рекомендуется тестировать миграцию локально и планировать обновление targetSdk заранее — после повышения нужно соблюдать все ограничения API 30.
  • Как проверить, сброшено ли разрешение пользователю? Всегда проверяйте checkSelfPermission перед операцией и показывайте rationale/направление в настройки при отказе.
  • Можно ли временно обойти scoped storage для тестов? Для отладки используют adb‑команды или специальные флаги на эмуляторе, но в проде полагаться на это нельзя.
  • Что эффективнее для медиаконтента — MediaStore или SAF? MediaStore — оптимальный выбор для фото/видео/аудио; SAF применим для документов и пользовательских папок.

Контрольный чеклист перед обновлением targetSdk до 30

  • Аудит прямых обращений к общему хранилищу.
  • Миграция данных в app‑specific или MediaStore.
  • Обновление логики запросов разрешений (one‑time, rationale, auto‑revoke).
  • Приведение уведомлений к MessagingStyle/Person/shortcutId.
  • Подготовка декларации для MANAGE_EXTERNAL_STORAGE, если он необходим.

Если нужно, подготовлю конкретный план миграции манифеста и примеры кода для MediaStore/SAF под ваш проект или разберу ваш AndroidManifest.xml и список разрешений — укажите, что предпочитаете.