AndroidManifest Permissions: ключові поняття, декларація та типи дозволів

Автор: IT Sectr Опубліковано: 2026-05-21 Час читання: 10 хв

AndroidManifest Permissions — це декларації дозволів у файлі AndroidManifest.xml, які визначають, до яких системних ресурсів і даних має доступ застосунок. Android вимагає вказувати кожен дозвіл у маніфесті перед використанням відповідного API: від камери та геолокації до надсилання SMS і доступу до контактів. Згідно з Android Developer Documentation, кожен дозвіл поділяється на один із чотирьох рівнів захисту: normal, dangerous, signature та special.

Головне

  • AndroidManifest.xml — файл маніфесту з декларацією всіх дозволів застосунку
  • Рівні захисту — normal, dangerous, signature, special з різними механізмами запиту
  • Runtime Permission — dangerous дозволи вимагають запиту під час виконання (Android 6+)
  • Declare vs Request — декларація в маніфесті обов’язкова, але dangerous вимагають додаткового запиту в коді
  • Групи — дозволи об’єднані в групи, згода на один дає доступ до всієї групи

Що таке AndroidManifest Permissions?

AndroidManifest Permissions — це механізм безпеки Android, який контролює доступ застосунків до захищених даних і системних функцій. Кожен застосунок повинен декларувати необхідні дозволи у файлі AndroidManifest.xml за допомогою елемента . Без декларації виклик відповідного API завершиться помилкою безпеки SecurityException.

Модель дозволів Android пройшла кілька етапів еволюції. До Android 6.0 (API 23) всі дозволи надавалися під час встановлення — користувач бачив повний список і погоджувався або відмовлявся від встановлення застосунку. Починаючи з Android 6.0, дозволи рівня dangerous запитуються під час виконання (Runtime Permissions), що дає користувачеві більш гнучкий контроль.

Дозволи поділяються на чотири рівні захисту: normal (автоматично надаються під час встановлення), dangerous (вимагають runtime-запиту), signature (доступні лише застосункам, підписаним тим самим сертифікатом) та special (вимагають окремого ввімкнення в налаштуваннях). Кожен рівень має свій механізм надання та відкликання.

За даними Google I/O 2024, Android 15 планує впровадити більш деталізовані дозволи — користувач зможе надавати доступ лише до певних файлів у медіатеці, а не до всієї бібліотеки. Це продовжує тенденцію Android до мінімізації обсягу даних, що надаються за замовчуванням.

Відмінність від моделі дозволів iOS

На відміну від iOS, де всі дозволи запитуються під час виконання (runtime), Android поділяє дозволи на ті, що встановлюються (install-time), і ті, що виконуються (runtime). Рівень normal надається автоматично під час встановлення без повідомлення користувача. Рівень dangerous вимагає явного діалогу, як у iOS.

Ще одна відмінність: в Android дозволи об’єднані в групи (permission groups). Якщо користувач погодився на доступ до камери, застосунок автоматично отримує доступ до мікрофона — вони в одній групі MICROPHONE. У iOS кожен дозвіл запитується окремо незалежно від групи.

Еволюція дозволів за версіями Android

Версія AndroidЗміна в моделі дозволів
Android 1.0–5.xВсі дозволи надаються під час встановлення
Android 6.0 (API 23)Введення Runtime Permissions для рівня dangerous
Android 10 (API 29)Scoped Storage — обмежений доступ до файлової системи
Android 11 (API 30)Автоскидання дозволів — невикористовувані дозволи скидаються
Android 14 (API 34)Runtime дозволи для медіа-доступу (фото, відео, аудіо)

Які типи дозволів існують

Android визначає чотири рівні захисту для дозволів, кожен з власними правилами надання. Розглянемо кожен рівень докладно.

Normal Permissions (install-time)

