AndroidManifest Permissions — это декларации разрешений в файле AndroidManifest.xml, которые определяют, к каким системным ресурсам и данным имеет доступ приложение. Android требует указывать каждое разрешение в манифесте перед использованием соответствующего API: от камеры и геолокации до отправки SMS и доступа к контактам. Согласно Android Developer Documentation, каждое разрешение делится на один из четырёх уровней защиты: normal, dangerous, signature и special.
Главное
AndroidManifest Permissions — это механизм безопасности Android, который контролирует доступ приложений к защищённым данным и системным функциям. Каждое приложение должно декларировать необходимые разрешения в файле AndroidManifest.xml с помощью элемента
Модель разрешений Android прошла несколько этапов эволюции. До Android 6.0 (API 23) все разрешения предоставлялись при установке — пользователь видел полный список и соглашался или отказывался от установки приложения. Начиная с Android 6.0, разрешения уровня dangerous запрашиваются во время выполнения (Runtime Permissions), что даёт пользователю более гибкий контроль.
Разрешения делятся на четыре уровня защиты: normal (автоматически предоставляются при установке), dangerous (требуют runtime-запроса), signature (доступны только приложениям, подписанным тем же сертификатом) и special (требуют отдельного включения в настройках). Каждый уровень имеет свой механизм предоставления и отзыва.
По данным Google I/O 2024, в Android 15 планируется внедрение более granular разрешений — пользователь сможет предоставлять доступ только к определённым файлам в медиатеке, а не ко всей библиотеке. Это продолжает тенденцию Android к минимизации объёма предоставляемых данных по умолчанию.
В отличие от iOS, где все разрешения запрашиваются во время выполнения (runtime), Android делит разрешения на устанавливаемые (install-time) и выполняемые (runtime). Уровень normal предоставляется автоматически при установке без уведомления пользователя. Уровень dangerous требует явного диалога, как в iOS.
Ещё одно отличие: в Android разрешения объединены в группы (permission groups). Если пользователь согласился на доступ к камере, приложение автоматически получает доступ к микрофону — они в одной группе MICROPHONE. В iOS каждое разрешение запрашивается отдельно независимо от группы.
| Версия Android | Изменение в модели разрешений |
|---|---|
| Android 1.0-5.x | Все разрешения предоставляются при установке (install-time) |
| Android 6.0 (API 23) | Введение Runtime Permissions для dangerous уровня |
| Android 10 (API 29) | Scoped Storage — ограничен доступ к файловой системе |
| Android 11 (API 30) | Auto-reset разрешений — неиспользуемые разрешения сбрасываются |
| Android 14 (API 34) | Runtime разрешения для медиа-доступа (фото, видео, аудио) |
Android определяет четыре уровня защиты (protection levels) для разрешений, каждый с собственными правилами предоставления. Рассмотрим каждый уровень подробно.
Normal разрешения предоставляются автоматически при установке приложения без уведомления или запроса пользователя. Они покрывают доступ к низкорисковым функциям, которые не угрожают приватности пользователя: INTERNET, ACCESS_NETWORK_STATE, VIBRATE, BLUETOOTH. Пользователь не видит диалога согласия — разрешение считается предоставленным по факту установки.
Разработчику не нужно обрабатывать запрос в коде для normal разрешений — достаточно объявить их в манифесте. Однако в Android 12+ при установке из Google Play пользователь видит вкладку «Разрешения» с перечислением всех normal разрешений, что повышает прозрачность. Согласно Statista (2024), более 90% приложений в Google Play используют INTERNET как самое распространённое normal разрешение.
Dangerous разрешения покрывают доступ к данным и функциям, которые могут нарушить приватность: камера, микрофон, геолокация, контакты, SMS, телефон, календарь, датчики тела. Эти разрешения требуют двухэтапного механизма: декларация в манифесте + запрос во время выполнения через ActivityCompat.requestPermissions().
Пользователь может отказать в предоставлении dangerous разрешения, и приложение должно корректно обработать этот сценарий. В Android 11+ если пользователь дважды отказал, последующие запросы не показывают системный диалог — система автоматически возвращает DENIED. В этом случае нужно направлять пользователя в настройки.
Уровень signature — разрешение предоставляется автоматически, если приложение подписано тем же сертификатом, что и система или другое приложение, определившее разрешение. Используется для системных и корпоративных приложений. Пример: BIND_ACCESSIBILITY_SERVICE — доступно только системным приложениям.
Уровень special (SYSTEM_ALERT_WINDOW, WRITE_SETTINGS, REQUEST_INSTALL_PACKAGES, MANAGE_EXTERNAL_STORAGE) — требует отдельного действия пользователя через системные настройки. Приложение может открыть страницу настроек с помощью Intent(Settings.ACTION_MANAGE_OVERLAY_PERMISSION). Google Play ограничивает использование special разрешений и требует обоснования в форме при публикации.
Начиная с Android 6.0, все dangerous разрешения требуют запроса во время выполнения. Рассмотрим полный цикл работы с runtime permissions на Kotlin.
Перед вызовом API, требующего dangerous разрешения, всегда проверяйте текущий статус через ContextCompat.checkSelfPermission(). Если статус PERMISSION_GRANTED — можно вызывать API. Если PERMISSION_DENIED — нужно запросить разрешение через ActivityResultContract RequestPermission (AndroidX) или устаревший requestPermissions().
Рекомендуется использовать ActivityResultContracts.RequestMultiplePermissions для запроса нескольких разрешений одновременно. Google рекомендует группировать связанные разрешения (например, камера + микрофон для видеозаписи) в один диалог, чтобы пользователь видел полный контекст запроса.
import android.Manifest
import android.content.pm.PackageManager
import androidx.activity.result.contract.ActivityResultContracts
import androidx.core.content.ContextCompat
class CameraActivity : AppCompatActivity() {
private val requestPermissionLauncher =
registerForActivityResult(
ActivityResultContracts.RequestPermission()
) { isGranted: Boolean ->
if (isGranted) {
openCamera()
} else {
explainWhyPermissionNeeded()
}
}
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
checkCameraPermission()
}
private fun checkCameraPermission() {
when {
ContextCompat.checkSelfPermission(this,
Manifest.permission.CAMERA
) == PackageManager.PERMISSION_GRANTED -> {
openCamera()
}
shouldShowRequestPermissionRationale(
Manifest.permission.CAMERA
) -> {
showRationale()
}
else -> {
requestPermissionLauncher.launch(
Manifest.permission.CAMERA
)
}
}
}
}
Если пользователь дважды отказал в разрешении, Android переводит запрос в состояние «Never ask again». В этом случае shouldShowRequestPermissionRationale() возвращает false, и системный диалог не будет показан. Приложение должно направить пользователя в системные настройки через Intent(Settings.ACTION_APPLICATION_DETAILS_SETTINGS).
Важно: не показывайте диалог с предложением открыть настройки сразу после первого отказа — это воспринимается как агрессивное поведение. Используйте shouldShowRequestPermissionRationale() для определения, нужно ли показывать объяснение. Material Design Guidelines рекомендуют показывать экран с пояснением ценности доступа, а не просто кнопку «Открыть настройки».
private fun openAppSettings() {
Intent(
Settings.ACTION_APPLICATION_DETAILS_SETTINGS,
Uri.fromParts("package", packageName, null)
).also { intent ->
startActivity(intent)
}
}
private fun showPermissionSettings() {
AlertDialog.Builder(this)
.setTitle("Доступ к камере")
.setMessage("Разрешите доступ к камере в Настройках, "
+ "чтобы снимать фото для профиля")
.setPositiveButton("Открыть настройки") { _, _ ->
openAppSettings()
}
.setNegativeButton("Отмена", null)
.show()
}
Файл AndroidManifest.xml содержит элемент
Каждое разрешение объявляется отдельным элементом
Например, разрешение WRITE_EXTERNAL_STORAGE не нужно на Android 10+ (Scoped Storage), поэтому указывайте maxSdkVersion="28" (Android 9). Это предотвращает лишние вопросы от пользователей на новых версиях. Android Studio предупреждает о рекомендуемых maxSdkVersion через Lint.
<!-- AndroidManifest.xml -->
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android">
<!-- Normal permissions (install-time) -->
<uses-permission
android:name="android.permission.INTERNET" />
<uses-permission
android:name="android.permission.ACCESS_NETWORK_STATE" />
<!-- Dangerous permissions (runtime) -->
<uses-permission
android:name="android.permission.CAMERA" />
<uses-permission
android:name="android.permission.ACCESS_FINE_LOCATION" />
<!-- Legacy storage permission limited to API 28 and below -->
<uses-permission
android:name="android.permission.WRITE_EXTERNAL_STORAGE"
android:maxSdkVersion="28" />
<uses-feature
android:name="android.hardware.camera"
android:required="false" />
<application>
<!-- ... -->
</application>
</manifest>
Элемент
Рекомендуется для всех аппаратных функций указывать required="false" и проверять доступность программно через PackageManager.hasSystemFeature(). Это расширяет аудиторию вашего приложения. Единственное исключение — если функция критична для работы приложения (приложение для заказа такси без GPS не имеет смысла).
Правильная работа с разрешениями — ключевой аспект качества Android-приложения. Рассмотрим основные рекомендации и типовые ошибки.
Запрашивайте только те разрешения, которые действительно необходимы для работы приложения. Каждое лишнее разрешение снижает конверсию установок и увеличивает количество отказов. Google Play Console показывает, сколько пользователей отказались от установки из-за набора разрешений. По данным AppBrain (2024), приложения с 10+ dangerous разрешениями имеют на 35% меньше установок.
Регулярно пересматривайте список разрешений. Удаляйте неиспользуемые, особенно при переходе на новые версии Android, где некоторые разрешения стали необязательны. Например, с появлением фото-пикера (ActivityResultContracts.PickVisualMedia) в Android 13+ доступ к медиатеке можно получать без dangerous разрешения READ_MEDIA_IMAGES.
Перед запросом dangerous разрешения покажите пользователю экран с объяснением, зачем нужно это разрешение и какую ценность оно даёт. Material Design рекомендует использовать bottom sheet или диалог с иконкой, кратким текстом и кнопкой «Продолжить». Rationale повышает согласие на 20-30% по сравнению с прямым запросом.
Проверяйте shouldShowRequestPermissionRationale() перед вызовом launch(). Если true — покажите rationale. Если false — либо разрешение уже дано, либо пользователь отказался навсегда (never ask again). В последнем случае покажите кнопку «Открыть настройки», а не повторяйте запрос.
Протестируйте все возможные сценарии: предоставление разрешения, отказ, отказ навсегда, отзыв разрешения в настройках, сброс разрешений (Android 11+ auto-reset). Каждый сценарий должен обрабатываться без краша и без потери данных. Android Testing Guide рекомендует использовать библиотеку TestPermission для автоматизации тестирования.
Особое внимание уделите сценарию, когда пользователь отозвал разрешение во время работы приложения (свёрнутое приложение → Настройки → отзыв). При возврате в приложение проверьте все разрешения заново через onResume(). Не полагайтесь на кеширование статуса разрешений — пользователь может изменить их в любой момент.
Часто задаваемые вопросы
Да, если SDK включает в свой манифест разрешение, оно объединяется с манифестом приложения при сборке. Вы можете отключить ненужное разрешение SDK с помощью tools:node="remove" в AndroidManifest.xml.
Вызов API без разрешения вызовет SecurityException, что приведёт к крашу приложения. Всегда проверяйте статус разрешения перед использованием соответствующего API и обрабатывайте отказ корректно.
В настройках устройства: Настройки → Приложения → [ваше приложение] → Разрешения. Для сброса всех разрешений используйте adb команду: adb shell pm reset-permissions.
Да, с помощью ActivityResultLauncher в Fragment или Service. Однако диалог запроса всегда требует UI-контекста Activity. Для Service вы можете показать Notification с Intent, открывающим Activity с запросом.
Например, WRITE_EXTERNAL_STORAGE не нужен на Android 10+ (Scoped Storage). Указав android:maxSdkVersion="28", вы исключаете декларацию разрешения на новых версиях, что улучшает совместимость и уменьшает список запрашиваемых разрешений.
Итоги
Мы разработаем мобильное приложение под ключ
IT Sectr создаёт приложения для iOS и Android для стартапов и бизнеса с 2017 года. Мы проконсультируем вас и предложим наилучшее решение.
Читайте также