Как работать с permission в Android — кратко и по делу
Короткий ответ: запрашивайте dangerous permissions в рантайме (проверка через ContextCompat.checkSelfPermission → Activity Result API / ActivityCompat.requestPermissions), обрабатывайте отказ через shouldShowRequestPermissionRationale и при "Не спрашивать" предлагайте открыть настройки приложения. Ниже — рабочие примеры и алгоритмы.
Как запрашивать разрешения в коде
- Всегда проверяйте текущее состояние перед запросом:
- ContextCompat.checkSelfPermission() — есть ли разрешение.
- Для группы разрешений проверяйте по каждому требуемому.
- Рекомендуемый современный способ — Activity Result API: kotlin
// В Activity или Fragment
private val requestCamera = registerForActivityResult(
ActivityResultContracts.RequestPermission()
) { granted ->
if (granted) openCamera() else handleDenied()
}
// Запрос
if (ContextCompat.checkSelfPermission(this, Manifest.permission.CAMERA)
!= PackageManager.PERMISSION_GRANTED) {
requestCamera.launch(Manifest.permission.CAMERA)
} else {
openCamera()
}
- Для множественных разрешений используйте RequestMultiplePermissions или Accompanist/Permissions в Compose: kotlin
val launcher = registerForActivityResult(
ActivityResultContracts.RequestMultiplePermissions()
) { results -> /* results: Map<String, Boolean> */ }
launcher.launch(arrayOf(Manifest.permission.CAMERA, Manifest.permission.RECORD_AUDIO))
- Сохраняйте UX:
- Запрашивайте только нужные разрешения, когда функция реально используется.
- Для уведомлений в Android 13+ динамически запрашивайте POST_NOTIFICATIONS.
- В Compose используйте библиотеки (Accompanist или официальные вспомогательные API) для декларативного диалога.
Проверяйте ContextCompat.checkSelfPermission() перед запросом, чтобы не показывать диалог повторно и не раздражать пользователя.
Короткая сводка по типам разрешений
| Тип | Пример | Как обрабатывается |
|---|---|---|
| normal | ACCESS_NETWORK_STATE | Авто при установке |
| dangerous | CAMERA, LOCATION | Runtime‑запрос |
| special | SYSTEM_ALERT_WINDOW | Запрос через настройки |
| new (post-API) | POST_NOTIFICATIONS, PHOTO_PICKER | Запрос/новые API поведения |
Как пользователю выдавать и управлять разрешениями
- Через Настройки > Приложения > [Ваше приложение] > Разрешения — включить/выключить по группам.
- Для "Только один раз" — выбирайте опцию в диалоге запроса (Android 11+).
- Если поставлен "Не спрашивать", нужно вручную открыть страницу приложения: kotlin
startActivity(Intent(Settings.ACTION_APPLICATION_DETAILS_SETTINGS).apply {
data = Uri.fromParts("package", packageName, null)
})
- Система автоматически отзывает неиспользуемые разрешения (auto-revoke) для неактивных приложений (поведение с Android 11+).
Не выдавайте все разрешения подряд. Чем меньше запрашиваете — выше доверие и шанс на согласие.
Что делать при запрете доступа — рекомендации для разработчика
Алгоритм обработки отказа:
- Если пользователь отказал первый раз — покажите объяснение (rationale) перед повторным запросом.
- Если shouldShowRequestPermissionRationale() возвращает false (включая "Не спрашивать") — не спамьте диалогами, предложите открыть настройки.
- Деградируйте функциональность: отключите фичу с понятным сообщением и альтернативой (например, загрузить фото вместо камеры).
- Логируйте отказы для аналитики, но не используйте это для агрессивных повторных запросов.
Пример rationale: kotlin
if (ActivityCompat.shouldShowRequestPermissionRationale(this, Manifest.permission.CAMERA)) {
AlertDialog.Builder(this)
.setMessage("Камера нужна для сканирования QR-кодов")
.setPositiveButton("Разрешить") { _,_ -> requestCamera.launch(Manifest.permission.CAMERA) }
.setNegativeButton("Отмена", null)
.show()
} else {
// Открываем настройки — пользователь, возможно, выбрал "Не спрашивать"
startActivity(Intent(Settings.ACTION_APPLICATION_DETAILS_SETTINGS).apply {
data = Uri.fromParts("package", packageName, null)
})
}
Частые ошибки
- Запрашивать все разрешения сразу при старте — ведёт к отказам.
- Игнорировать shouldShowRequestPermissionRationale и повторно показывать диалоги.
- Пытаться работать с API без проверки разрешения → краши.
- Не учитывать авто-отзыв (auto-revoke) и новые приватные API (PHOTO_PICKER, APPROXIMATE_LOCATION).
FAQ
-
Нужно ли запрашивать разрешение при установке?
Нельзя: dangerous permissions запрашиваются в рантайме с Android 6.0+. -
Как понять, что пользователь выбрал "Только один раз"?
В диалоге система даёт опцию; при следующем использовании нужно снова запросить. -
Что с доступом к файлам (storage)?
Используйте Scoped Storage и MediaStore; минимизируйте использование READ/WRITE_EXTERNAL_STORAGE, мигрируйте на Photo Picker и API доступа к медиа. -
Как тестировать поведение на разных Android?
Тестируйте на эмуляторах и реальных устройствах с разными версиями — поведение Permission API меняется между релизами.
Если нужно, могу подготовить готовые Kotlin‑фрагменты для вашего проекта (Activity/Fragment/Compose) с учетом Activity Result API и обработки всех веток отказа.