Normal дозволи надаються автоматично під час встановлення застосунку без повідомлення або запиту до користувача. Вони покривають доступ до низькоризикових функцій, які не загрожують приватності користувача: INTERNET, ACCESS_NETWORK_STATE, VIBRATE, BLUETOOTH. Користувач не бачить діалогу згоди — дозвіл вважається наданим за фактом встановлення.

Розробнику не потрібно обробляти запит у коді для normal дозволів — достатньо оголосити їх у маніфесті. Однак в Android 12+ під час встановлення з Google Play користувач бачить вкладку «Дозволи» з переліком усіх normal дозволів, що підвищує прозорість. Згідно з Statista (2024), понад 90% застосунків у Google Play використовують INTERNET як найпоширеніший normal дозвіл.

Dangerous Permissions (runtime)

Dangerous дозволи покривають доступ до даних і функцій, які можуть порушити приватність: камера, мікрофон, геолокація, контакти, SMS, телефон, календар, датчики тіла. Ці дозволи вимагають двоетапного механізму: декларація в маніфесті + запит під час виконання через ActivityCompat.requestPermissions().

Користувач може відмовити в наданні dangerous дозволу, і застосунок повинен коректно обробити цей сценарій. В Android 11+ якщо користувач двічі відмовив, наступні запити не показують системний діалог — система автоматично повертає DENIED. У цьому випадку потрібно направляти користувача в налаштування.

Signature та Special Permissions

Рівень 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 дозволів і вимагає обґрунтування у формі під час публікації.

Runtime Permission: робота з dangerous дозволами

Починаючи з Android 6.0, всі dangerous дозволи вимагають запиту під час виконання. Розглянемо повний цикл роботи з runtime permissions на Kotlin.

Перевірка та запит дозволу

Перед викликом API, що вимагає dangerous дозволу, завжди перевіряйте поточний статус через ContextCompat.checkSelfPermission(). Якщо статус PERMISSION_GRANTED — можна викликати API. Якщо PERMISSION_DENIED — потрібно запитати дозвіл через ActivityResultContract RequestPermission (AndroidX) або застарілий requestPermissions().

Рекомендується використовувати ActivityResultContracts.RequestMultiplePermissions для запиту кількох дозволів одночасно. Google рекомендує групувати пов’язані дозволи (наприклад, камера + мікрофон для відеозапису) в один діалог, щоб користувач бачив повний контекст запиту.

kotlin
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 рекомендують показувати екран із поясненням цінності доступу, а не просто кнопку «Відкрити налаштування».

kotlin
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

Файл AndroidManifest.xml містить елемент для кожного дозволу, який використовує застосунок. Дозволи оголошуються на рівні перед елементом .

Синтаксис декларації

Кожен дозвіл оголошується окремим елементом з атрибутом android:name, що вказує повне ім’я дозволу. Для дозволів, що з’явилися в певних версіях Android, використовуйте атрибут maxSdkVersion, щоб обмежити декларацію лише потрібними версіями — це покращує сумісність.

Наприклад, дозвіл WRITE_EXTERNAL_STORAGE не потрібен на Android 10+ (Scoped Storage), тому вказуйте maxSdkVersion="28" (Android 9). Це запобігає зайвим питанням від користувачів на нових версіях. Android Studio попереджає про рекомендовані maxSdkVersion через Lint.

xml
<!-- 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>

Використання для фільтрації

Елемент вказує, що застосунку потрібне певне апаратне забезпечення (камера, GPS, NFC). Атрибут android:required="false" дозволяє встановлювати застосунок на пристрої без цього обладнання — перевірка доступності виконується в коді. Якщо required="true", Google Play фільтрує застосунок, і він стає недоступним для непідхожих пристроїв.

Рекомендується для всіх апаратних функцій вказувати required="false" і перевіряти доступність програмно через PackageManager.hasSystemFeature(). Це розширює аудиторію вашого застосунку. Єдиний виняток — якщо функція критична для роботи застосунку (застосунок для замовлення таксі без GPS не має сенсу).

