Как объявлять разрешения в манифесте?
Комментарии (3)
Ответ сгенерирован нейросетью и может содержать ошибки
Объявление разрешений в AndroidManifest.xml
Работа с разрешениями в Android — фундаментальный аспект разработки, требующий строгого соблюдения правил безопасности и конфиденциальности пользователей. Разрешения объявляются в файле AndroidManifest.xml, который является главным конфигурационным файлом приложения.
Основные типы разрешений
Android делит разрешения на несколько категорий:
- Обычные (Normal) разрешения — не представляют риска для приватности пользователя. Система предоставляет их автоматически при установке приложения. Например,
android.permission.VIBRATEилиandroid.permission.INTERNET. - Опасные (Dangerous) разрешения — затрагивают приватность или могут повлиять на данные/операции пользователя. Требуют явного запроса и получения согласия пользователя во время выполнения (runtime). Например,
android.permission.CAMERA,android.permission.READ_CONTACTS. - Сигнатурные (Signature) разрешения — предоставляются автоматически, если запрашивающее приложение подписано тем же сертификатом, что и приложение, объявившее разрешение. Используются для безопасного взаимодействия между приложениями одного разработчика.
- Особые (Special) разрешения — например,
SYSTEM_ALERT_WINDOWилиWRITE_SETTINGS. Их запрос происходит по уникальным, нестандартным сценариям.
Синтаксис объявления в манифесте
Для объявления разрешения, которое ваше приложение будет использовать, используется элемент <uses-permission>. Он помещается на верхнем уровне манифеста, как дочерний для корневого элемента <manifest>.
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.example.myapp">
<!-- Запрос на использование разрешения -->
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE"
android:maxSdkVersion="28" /> <!-- Атрибут для обратной совместимости -->
<application ...>
...
</application>
</manifest>
Если вы создаете приложение-провайдер, которое предоставляет функциональность другим приложениям, и хотите защитить её, вы объявляете собственное разрешение с помощью элемента <permission>.
<manifest ...>
<!-- Объявление собственного опасного разрешения -->
<permission
android:name="com.example.myapp.permission.ACCESS_PREMIUM_DATA"
android:label="Доступ к премиум-данным"
android:description="Разрешает доступ к закрытому премиум-контенту"
android:protectionLevel="dangerous" />
<application ...>
...
</application>
</manifest>
Ключевые атрибуты элемента <permission>:
android:name— Уникальное имя разрешения (обычно с префиксом пакета).android:protectionLevel— Уровень защиты:"normal","dangerous","signature"и др. Определяет, как система будет обрабатывать запрос.android:labelиandroid:description— Человекочитаемые строки, которые система показывает пользователю при запросе.
Запрос опасных разрешений во время выполнения (Runtime)
Объявления в манифесте недостаточно для опасных разрешений. Начиная с Android 6.0 (API 23), их необходимо запрашивать динамически в коде активности или фрагмента.
Базовый алгоритм:
- Проверить наличие разрешения с помощью
ContextCompat.checkSelfPermission(). - Если разрешение не предоставлено, запросить его с помощью
ActivityCompat.requestPermissions(). - Обработать результат запроса в переопределенном методе
onRequestPermissionsResult().
// Пример в Activity или Fragment (Kotlin)
private val PERMISSION_REQUEST_CODE = 1001
private val REQUIRED_PERMISSION = Manifest.permission.ACCESS_FINE_LOCATION
fun checkOrRequestPermission() {
// 1. Проверяем текущий статус
when {
ContextCompat.checkSelfPermission(this, REQUIRED_PERMISSION) == PackageManager.PERMISSION_GRANTED -> {
// Разрешение уже есть, выполняем нужную операцию
startLocationUpdates()
}
shouldShowRequestPermissionRationale(REQUIRED_PERMISSION) -> {
// 2. Объясняем пользователю, зачем нужно разрешение (опционально)
showRationaleDialog("Для отображения вашего местоположения на карте необходимо разрешение на доступ к геолокации.") {
// После объяснения запрашиваем
requestPermissions(arrayOf(REQUIRED_PERMISSION), PERMISSION_REQUEST_CODE)
}
}
else -> {
// 3. Запрашиваем разрешение напрямую
requestPermissions(arrayOf(REQUIRED_PERMISSION), PERMISSION_REQUEST_CODE)
}
}
}
// 4. Обрабатываем ответ пользователя
override fun onRequestPermissionsResult(
requestCode: Int,
permissions: Array<String>,
grantResults: IntArray
) {
super.onRequestPermissionsResult(requestCode, permissions, grantResults)
if (requestCode == PERMISSION_REQUEST_CODE) {
if (grantResults.isNotEmpty() && grantResults[0] == PackageManager.PERMISSION_GRANTED) {
startLocationUpdates() // Разрешение получено
} else {
showMessage("Разрешение отклонено. Функционал локации недоступен.") // Разрешение отклонено
}
}
}
Современный подход с Activity Result API
В современных приложениях рекомендуется использовать Activity Result API (registerForActivityResult с контрактом ActivityResultContracts.RequestPermission), который является более декларативным и упрощает управление жизненным циклом.
// Объявление лаунчера для запроса разрешения
private val requestPermissionLauncher = registerForActivityResult(
ActivityResultContracts.RequestPermission()
) { isGranted: Boolean ->
if (isGranted) {
startLocationUpdates()
} else {
showMessage("Разрешение необходимо для работы функции.")
}
}
// Использование
fun requestPermission() {
requestPermissionLauncher.launch(Manifest.permission.ACCESS_FINE_LOCATION)
}
Важные принципы и лучшие практики
- Запрашивайте разрешения контекстно, непосредственно перед выполнением операции, которая в них нуждается.
- Всегда предоставляйте четкое объяснение (
rationale), зачем приложению нужно разрешение. Используйте диалоги или другие UI-элементы. - Уважайте отказ пользователя. Ваше приложение должно корректно работать даже при отклонении разрешения, предлагая альтернативные функции или ограниченный режим.
- Помните о группах разрешений. Запросив одно разрешение из группы (например,
ACCESS_FINE_LOCATION), приложение получает доступ и к другим разрешениям в этой группе (например,ACCESS_COARSE_LOCATION), но для ясности кода их все равно лучше проверять отдельно. - Тестируйте сценарии как предоставления, так и отклонения разрешений, а также их отзыва в настройках системы.
Грамотная работа с разрешениями — это не только техническое требование, но и важная часть UX, напрямую влияющая на доверие пользователей и рейтинг приложения в магазине.
fff