Каждое приложение 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()
. Чтобы предоставить пользователю больше информации или контекста, измените пользовательский интерфейс приложения, чтобы пользователям было проще понять, зачем той или иной функции требуется то или иное разрешение. Например, вы можете изменить текст на кнопке, активирующей эту функцию.Кроме того, текст в диалоговом окне системных разрешений ссылается на группу разрешений , связанную с запрошенным вами разрешением. Эта группа разрешений разработана для удобства использования системы, и ваше приложение не должно полагаться на разрешения, находящиеся внутри или вне определённой группы разрешений.
В следующем фрагменте кода показано, как обрабатывать ответ о разрешениях:
Котлин
// Register the permissions callback, which handles the user's response to the // system permissions dialog. Save the return value, an instance of // ActivityResultLauncher. You can use either a val, as shown in this snippet, // or a lateinit var in your onAttach() or onCreate() method. val requestPermissionLauncher = registerForActivityResult(RequestPermission() ) { isGranted: Boolean -> if (isGranted) { // 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. } }
Ява
// Register the permissions callback, which handles the user's response to the // system permissions dialog. Save the return value, an instance of // ActivityResultLauncher, as an instance variable. private ActivityResultLauncher<String> requestPermissionLauncher = registerForActivityResult(new RequestPermission(), isGranted -> { if (isGranted) { // 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. } });
А этот фрагмент кода демонстрирует рекомендуемый процесс проверки наличия разрешения и запроса разрешения у пользователя при необходимости:
Котлин
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) } }
Ява
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) } }
Ява
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. } } }
Ява
@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>
Фоновое местоположение
Приложению требуется доступ к данным о местоположении в фоновом режиме, если его функция постоянно передает данные о местоположении другим пользователям или использует 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>
Обработка отказа в разрешении
Если пользователь отклоняет запрос на разрешение, ваше приложение должно помочь пользователям понять последствия отказа. В частности, приложение должно информировать пользователей о функциях, которые не работают из-за отсутствия разрешения. При этом учитывайте следующие рекомендации:
Направьте внимание пользователя. Выделите определённую часть пользовательского интерфейса вашего приложения, функциональность которой ограничена из-за отсутствия у приложения необходимых разрешений. Вот несколько примеров того, что вы можете сделать:
- Показывать сообщение там, где должны были появиться результаты или данные функции.
- Отобразить другую кнопку, содержащую значок ошибки и цвет.
Будьте конкретны. Не показывайте общее сообщение. Вместо этого чётко укажите, какие функции недоступны из-за отсутствия у вашего приложения необходимого разрешения.
Не блокируйте пользовательский интерфейс. Другими словами, не выводите полноэкранное предупреждение, которое не позволяет пользователям продолжать использовать ваше приложение.
В то же время ваше приложение должно учитывать решение пользователя отказать в предоставлении разрешения. Начиная с 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 — имя разрешения, которое вы хотите сбросить.
Чтобы просмотреть полный список разрешений приложений Android, посетите справочную страницу API разрешений .
Одноразовые разрешения
Начиная с Android 11 (уровень API 30), всякий раз, когда ваше приложение запрашивает разрешение, связанное с местоположением, микрофоном или камерой, диалоговое окно разрешений, отображаемое для пользователя, содержит параметр, называемый Только в этот раз , как показано на рисунке 2. Если пользователь выбирает этот параметр в диалоговом окне, вашему приложению предоставляется временное одноразовое разрешение .
Затем ваше приложение может получить доступ к соответствующим данным в течение определенного периода времени, который зависит от поведения вашего приложения и действий пользователя:
- Пока активность вашего приложения видна, ваше приложение может получать доступ к данным.
- Если пользователь переводит ваше приложение в фоновый режим, оно может продолжать получать доступ к данным в течение короткого периода времени.
- Если вы запускаете службу переднего плана, пока активность видима, а затем пользователь переводит ваше приложение в фоновый режим, ваше приложение может продолжать получать доступ к данным до тех пор, пока служба переднего плана не остановится.
Процесс приложения завершается при отзыве разрешения
Если пользователь отменит одноразовое разрешение, например, в системных настройках, ваше приложение не сможет получить доступ к данным, независимо от того, запущена ли служба переднего плана. Как и в случае с любым разрешением, отзыв пользователем одноразового разрешения приложения приводит к его завершению.
Когда пользователь в следующий раз откроет ваше приложение и функция в вашем приложении запросит доступ к местоположению, микрофону или камере, пользователю снова будет предложено предоставить разрешение.
Сбросить неиспользуемые разрешения
Android предоставляет несколько способов сброса неиспользуемых разрешений среды выполнения до состояния по умолчанию, когда им отказано:
- API, с помощью которого вы можете заблаговременно закрыть своему приложению доступ к неиспользуемому разрешению времени выполнения.
- Системный механизм, который автоматически сбрасывает разрешения неиспользуемых приложений .
Удалить доступ к приложению
В Android 13 (уровень API 33) и более поздних версиях вы можете запретить приложению доступ к разрешениям времени выполнения, которые ему больше не требуются. При обновлении приложения выполните этот шаг, чтобы пользователи лучше понимали, почему ваше приложение продолжает запрашивать определённые разрешения. Это поможет повысить доверие пользователей к вашему приложению.
Чтобы удалить доступ к разрешению времени выполнения, передайте имя этого разрешения в revokeSelfPermissionOnKill()
. Чтобы удалить доступ к группе разрешений времени выполнения одновременно, передайте коллекцию имён разрешений в revokeSelfPermissionsOnKill()
. Процесс удаления разрешения происходит асинхронно и завершает все процессы, связанные с UID вашего приложения.
Чтобы система закрыла вашему приложению доступ к разрешениям, все процессы, связанные с вашим приложением, должны быть завершены. При вызове API система определяет, когда можно безопасно завершить эти процессы. Обычно система ожидает, пока ваше приложение не проработает длительное время в фоновом режиме, а не на переднем плане.
Чтобы сообщить пользователю, что вашему приложению больше не требуется доступ к определённым разрешениям времени выполнения, при следующем запуске приложения отобразите диалоговое окно. Это диалоговое окно может содержать список разрешений.
Автоматический сброс разрешений неиспользуемых приложений
Если ваше приложение предназначено для Android 11 (API уровня 30) или выше и не используется в течение нескольких месяцев, система защищает пользовательские данные, автоматически сбрасывая конфиденциальные разрешения времени выполнения, предоставленные пользователем вашему приложению. Подробнее см. в руководстве о спящем режиме приложений .
При необходимости запросите возможность стать обработчиком по умолчанию.
Некоторым приложениям необходим доступ к конфиденциальной информации пользователя, связанной с журналами вызовов и SMS-сообщениями. Если вы хотите запросить разрешения, относящиеся к журналам вызовов и SMS-сообщениям, и опубликовать приложение в Play Маркете, вам необходимо предложить пользователю установить ваше приложение в качестве обработчика по умолчанию для основной системной функции, прежде чем запрашивать эти разрешения для выполнения.
Дополнительную информацию об обработчиках по умолчанию, включая рекомендации по отображению запроса обработчика по умолчанию для пользователей, см. в руководстве о разрешениях, используемых только в обработчиках по умолчанию .
Предоставьте все разрешения на выполнение для целей тестирования.
Чтобы автоматически предоставить все разрешения времени выполнения при установке приложения на эмуляторе или тестовом устройстве, используйте опцию -g
для команды adb shell install
, как показано в следующем фрагменте кода:
adb shell install -g PATH_TO_APK_FILE
Дополнительные ресурсы
Дополнительную информацию о разрешениях можно найти в следующих статьях:
Чтобы узнать больше о запросе разрешений, ознакомьтесь с примерами разрешений.
Вы также можете выполнить эту лабораторную работу, демонстрирующую лучшие практики обеспечения конфиденциальности .