Найкращі практики та помилки

Правильна робота з дозволами — ключовий аспект якості Android-застосунку. Розглянемо основні рекомендації та типові помилки.

Мінімізація дозволів, що запитуються

Запитуйте лише ті дозволи, які дійсно необхідні для роботи застосунку. Кожен зайвий дозвіл знижує конверсію встановлень і збільшує кількість відмов. Google Play Console показує, скільки користувачів відмовилися від встановлення через набір дозволів. За даними AppBrain (2024), застосунки з 10+ dangerous дозволами мають на 35% менше встановлень.

Регулярно переглядайте список дозволів. Видаляйте невикористовувані, особливо під час переходу на нові версії Android, де деякі дозволи стали необов’язковими. Наприклад, з появою фото-пікера (ActivityResultContracts.PickVisualMedia) в Android 13+ доступ до медіатеки можна отримувати без dangerous дозволу READ_MEDIA_IMAGES.

Показ rationale перед запитом

Перед запитом 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(). Не покладайтеся на кешування статусу дозволів — користувач може змінити їх у будь-який момент.

Типові помилки

  • Запит дозволу без попередньої перевірки checkSelfPermission — викличе зайвий діалог
  • Ігнорування shouldShowRequestPermissionRationale — погіршує UX після першої відмови
  • Запит дозволу без контексту (просто «Дозволити доступ?») — знижує згоду
  • Використання WRITE_EXTERNAL_STORAGE на Android 10+ без maxSdkVersion — зайвий запит
  • Відсутність перевірки дозволів в onResume — пропуск відкликання дозволу в налаштуваннях

Часті запитання

Чи потрібно декларувати дозвіл, якщо його запитує SDK?

Так, якщо SDK включає у свій маніфест дозвіл, він об’єднується з маніфестом застосунку під час збірки. Ви можете вимкнути непотрібний дозвіл SDK за допомогою tools:node="remove" в AndroidManifest.xml.

Що станеться, якщо не обробити відмову дозволу?

Виклик API без дозволу викличе SecurityException, що призведе до крашу застосунку. Завжди перевіряйте статус дозволу перед використанням відповідного API та обробляйте відмову коректно.

Як скинути дозволи в процесі розробки?

У налаштуваннях пристрою: Налаштування → Застосунки → [ваш застосунок] → Дозволи. Для скидання всіх дозволів використовуйте adb команду: adb shell pm reset-permissions.

Чи можна запитати дозвіл без Activity?

Так, за допомогою ActivityResultLauncher у Fragment або Service. Однак діалог запиту завжди вимагає UI-контексту Activity. Для Service ви можете показати Notification з Intent, що відкриває Activity із запитом.

Навіщо потрібен maxSdkVersion для дозволів?

Наприклад, WRITE_EXTERNAL_STORAGE не потрібен на Android 10+ (Scoped Storage). Вказавши android:maxSdkVersion="28", ви виключаєте декларацію дозволу на нових версіях, що покращує сумісність і зменшує список дозволів, що запитуються.

Підсумки

  • AndroidManifest Permissions — обов’язкові декларації доступу до системних ресурсів в Android
  • 4 рівні захисту — normal, dangerous, signature, special з різними механізмами надання
  • Runtime Permissions — dangerous дозволи вимагають запиту під час виконання (Android 6+)
  • Групи дозволів — згода на один дозвіл у групі дає доступ до всіх у групі
  • Rationale — показ пояснення перед запитом підвищує згоду на 20-30%
  • Мінімізація — запитуйте лише необхідні дозволи та використовуйте maxSdkVersion
  • Завжди перевіряйте статус дозволу перед викликом API та обробляйте всі сценарії відмови

Ми розробимо мобільний застосунок під ключ

IT Sectr створює застосунки для iOS та Android для стартапів і бізнесу з 2017 року. Ми проконсультуємо вас і запропонуємо найкраще рішення.

Обговорити проект

Читайте також