Каждое приложение Android запускается в изолированной среде с ограниченным доступом. Если приложению требуется доступ к ресурсам или информации за пределами его собственной изолированной среды, вы можете объявить динамическое разрешение и настроить запрос разрешений, который предоставляет такой доступ. Эти шаги являются частью рабочего процесса по использованию разрешений.
Если вы запрашиваете опасные разрешения и ваше приложение установлено на устройстве с Android 6.0 (уровень API 23) или более поздней версии, вы должны запрашивать опасные разрешения во время выполнения, следуя инструкциям в этом руководстве.
Если вы не запрашиваете опасные разрешения или ваше приложение установлено на устройстве с Android 5.1 (уровень API 22) или более ранней версии, разрешения предоставляются автоматически и вам не нужно выполнять остальные действия, описанные на этой странице.
Основные принципы
Основные принципы запроса разрешений во время выполнения:
- Запрашивайте разрешение в контексте, когда пользователь начинает взаимодействовать с функцией, для которой оно требуется.
- Не блокировать пользователя. У пользователей всегда должна быть возможность отменить обучающий процесс, например объяснение того, зачем нужны разрешения.
- Если пользователь отказался предоставить доступ или отменил его, примените стратегию постепенного сокращения, при этом сохранив работоспособность приложения. Рекомендуем также отключить функцию, для которой требуются разрешения.
- Не делайте предположений о поведении системы. Например, не предполагайте, что разрешения относятся к одной и той же группе разрешений. Группа разрешений просто помогает системе минимизировать количество системных диалоговых окон, которые показываются пользователю, когда приложение запрашивает тесно связанные разрешения.
Как запросить разрешения
Прежде чем объявлять и запрашивать динамические разрешения, определите, нужны ли они вашему приложению. Многие функции, например фотосъемка, приостановка воспроизведения медиаконтента и показ релевантной рекламы, можно реализовать без объявления разрешений.
Если вы решите, что в приложении нужно объявить и запросить динамические разрешения, выполните следующие действия:
- Объявите разрешения, которые могут потребоваться вашему приложению, в его файле манифеста.
- Разработайте пользовательский интерфейс приложения так, чтобы определенные действия в нем были связаны с конкретными динамическими разрешениями. Сообщите пользователям, какие действия могут потребовать от них предоставления разрешения на доступ вашего приложения к личным данным пользователя.
- Дождитесь, пока пользователь запустит в приложении задачу или действие, для которых требуется доступ к определенным личным данным. В этот момент приложение может запросить динамическое разрешение, необходимое для доступа к этим данным.
Проверьте, предоставил ли пользователь
динамическое разрешение, которое требуется вашему приложению. Если да, то приложение может получить доступ к личным данным пользователя. Если нет, переходите к следующему пункту.
Вы должны проверять наличие разрешения каждый раз, когда выполняете операцию, которая его требует.
Проверьте, нужно ли показывать пользователю обоснование, объясняющее, почему приложению требуется определенное динамическое разрешение. Если система определит, что приложение не должно показывать обоснование, перейдите к следующему шагу, не показывая элемент пользовательского интерфейса.
Если система определит, что ваше приложение должно показать обоснование, представьте его пользователю в элементе пользовательского интерфейса. В этом обосновании четко объясните, к каким данным приложение пытается получить доступ и какие преимущества оно может предоставить пользователю, если он предоставит динамическое разрешение. После того как пользователь подтвердит, что понял причину, перейдите к следующему шагу.
Запросите динамическое разрешение, которое требуется вашему приложению для доступа к личным пользовательским данным. Система показывает запрос на динамическое разрешение, например такой, как на обзорной странице разрешений.
Проверьте ответ пользователя – предоставил ли он динамическое разрешение.
Если пользователь предоставил разрешение вашему приложению, вы можете получить доступ к его личным данным. Если пользователь отклонил запрос, обеспечьте постепенное сокращение функциональности приложения, чтобы оно работало без информации, защищенной этим разрешением.
На рисунке 1 показан рабочий процесс и набор решений, связанных с этим процессом:
Как определить, есть ли у приложения разрешение
Чтобы проверить, предоставил ли пользователь вашему приложению определенное разрешение, передайте это разрешение в метод ContextCompat.checkSelfPermission().
Этот метод возвращает PERMISSION_GRANTED или PERMISSION_DENIED в зависимости от того, есть ли у приложения разрешение.
Объясните, почему приложению требуется разрешение
В диалоговом окне, которое появляется при вызове метода requestPermissions(), указано, какое разрешение запрашивает приложение, но не объясняется, зачем оно нужно. В некоторых случаях это может вызвать у пользователя недоумение. Рекомендуется объяснить пользователю, зачем приложению нужны разрешения, прежде чем вызывать requestPermissions().
Исследования показывают, что пользователи гораздо охотнее предоставляют разрешения, если понимают, зачем они нужны, например для работы основной функции приложения или для показа рекламы. Если вы используете только часть вызовов API, относящихся к группе разрешений, укажите, какие именно разрешения вы используете и зачем. Например, если вы используете только приблизительное местоположение, сообщите об этом в описании приложения или справочных статьях о нем.
В некоторых случаях также полезно сообщать пользователям о доступе к конфиденциальным данным в режиме реального времени. Например, если приложение использует камеру или микрофон, сообщите об этом пользователю с помощью значка уведомления в приложении или на панели уведомлений (если приложение работает в фоновом режиме). Так у пользователя не возникнет ощущения, что вы собираете данные тайно.
Если для работы функции требуется разрешение, но пользователю не очевидно, зачем оно нужно, объясните, почему вы запрашиваете разрешение на доступ к конфиденциальной информации.
Если метод ContextCompat.checkSelfPermission() возвращает PERMISSION_DENIED, вызовите shouldShowRequestPermissionRationale(). Если этот метод возвращает true, покажите пользователю обучающий интерфейс. В этом интерфейсе опишите, почему функция, которую хочет включить пользователь, требует определенного разрешения.
Если приложение запрашивает разрешение на доступ к местоположению, микрофону или камере, рекомендуем объяснить, зачем это нужно.
Запросить разрешения
После того как пользователь увидит обучающий интерфейс или возвращаемое значение shouldShowRequestPermissionRationale() укажет, что показывать обучающий интерфейс не нужно, запросите разрешение. Пользователи видят диалоговое окно, в котором могут предоставить приложению определенное разрешение.
Для этого используйте контракт RequestPermission, включенный в библиотеку AndroidX, который позволяет системе управлять кодом запроса разрешения за вас. Поскольку использование контракта RequestPermission упрощает логику, это рекомендуемое решение, когда это возможно. Однако при необходимости вы можете самостоятельно управлять кодом запроса в рамках запроса разрешений и включить этот код в логику обратного вызова.
Разрешить системе управлять кодом запроса разрешения
Чтобы система могла управлять кодом запроса, связанным с запросом разрешений, добавьте зависимости от следующих библиотек в файл build.gradle вашего модуля:
androidx.activityверсии 1.2.0 или более поздней;androidx.fragmentверсии 1.3.0 или более поздней.
Затем вы можете использовать один из следующих классов:
- Чтобы запросить одно разрешение, используйте
RequestPermission. - Чтобы запросить несколько разрешений одновременно, используйте
RequestMultiplePermissions.
Ниже описано, как использовать контракт RequestPermission. Процесс почти такой же, как и для контракта RequestMultiplePermissions.
В логике инициализации действия или фрагмента передайте реализацию
ActivityResultCallbackв вызовregisterForActivityResult().ActivityResultCallbackопределяет, как приложение обрабатывает ответ пользователя на запрос разрешения.Сохраните ссылку на возвращаемое значение
registerForActivityResult(), которое имеет типActivityResultLauncher.Чтобы при необходимости показать диалоговое окно системных разрешений, вызовите метод
launch()для экземпляраActivityResultLauncher, сохраненного на предыдущем шаге.После вызова
launch()появляется диалоговое окно системных разрешений. Когда пользователь делает выбор, система асинхронно вызывает вашу реализациюActivityResultCallback, которую вы определили на предыдущем шаге.Примечание. В приложении нельзя настроить диалоговое окно, которое появляется при вызове
launch(). Чтобы предоставить пользователю больше информации или контекста, измените интерфейс приложения так, чтобы пользователям было проще понять, зачем функции в вашем приложении требуется определенное разрешение. Например, можно изменить текст на кнопке, которая включает функцию.Кроме того, в тексте диалогового окна упоминается группа разрешений, связанная с запрашиваемым разрешением. Такая группировка разрешений предназначена для удобства использования системы, и ваше приложение не должно полагаться на то, что разрешения находятся внутри или за пределами определенной группы разрешений.
В следующем фрагменте кода показано, как обрабатывать ответ на запрос разрешений:
Kotlin
when { ContextCompat.checkSelfPermission( CONTEXT, Manifest.permission.REQUESTED_PERMISSION ) == PackageManager.PERMISSION_GRANTED -> { // You can use the API that requires the permission. performAction(...) } ActivityCompat.shouldShowRequestPermissionRationale( this, Manifest.permission.REQUESTED_PERMISSION) -> { // In an educational UI, explain to the user why your app requires this // permission for a specific feature to behave as expected, and what // features are disabled if it's declined. In this UI, include a // "cancel" or "no thanks" button that lets the user continue // using your app without granting the permission. showInContextUI(...) } else -> { // You can directly ask for the permission. requestPermissions(CONTEXT, arrayOf(Manifest.permission.REQUESTED_PERMISSION), REQUEST_CODE) } }
Java
if (ContextCompat.checkSelfPermission( CONTEXT, Manifest.permission.REQUESTED_PERMISSION) == PackageManager.PERMISSION_GRANTED) { // You can use the API that requires the permission. performAction(...); } else if (ActivityCompat.shouldShowRequestPermissionRationale( this, Manifest.permission.REQUESTED_PERMISSION)) { // In an educational UI, explain to the user why your app requires this // permission for a specific feature to behave as expected, and what // features are disabled if it's declined. In this UI, include a // "cancel" or "no thanks" button that lets the user continue // using your app without granting the permission. showInContextUI(...); } else { // You can directly ask for the permission. requestPermissions(CONTEXT, new String[] { Manifest.permission.REQUESTED_PERMISSION }, REQUEST_CODE); }
А этот фрагмент кода демонстрирует рекомендуемый процесс проверки разрешения и запроса разрешения у пользователя при необходимости:
Kotlin
when { ContextCompat.checkSelfPermission( CONTEXT, Manifest.permission.REQUESTED_PERMISSION ) == PackageManager.PERMISSION_GRANTED -> { // You can use the API that requires the permission. } ActivityCompat.shouldShowRequestPermissionRationale( this, Manifest.permission.REQUESTED_PERMISSION) -> { // In an educational UI, explain to the user why your app requires this // permission for a specific feature to behave as expected, and what // features are disabled if it's declined. In this UI, include a // "cancel" or "no thanks" button that lets the user continue // using your app without granting the permission. showInContextUI(...) } else -> { // You can directly ask for the permission. // The registered ActivityResultCallback gets the result of this request. requestPermissionLauncher.launch( Manifest.permission.REQUESTED_PERMISSION) } }
Java
if (ContextCompat.checkSelfPermission( CONTEXT, Manifest.permission.REQUESTED_PERMISSION) == PackageManager.PERMISSION_GRANTED) { // You can use the API that requires the permission. performAction(...); } else if (ActivityCompat.shouldShowRequestPermissionRationale( this, Manifest.permission.REQUESTED_PERMISSION)) { // In an educational UI, explain to the user why your app requires this // permission for a specific feature to behave as expected, and what // features are disabled if it's declined. In this UI, include a // "cancel" or "no thanks" button that lets the user continue // using your app without granting the permission. showInContextUI(...); } else { // You can directly ask for the permission. // The registered ActivityResultCallback gets the result of this request. requestPermissionLauncher.launch( Manifest.permission.REQUESTED_PERMISSION); }
Управляйте кодом запроса разрешений самостоятельно
Вместо того чтобы разрешать системе управлять кодом запроса разрешений, вы можете управлять им самостоятельно. Для этого включите код запроса в вызов requestPermissions().
В следующем фрагменте кода показано, как запросить разрешение с помощью кода запроса:
Kotlin
when { ContextCompat.checkSelfPermission( CONTEXT, Manifest.permission.REQUESTED_PERMISSION ) == PackageManager.PERMISSION_GRANTED -> { // You can use the API that requires the permission. performAction(...) } ActivityCompat.shouldShowRequestPermissionRationale( this, Manifest.permission.REQUESTED_PERMISSION) -> { // In an educational UI, explain to the user why your app requires this // permission for a specific feature to behave as expected, and what // features are disabled if it's declined. In this UI, include a // "cancel" or "no thanks" button that lets the user continue // using your app without granting the permission. showInContextUI(...) } else -> { // You can directly ask for the permission. requestPermissions(CONTEXT, arrayOf(Manifest.permission.REQUESTED_PERMISSION), REQUEST_CODE) } }
Java
if (ContextCompat.checkSelfPermission( CONTEXT, Manifest.permission.REQUESTED_PERMISSION) == PackageManager.PERMISSION_GRANTED) { // You can use the API that requires the permission. performAction(...); } else if (ActivityCompat.shouldShowRequestPermissionRationale( this, Manifest.permission.REQUESTED_PERMISSION)) { // In an educational UI, explain to the user why your app requires this // permission for a specific feature to behave as expected, and what // features are disabled if it's declined. In this UI, include a // "cancel" or "no thanks" button that lets the user continue // using your app without granting the permission. showInContextUI(...); } else { // You can directly ask for the permission. requestPermissions(CONTEXT, new String[] { Manifest.permission.REQUESTED_PERMISSION }, REQUEST_CODE); }
После того как пользователь ответит на запрос, система вызовет метод onRequestPermissionsResult(). Система передает ответ пользователя в диалоговое окно разрешения, а также код запроса, который вы определили, как показано в следующем фрагменте кода:
Kotlin
override fun onRequestPermissionsResult(requestCode: Int, permissions: Array<String>, grantResults: IntArray) { when (requestCode) { PERMISSION_REQUEST_CODE -> { // If request is cancelled, the result arrays are empty. if ((grantResults.isNotEmpty() && grantResults[0] == PackageManager.PERMISSION_GRANTED)) { // Permission is granted. Continue the action or workflow // in your app. } else { // Explain to the user that the feature is unavailable because // the feature requires a permission that the user has denied. // At the same time, respect the user's decision. Don't link to // system settings in an effort to convince the user to change // their decision. } return } // Add other 'when' lines to check for other // permissions this app might request. else -> { // Ignore all other requests. } } }
Java
@Override public void onRequestPermissionsResult(int requestCode, String[] permissions, int[] grantResults) { switch (requestCode) { case PERMISSION_REQUEST_CODE: // If request is cancelled, the result arrays are empty. if (grantResults.length > 0 && grantResults[0] == PackageManager.PERMISSION_GRANTED) { // Permission is granted. Continue the action or workflow // in your app. } else { // Explain to the user that the feature is unavailable because // the feature requires a permission that the user has denied. // At the same time, respect the user's decision. Don't link to // system settings in an effort to convince the user to change // their decision. } return; } // Other 'case' lines to check for other // permissions this app might request. } }
Запрос доступа к данным о местоположении
Запрашивая доступ к данным о местоположении, следуйте тем же рекомендациям, что и для других динамических разрешений. Важное отличие разрешений на доступ к данным о местоположении заключается в том, что в системе есть несколько разрешений, связанных с местоположением. Какие разрешения вы запрашиваете и как вы это делаете, зависит от требований к местоположению для вашего приложения.
Доступ к данным о местоположении в активном режиме
Если в приложении есть функция, которая передает или получает данные о местоположении только один раз или в течение определенного времени, то ей требуется доступ к геоданным в активном режиме. Вот несколько примеров:
- В навигационном приложении есть функция, которая позволяет пользователям получать пошаговые инструкции.
- В мессенджере есть функция, которая позволяет пользователям делиться своим текущим местоположением с другими пользователями.
Система считает, что приложение использует данные о местоположении в активном режиме, если функция приложения получает доступ к текущему местоположению устройства в одной из следующих ситуаций:
- Действие, которое относится к вашему приложению, видно.
Приложение использует активную службу. Когда активная служба запущена, система показывает пользователю постоянное уведомление. Приложение сохраняет доступ, когда работает в фоновом режиме, например когда пользователь нажимает кнопку Главный экран или выключает экран устройства.
В Android 10 (уровень API 29) и более поздних версиях необходимо объявить тип активной службы
location, как показано в следующем фрагменте кода. В более ранних версиях Android мы рекомендуем объявлять этот тип активной службы.<!-- Recommended for Android 9 (API level 28) and lower. --> <!-- Required for Android 10 (API level 29) and higher. --> <service android:name="MyNavigationService" android:foregroundServiceType="location" ... > <!-- Any inner elements go here. --> </service>
Чтобы запросить доступ к данным о местоположении в активном режиме, добавьте в приложение разрешение ACCESS_COARSE_LOCATION или ACCESS_FINE_LOCATION, как показано в следующем фрагменте кода:
<manifest ... > <!-- Include this permission any time your app needs location information. --> <uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" /> <!-- Include only if your app benefits from precise location access. --> <uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" /> </manifest>
Доступ к геоданным в фоновом режиме
Доступ к данным о местоположении в фоновом режиме требуется, если функция в приложении постоянно передает информацию о местоположении другим пользователям или использует Geofencing API. Вот несколько примеров:
- В приложении для семейного обмена геоданными есть функция, которая позволяет пользователям постоянно делиться своим местоположением с членами семьи.
- В приложении для IoT есть функция, которая позволяет пользователям настраивать устройства умного дома так, чтобы они выключались, когда пользователь уходит из дома, и включались, когда он возвращается.
Доступ к данным о местоположении в фоновом режиме – это доступ к текущему местоположению устройства в любых ситуациях, кроме описанных в разделе Доступ к данным о местоположении в активном режиме. Точность определения местоположения в фоновом режиме такая же, как и точная геолокация в активном режиме, и зависит от разрешений на доступ к данным о местоположении, которые запрашивает приложение.
В Android 10 (уровень API 29) и более поздних версиях необходимо объявить разрешение ACCESS_BACKGROUND_LOCATION в манифесте приложения, чтобы запрашивать доступ к данным о местоположении в фоновом режиме во время выполнения. В более ранних версиях Android, когда приложение получает доступ к данным о местоположении в активном режиме, оно автоматически получает доступ к данным о местоположении в фоновом режиме.
<manifest ... >
<!-- Required only when requesting background location access on
Android 10 (API level 29) and higher. -->
<uses-permission android:name="android.permission.ACCESS_BACKGROUND_LOCATION" />
</manifest>
Обработка отказа в разрешении
Если пользователь отклоняет запрос разрешения, ваше приложение должно помочь ему понять последствия этого действия. В частности, вы должны сообщить пользователям, какие функции не работают из-за отсутствия разрешения. При этом следуйте приведенным ниже рекомендациям.
- Минимизация потери функциональности. Пользователи должны иметь возможность работать с приложением в максимально возможном объеме без предоставления запрашиваемых разрешений. Если функция работает хотя бы частично, лучше оставить ее включенной.
Направляйте внимание пользователя. Выделите определенную часть интерфейса приложения, где функциональность ограничена из-за отсутствия необходимого разрешения. Вот что можно сделать:
- Показывать сообщение там, где должны были появиться результаты или данные функции.
- Покажите другую кнопку со значком и цветом ошибки.
Выделяйте в названии конкретные черты товара. Не показывайте стандартное сообщение. Вместо этого четко объясните, какие функции недоступны из-за отсутствия разрешения.
Не блокируйте пользовательский интерфейс. Другими словами, не показывайте полноэкранное предупреждение, которое не позволяет пользователям продолжить работу с приложением.
Примите выбор пользователя. Вы можете сообщить пользователю, как отсутствие доступа к запрашиваемым разрешениям повлияет на функциональность приложения, но не должны заставлять его изменить свое решение. Важно сообщить пользователю, что он не получит доступ ко всем функциям, когда это уместно (например, при попытке использовать часть приложения, заблокированную без разрешения), но постоянные напоминания о необходимости пересмотреть свое решение не уважают его выбор.
Следуя этим рекомендациям, вы поможете пользователям управлять доступом к своим личным данным в соответствии с их ценностями. Если вы не будете уважать решения пользователей, касающиеся конфиденциальности, это подорвет доверие к вашему приложению и всей экосистеме.
Кроме того, если пользователь нажмет "Отклонить" для определенного разрешения более одного раза за время использования приложения на устройстве, он больше не увидит системное диалоговое окно разрешений, если приложение снова запросит это разрешение. Действие пользователя подразумевает "больше не спрашивать" и считается постоянным отказом. Запрашивайте разрешения только тогда, когда пользователям нужен доступ к определенной функции. В противном случае вы можете случайно потерять возможность повторно запрашивать разрешения. В некоторых случаях разрешение может быть отклонено автоматически, без каких-либо действий со стороны пользователя. (Разрешение также может быть предоставлено автоматически.) Не стоит полагаться на автоматические действия. Каждый раз, когда приложению требуется доступ к функции, для которой необходимо разрешение, проверяйте, предоставлено ли оно. Чтобы пользователям было удобно предоставлять разрешения, ознакомьтесь с рекомендациями по работе с разрешениями для приложений.
Как проверить статус отклонения при тестировании и отладке
Чтобы определить, было ли приложению навсегда отказано в разрешениях (для отладки и тестирования), используйте следующую команду:
adb shell dumpsys package PACKAGE_NAME
где PACKAGE_NAME – название пакета, который нужно проверить.
Выходные данные команды содержат разделы, которые выглядят следующим образом:
... runtime permissions: android.permission.POST_NOTIFICATIONS: granted=false, flags=[ USER_SENSITIVE_WHEN_GRANTED|USER_SENSITIVE_WHEN_DENIED] android.permission.ACCESS_FINE_LOCATION: granted=false, flags=[ USER_SET|USER_FIXED|USER_SENSITIVE_WHEN_GRANTED|USER_SENSITIVE_WHEN_DENIED] android.permission.BLUETOOTH_CONNECT: granted=false, flags=[ USER_SENSITIVE_WHEN_GRANTED|USER_SENSITIVE_WHEN_DENIED] ...
Разрешения, в которых пользователь отказал один раз, помечаются значком USER_SET.
Разрешения, которые были отклонены навсегда (вы дважды нажали Запретить), помечаются значком USER_FIXED.
Чтобы тестировщики видели диалоговое окно запроса, сбросьте эти флаги после отладки приложения. Для этого используйте следующую команду:
adb shell pm clear-permission-flags PACKAGE_NAME PERMISSION_NAME user-set user-fixed
PERMISSION_NAME – название разрешения, которое нужно сбросить.
PERMISSION_NAME – название разрешения, которое нужно сбросить.
Полный список разрешений для приложений Android можно найти на странице документации по API разрешений.
Разовые разрешения
Начиная с Android 11 (уровень API 30), когда приложение запрашивает разрешение на доступ к данным о местоположении, микрофону или камере, в пользовательском диалоговом окне разрешений появляется вариант Только в этот раз, как показано на рисунке 2. Если пользователь выберет этот вариант, приложению будет предоставлено временное разовое разрешение.
После этого приложение сможет получать доступ к связанным данным в течение определенного периода времени, который зависит от поведения приложения и действий пользователя:
- Пока действия в приложении видны, оно может получать доступ к данным.
- Если пользователь переводит приложение в фоновый режим, оно может продолжать получать доступ к данным в течение короткого периода времени.
- Если вы запустите активную службу, пока действие видно, а затем пользователь переведет приложение в фоновый режим, оно сможет получать доступ к данным, пока активная служба не остановится.
Процесс приложения завершается, когда разрешение отзывается
Если пользователь отзовет разовое разрешение, например в системных настройках, приложение не сможет получить доступ к данным, даже если вы запустили активную службу. Как и в случае с любым другим разрешением, если пользователь отзовет разовое разрешение, процесс приложения будет завершен.
Когда пользователь в следующий раз откроет приложение и функция запросит доступ к местоположению, микрофону или камере, пользователь снова увидит запрос разрешения.
Сбросить неиспользуемые разрешения
В Android есть несколько способов сбросить неиспользуемые динамические разрешения до состояния по умолчанию (запрещено):
- API, с помощью которого можно отзывать у приложения доступ к неиспользуемым динамическим разрешениям.
- Системный механизм, который автоматически сбрасывает разрешения неиспользуемых приложений.
Как закрыть доступ к приложению
В Android 13 (уровень API 33) и более поздних версиях можно отзывать у приложения динамические разрешения, которые ему больше не нужны. При обновлении приложения выполните этот шаг, чтобы пользователи понимали, почему оно продолжает запрашивать определенные разрешения. Это помогает укрепить доверие пользователей к вашему приложению.
Чтобы закрыть доступ к динамическому разрешению, передайте его название в revokeSelfPermissionOnKill(). Чтобы отозвать доступ к группе динамических разрешений, передайте коллекцию названий разрешений в revokeSelfPermissionsOnKill(). Процесс отзыва разрешений происходит асинхронно и завершает все процессы, связанные с UID вашего приложения.
Чтобы система могла отозвать разрешения, все процессы, связанные с приложением, должны быть завершены. При вызове API система определяет, когда можно безопасно завершить эти процессы. Обычно система ждет, пока приложение не проведет длительное время в фоновом режиме.
Чтобы сообщить пользователю, что приложению больше не требуется доступ к определенным динамическим разрешениям, покажите диалоговое окно при следующем запуске приложения. В этом окне можно указать список разрешений.
Автоматический отзыв разрешений для неиспользуемых приложений
Если ваше приложение предназначено для Android 11 (уровень API 30) или более поздней версии и не используется в течение нескольких месяцев, система защищает пользовательские данные, автоматически сбрасывая конфиденциальные динамические разрешения, которые пользователь предоставил вашему приложению. Подробнее об этом рассказывается в руководстве по гибернации приложений.
Запрос на назначение обработчиком по умолчанию (при необходимости)
Некоторым приложениям требуется доступ к конфиденциальной информации пользователей, связанной со списками вызовов и SMS. Если вы хотите запросить разрешения на доступ к спискам вызовов и SMS-сообщениям и опубликовать приложение в Google Play, то перед запросом динамических разрешений предложите пользователю сделать ваше приложение обработчиком по умолчанию для основной системной функции.
Дополнительную информацию об обработчиках по умолчанию, в том числе о том, как показывать пользователям запрос на выбор обработчика по умолчанию, можно найти в руководстве по разрешениям, которые используются только в обработчиках по умолчанию.
Предоставить все динамические разрешения для тестирования
Чтобы автоматически предоставить все динамические разрешения при установке приложения на эмулятор или тестовое устройство, используйте параметр -g для команды adb shell install, как показано в следующем фрагменте кода:
adb shell install -g PATH_TO_APK_FILE
Дополнительные ресурсы
Дополнительную информацию о разрешениях можно найти в следующих статьях:
Чтобы узнать больше о запросе разрешений, ознакомьтесь с примерами.
Вы также можете выполнить практическую работу, посвященную рекомендациям по обеспечению конфиденциальности.