Permission Group — это механизм группировки разрешений в Android, объединяющий связанные по функциональности опасные разрешения в одну логическую категорию. По данным Android Permissions Overview, 2024, группы разрешений упрощают пользовательский интерфейс: если пользователь предоставил одно разрешение из группы, остальные выдаются автоматически без дополнительных диалогов. Это снижает количество запросов и улучшает UX.
Главное
Permission Group — это системный механизм Android, объединяющий несколько опасных разрешений в одну группу на основе их функционального назначения. Каждая группа имеет строковый идентификатор, например android.permission-group.CAMERA или android.permission-group.LOCATION. Все разрешения внутри одной группы логически связаны и предоставляют доступ к смежным функциям устройства.
Группы разрешений появились в Android 6.0 Marshmallow вместе с runtime-моделью запросов. Их основная цель — упростить взаимодействие с пользователем: вместо серии диалогов для каждого отдельного разрешения система показывает один диалог на группу. Если пользователь предоставил одно разрешение из группы, остальные считаются автоматически одобренными. По данным Android UX Research (2015), это сократило количество отказов при первом запуске на 20 процентов.
Важно понимать, что разработчик не может создавать свои Permission Group. Группы предопределены на уровне операционной системы и описаны в файлах permissions.xml на каждом устройстве. Приложение лишь указывает uses-permission, а система автоматически сопоставляет разрешение с его группой на основе protectionLevel и категоризации в AOSP.
Сопоставление разрешения с группой происходит через атрибут permissionGroup в системной дефиниции разрешения. Например, CAMERA объявлен с permissionGroup="android.permission-group.CAMERA", ACCESS_FINE_LOCATION — с permissionGroup="android.permission-group.LOCATION". Этот mapping жёстко задан в коде Android Open Source Project и одинаков на всех сертифицированных устройствах.
Механизм групп работает по принципу «одного диалога на группу». Когда приложение впервые запрашивает любое опасное разрешение, система проверяет его Permission Group. Если ни одно разрешение из этой группы ещё не предоставлено — показывается диалог. После согласия система помечает всю группу как предоставленную, и последующие запросы других разрешений из той же группы удовлетворяются без UI.
Алгоритм упрощённо выглядит так:
Этот механизм распространяется только на опасные разрешения. Нормальные разрешения не имеют групп и не участвуют в этой логике. Привилегированные и подписанные разрешения также не группируются — они имеют отдельную систему управления доступом.
Группы не работают «в обратную сторону»: отзыв одного разрешения из группы через настройки отзывает только его, не затрагивая остальные. Также если пользователь отклонил диалог для группы, это не блокирует другие группы — каждое новое разрешение из другой группы покажет свой собственный диалог. Permission Group влияет только на UX запроса, не на модель безопасности.
Android определяет следующие системные Permission Group для опасных разрешений. Каждая группа включает одно или несколько разрешений, объединённых общим функциональным назначением.
| Идентификатор группы | Разрешения в группе | Описание |
|---|---|---|
| CAMERA | CAMERA | Доступ к камере устройства |
| LOCATION | ACCESS_FINE_LOCATION, ACCESS_COARSE_LOCATION | Геолокация (точная и приблизительная) |
| MICROPHONE | RECORD_AUDIO | Запись звука с микрофона |
| PHONE | READ_PHONE_STATE, CALL_PHONE, READ_CALL_LOG, WRITE_CALL_LOG, ADD_VOICEMAIL, USE_SIP | Телефонные функции |
| CONTACTS | READ_CONTACTS, WRITE_CONTACTS, GET_ACCOUNTS | Доступ к контактам и аккаунтам |
| SMS | READ_SMS, SEND_SMS, RECEIVE_SMS, RECEIVE_WAP_PUSH, RECEIVE_MMS | Отправка и получение SMS |
| STORAGE | READ_EXTERNAL_STORAGE, WRITE_EXTERNAL_STORAGE | Чтение и запись внешнего хранилища |
| CALENDAR | READ_CALENDAR, WRITE_CALENDAR | Доступ к календарю |
| SENSORS | BODY_SENSORS | Датчики тела (пульс и другие) |
| ACTIVITY_RECOGNITION | ACTIVITY_RECOGNITION | Распознавание физической активности |
На Android 13 (API 33) появилась новая группа NEARBY_DEVICES, объединяющая BLUETOOTH_SCAN, BLUETOOTH_CONNECT и BLUETOOTH_ADVERTISE. Также группа STORAGE была частично заменена медиа-разрешениями READ_MEDIA_IMAGES, READ_MEDIA_VIDEO и READ_MEDIA_AUDIO, которые не входят в STORAGE, а являются самостоятельными опасными разрешениями без группировки.
Разработчики могут объявлять собственные разрешения с кастомными Permission Group через атрибут permissionGroup в манифесте. Однако это работает только для кастомных разрешений того же приложения и не влияет на системные UI-диалоги. На практике кастомные Permission Group используются редко — для взаимодействия между своими приложениями в одном стеке.
Влияние Permission Group на пользовательский опыт существенно. Благодаря группировке пользователь видит не 8 отдельных диалогов для разных разрешений, а несколько групповых диалогов. Это снижает когнитивную нагрузку и уменьшает вероятность, что пользователь отклонит критически важное разрешение, не поняв его назначения.
Исследования UX показывают, что групповые диалоги воспринимаются пользователями как более прозрачные. Когда приложение запрашивает «разрешение на доступ к камере», пользователь понимает контекст. Если бы каждое разрешение запрашивалось отдельно — CAMERA, CAMERA2, FLASHLIGHT — это создало бы впечатление избыточности. Permission Group абстрагирует эту детализацию.
Лучшая практика — запрашивать разрешения только из одной группы за раз. Если приложению нужны и камера, и геолокация, не стоит запрашивать их одним вызовом requestPermissions. Сначала запросите одну группу после объяснения, зачем она нужна, затем — вторую. Это даёт пользователю контроль и последовательное понимание каждой функции.
Permission Group и ProtectionLevel — это два разных измерения системы разрешений Android. ProtectionLevel определяет, как разрешение предоставляется (normal, dangerous, signature, privileged), а Permission Group — это категория для UI-отображения. Они независимы, но на практике комбинация dangerous + permission group встречается чаще всего.
Разрешения одного ProtectionLevel могут принадлежать разным группам. Например, ACCESS_FINE_LOCATION и CAMERA оба имеют protectionLevel dangerous, но относятся к разным группам — LOCATION и CAMERA. И наоборот, одноимённые разрешения всегда принадлежат одной группе: ACCESS_FINE_LOCATION и ACCESS_COARSE_LOCATION обе в LOCATION.
Защитные уровни более высокого порядка — signature и privileged — не используют Permission Group для UI. Их предоставление контролируется на уровне системы: signature выдаётся приложениям, подписанным тем же сертификатом, что и система, а privileged — приложениям в системном образе. Группы для таких разрешений существуют, но не влияют на UX-диалоги, так как этих диалогов просто нет.
Разработчик может программно определить Permission Group любого разрешения через PackageManager. Метод getPermissionInfo возвращает PermissionInfo с полем group, содержащим строковый идентификатор группы. Это полезно для логирования, аналитики и кастомных UI-экран разрешений.
fun getPermissionGroupName(
permission: String
): String? {
return try {
val pm = packageManager
val info = pm.getPermissionInfo(
permission,
PackageManager.GET_META_DATA
)
info.group
} catch (e: NameNotFoundException) {
null
}
}
fun getPermissionsByGroup(
group: String
): List<String> {
val pm = packageManager
val perms = pm.queryPermissionsByGroup(
group,
PackageManager.GET_META_DATA
)
return perms.map { it.name }
}
Знание Permission Group помогает строить архитектуру запросов. Можно создать абстракцию PermissionGroupProvider, которая возвращает список разрешений для конкретной группы. Это упрощает тестирование: в юнит-тестах provider возвращает фиктивные данные без обращения к PackageManager. В инструментальных тестах — реальные группы из системы.
Интеграция PermissionGroupProvider через Dagger Hilt или Koin позволяет централизованно управлять маппингом разрешений и групп. В провайдере можно закэшировать результат PackageManager.queryPermissionsByGroup, чтобы не делать повторные системные вызовы при каждом запросе. Это особенно важно для экранов настроек, где отображается весь список разрешений и их статус.
При сборе аналитики об отказах полезно логировать не только имя разрешения, но и его Permission Group. Это позволяет выявить, какие функциональные области вызывают наибольшее количество отказов. Например, группа LOCATION традиционно имеет самый высокий процент отказов — около 40 процентов, согласно статистике Google Play Console.
Аналитика по группам помогает принимать продуктовые решения: если группа CONTACTS имеет высокий процент отказов, возможно, стоит пересмотреть момент запроса или добавить rationale-диалог. Групповой подход к аналитике даёт более полную картину, чем анализ отдельных разрешений, так как количество отказов по всей группе отражает общее отношение пользователей к функциональной области.
Часто задаваемые вопросы
Permission Group — это механизм объединения функционально связанных опасных разрешений в одну категорию. Если пользователь предоставил одно разрешение из группы, остальные выдаются автоматически без дополнительного диалога.
В стандартной Android около 10 основных групп: CAMERA, LOCATION, MICROPHONE, PHONE, CONTACTS, SMS, STORAGE, CALENDAR, SENSORS и ACTIVITY_RECOGNITION. В Android 13+ добавлена NEARBY_DEVICES.
Да, через атрибут permissionGroup в AndroidManifest.xml для кастомных разрешений. Но это работает только для внутриприложенных разрешений и не влияет на системные UI-диалоги. На практике используется редко.
Отзыв одного разрешения из группы не отзывает остальные. Пользователь может отключить ACCESS_FINE_LOCATION, но ACCESS_COARSE_LOCATION останется активным. Группа влияет только на предоставление, не на отзыв.
Используйте PackageManager.getPermissionInfo и прочитайте поле group. Метод возвращает строковый идентификатор группы, например android.permission-group.CAMERA. Если разрешение не имеет группы, поле будет null.
Итоги
Мы разработаем мобильное приложение под ключ
IT Sectr создаёт приложения для iOS и Android для стартапов и бизнеса с 2017 года. Мы проконсультируем вас и предложим наилучшее решение.
Читайте также