Каждое приложение Android работает в песочнице с ограниченным доступом. Если вашему приложению необходимо использовать ресурсы или информацию за пределами своей песочницы, вы можете объявить разрешение во время выполнения и настроить запрос на предоставление этого доступа. Эти шаги являются частью рабочего процесса использования разрешений .
Если вы запрашиваете опасные разрешения , и если ваше приложение установлено на устройстве под управлением Android 6.0 (уровень API 23) или выше, вам необходимо запросить эти опасные разрешения во время выполнения, следуя инструкциям в этом руководстве.
Если вы не указываете никаких опасных разрешений или если ваше приложение установлено на устройстве под управлением Android 5.1 (уровень API 22) или ниже, разрешения предоставляются автоматически, и вам не нужно выполнять остальные шаги на этой странице.
Основные принципы
Основные принципы запроса разрешений во время выполнения программы следующие:
- Запросите разрешение в контексте, когда пользователь начинает взаимодействовать с функцией, которая этого требует.
- Не блокируйте пользователя. Всегда предоставляйте возможность отменить обучающий интерфейс, например, тот, который объясняет обоснование запроса разрешений.
- Если пользователь отклоняет или отзывает разрешение, необходимое для работы функции, плавно переведите приложение в более старую версию, чтобы пользователь мог продолжить его использование, возможно, отключив функцию, требующую этого разрешения.
- Не следует предполагать какое-либо поведение системы. Например, не следует предполагать, что разрешения находятся в одной группе разрешений . Группа разрешений лишь помогает системе минимизировать количество диалоговых окон, отображаемых пользователю, когда приложение запрашивает тесно связанные разрешения.
Порядок действий при запросе разрешений
Прежде чем запрашивать и объявлять разрешения во время выполнения вашего приложения, оцените, действительно ли вашему приложению это необходимо . Вы можете реализовать множество сценариев использования вашего приложения, таких как фотографирование, приостановка воспроизведения мультимедиа и показ релевантной рекламы, без необходимости объявлять какие-либо разрешения.
Если вы пришли к выводу, что вашему приложению необходимо объявлять и запрашивать разрешения во время выполнения, выполните следующие шаги:
- Укажите необходимые вашему приложению разрешения в файле манифеста.
- Разработайте пользовательский интерфейс (UX) вашего приложения таким образом, чтобы определенные действия в приложении были связаны с определенными разрешениями во время выполнения. Сообщите пользователям, для каких действий может потребоваться предоставление вашему приложению разрешения на доступ к личным данным пользователей.
- Дождитесь , пока пользователь запустит задачу или действие в вашем приложении, требующее доступа к определенным конфиденциальным данным пользователя. В этот момент ваше приложение может запросить необходимые разрешения во время выполнения для доступа к этим данным.
Проверьте, предоставил ли пользователь уже необходимые вашему приложению разрешения во время выполнения. Если да, то ваше приложение может получить доступ к личным данным пользователя. Если нет, перейдите к следующему шагу.
Необходимо проверять наличие у вас необходимых разрешений каждый раз, когда вы выполняете операцию, требующую таких разрешений.
Проверьте , должно ли ваше приложение отображать пользователю обоснование , объясняющее, почему приложению необходимо предоставить определенное разрешение во время выполнения. Если система определит, что приложение не должно отображать обоснование, перейдите непосредственно к следующему шагу, не отображая элемент пользовательского интерфейса.
Если система определит, что ваше приложение должно показать обоснование, представьте его пользователю в элементе пользовательского интерфейса. В этом обосновании четко объясните, к каким данным ваше приложение пытается получить доступ и какие преимущества приложение может предоставить пользователю, если он предоставит разрешение во время выполнения. После того, как пользователь подтвердит обоснование, перейдите к следующему шагу.
Запросите у вашего приложения необходимые разрешения во время выполнения для доступа к личным данным пользователя. Система отобразит запрос на предоставление разрешений во время выполнения, подобный тому, что показан на странице обзора разрешений .
Проверьте ответ пользователя — предоставил он или отклонил разрешение во время выполнения.
Если пользователь предоставил вашему приложению разрешение, вы можете получить доступ к личным данным пользователя. Если же пользователь отклонил разрешение, корректно переведите приложение в более доступное состояние , предоставив пользователю функциональность без доступа к информации, защищенной этим разрешением.
На рисунке 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(). Чтобы предоставить пользователю больше информации или контекста, измените пользовательский интерфейс приложения таким образом, чтобы пользователям было проще понять, почему для той или иной функции вашего приложения требуется определенное разрешение. Например, вы можете изменить текст на кнопке, которая включает эту функцию.Кроме того, текст в диалоговом окне системных разрешений ссылается на группу разрешений , связанную с запрошенным вами разрешением. Эта группировка разрешений предназначена для удобства использования системы, и ваше приложение не должно зависеть от того, находятся ли разрешения внутри или вне определенной группы разрешений.
Следующий фрагмент кода показывает, как обрабатывать ответ с запросом на предоставление прав доступа:
Котлин
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); }
Этот фрагмент кода демонстрирует рекомендуемый процесс проверки наличия разрешения и запроса разрешения у пользователя при необходимости:
Котлин
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() .
Следующий фрагмент кода демонстрирует, как запросить разрешение с помощью кода запроса:
Котлин
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() вашего приложения. Система передает ответ пользователя на диалоговое окно запроса разрешений, а также определенный вами код запроса, как показано в следующем фрагменте кода:
Котлин
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=">;loca<tion" ... !-- Any inner >e<lements >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_LOCATI>ON&q<uot; / !-- Include only if your app benefits from precise location >acc<ess. -- uses-permission android:name="android.permission.ACCESS_F>I<NE_LOCATI>ON" / /manifest
Фоновое местоположение
Приложению требуется доступ к местоположению в фоновом режиме, если какая-либо функция приложения постоянно передает данные о местоположении другим пользователям или использует API геозонирования . Вот несколько примеров:
- В приложении для обмена местоположением между членами семьи есть функция, позволяющая пользователям постоянно делиться своим местоположением с членами семьи.
- В приложениях для Интернета вещей есть функция, позволяющая пользователям настраивать свои домашние устройства таким образом, чтобы они выключались, когда пользователь покидает дом, и снова включались, когда пользователь возвращается домой.
Система считает, что ваше приложение использует определение местоположения в фоновом режиме, если оно обращается к текущему местоположению устройства в любой ситуации, кроме тех, которые описаны в разделе определения местоположения в активном режиме . Точность определения местоположения в фоновом режиме совпадает с точностью определения местоположения в активном режиме и зависит от разрешений на определение местоположения, которые ваше приложение запрашивает.
В 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_LOCATI>O<N" />
/manifest
Обработка отказа в предоставлении доступа
Если пользователь отклоняет запрос на разрешение, ваше приложение должно помочь пользователям понять последствия отказа. В частности, ваше приложение должно информировать пользователей о функциях, которые не будут работать из-за отсутствия разрешения. При этом следует учитывать следующие рекомендации:
Направьте внимание пользователя. Выделите определенную часть пользовательского интерфейса вашего приложения, где функциональность ограничена из-за отсутствия необходимых разрешений. Примеры того, что вы можете сделать, включают следующее:
- Отобразить сообщение там, где должны были бы появиться результаты или данные данной функции.
- Отобразить другую кнопку , содержащую значок ошибки и соответствующий цвет.
Будьте конкретны. Не используйте общие сообщения. Вместо этого четко укажите, какие функции недоступны, поскольку у вашего приложения нет необходимых разрешений.
Не блокируйте пользовательский интерфейс. Другими словами, не отображайте на весь экран предупреждающее сообщение, которое мешает пользователям продолжать использовать ваше приложение.
В то же время ваше приложение должно уважать решение пользователя об отказе в предоставлении разрешения. Начиная с Android 11 (уровень API 30), если пользователь нажимает «Отказать» для определенного разрешения более одного раза в течение всего времени работы вашего приложения на устройстве, диалоговое окно системных разрешений не отображается, если ваше приложение запросит это разрешение снова. Действие пользователя подразумевает «больше не запрашивать». В предыдущих версиях пользователи видели диалоговое окно системных разрешений каждый раз, когда ваше приложение запрашивало разрешение, если они предварительно не выбрали флажок или опцию «больше не запрашивать» .
Если пользователь отклоняет запрос на предоставление разрешения более одного раза, это считается окончательным отказом. Очень важно запрашивать у пользователей разрешения только тогда, когда им необходим доступ к определенной функции; в противном случае вы можете непреднамеренно потерять возможность повторного запроса разрешений.
В некоторых ситуациях разрешение может быть отклонено автоматически, без каких-либо действий со стороны пользователя. (Разрешение также может быть предоставлено автоматически.) Важно не делать никаких предположений об автоматическом поведении. Каждый раз, когда вашему приложению необходимо получить доступ к функциям, требующим разрешения, проверяйте, что вашему приложению по-прежнему предоставлено это разрешение.
Для обеспечения наилучшего пользовательского опыта при запросе разрешений для приложений, также ознакомьтесь с рекомендациями по использованию разрешений для приложений .
Проверяйте статус отказа при тестировании и отладке.
Чтобы определить, были ли приложению навсегда запрещены какие-либо разрешения (в целях отладки и тестирования), используйте следующую команду:
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-сообщений, и опубликовать свое приложение в Play Store, вам необходимо предложить пользователю установить ваше приложение в качестве обработчика по умолчанию для основной системной функции, прежде чем запрашивать эти разрешения во время выполнения.
Для получения дополнительной информации о обработчиках по умолчанию, включая рекомендации по отображению запроса на выбор обработчика по умолчанию для пользователей, см. руководство о разрешениях, используемых только в обработчиках по умолчанию .
Предоставьте все права доступа во время выполнения для целей тестирования.
Чтобы автоматически предоставить все разрешения во время выполнения при установке приложения на эмулятор или тестовое устройство, используйте параметр -g для команды adb shell install , как показано в следующем фрагменте кода:
adb shell install -g PATH_TO_APK_FILE
Дополнительные ресурсы
Для получения дополнительной информации о разрешениях ознакомьтесь с этими статьями:
Чтобы узнать больше о запросе разрешений, ознакомьтесь с примерами разрешений .
Вы также можете выполнить это практическое задание, демонстрирующее лучшие практики обеспечения конфиденциальности .