Если какой-либо функции вашего приложения требуется доступ к местоположению, подождите, пока пользователь не начнет взаимодействовать с этой функцией, прежде чем отправлять запрос на разрешение. Этот рабочий процесс соответствует передовой практике запроса разрешений во время выполнения в контексте, как описано в руководстве, объясняющем, как запрашивать разрешения для приложений .
На рис. 1 показан пример выполнения этого процесса. Приложение содержит функцию «поделиться местоположением», для которой требуется доступ к местоположению на переднем плане. Однако приложение не запрашивает разрешение на определение местоположения, пока пользователь не нажмет кнопку «Поделиться местоположением» .
Пользователь может предоставить только приблизительное местоположение
В Android 12 (уровень API 31) или более поздней версии пользователи могут запросить, чтобы ваше приложение получало только приблизительную информацию о местоположении, даже если ваше приложение запрашивает разрешение времени выполнения ACCESS_FINE_LOCATION
.
Чтобы справиться с этим потенциальным поведением пользователя, не запрашивайте разрешение ACCESS_FINE_LOCATION
само по себе. Вместо этого запросите разрешение ACCESS_FINE_LOCATION
и разрешение ACCESS_COARSE_LOCATION
в одном запросе во время выполнения. Если вы попытаетесь запросить только ACCESS_FINE_LOCATION
, система игнорирует запрос в некоторых выпусках Android 12. Если ваше приложение предназначено для Android 12 или более поздней версии, система регистрирует следующее сообщение об ошибке в Logcat :
ACCESS_FINE_LOCATION must be requested with ACCESS_COARSE_LOCATION.
Когда ваше приложение запрашивает как ACCESS_FINE_LOCATION
, так и ACCESS_COARSE_LOCATION
, диалоговое окно системных разрешений включает следующие параметры для пользователя:
- Точный : позволяет вашему приложению получать точную информацию о местоположении.
- Приблизительно : позволяет вашему приложению получать только приблизительную информацию о местоположении.
На рис. 3 показано, что диалоговое окно содержит визуальную подсказку для обоих вариантов, помогающую пользователю сделать выбор. После того, как пользователь принимает решение о точности местоположения, он нажимает одну из трех кнопок, чтобы выбрать продолжительность предоставления разрешения.
В Android 12 и более поздних версиях пользователи могут перейти к настройкам системы, чтобы установить предпочтительную точность определения местоположения для любого приложения, независимо от целевой версии SDK этого приложения. Это справедливо даже в том случае, если ваше приложение установлено на устройстве под управлением Android 11 или более ранней версии, а затем пользователь обновляет устройство до Android 12 или более поздней версии.
Выбор пользователя влияет на предоставление разрешений
В следующей таблице показаны разрешения, которые система предоставляет вашему приложению, на основе параметров, которые пользователь выбирает в диалоговом окне среды выполнения разрешений:
Точный | Приблизительный | |
---|---|---|
Во время использования приложения | ACCESS_FINE_LOCATION иACCESS_COARSE_LOCATION | ACCESS_COARSE_LOCATION |
Только на этот раз | ACCESS_FINE_LOCATION иACCESS_COARSE_LOCATION | ACCESS_COARSE_LOCATION |
Отрицать | Нет разрешений на определение местоположения | Нет разрешений на определение местоположения |
Чтобы определить, какие разрешения система предоставила вашему приложению, проверьте возвращаемое значение вашего запроса разрешений. Вы можете использовать библиотеки Jetpack в коде, аналогичном следующему, или вы можете использовать библиотеки платформы, где вы сами управляете кодом запроса разрешения .
Котлин
@RequiresApi(Build.VERSION_CODES.N) fun requestPermissions() { val locationPermissionRequest = registerForActivityResult( ActivityResultContracts.RequestMultiplePermissions() ) { permissions -> when { permissions.getOrDefault(Manifest.permission.ACCESS_FINE_LOCATION, false) -> { // Precise location access granted. } permissions.getOrDefault(Manifest.permission.ACCESS_COARSE_LOCATION, false) -> { // Only approximate location access granted. } else -> { // No location access granted. } } } // Before you perform the actual permission request, check whether your app // already has the permissions, and whether your app needs to show a permission // rationale dialog. For more details, see Request permissions: // https://developer.android.com/training/permissions/requesting#request-permission locationPermissionRequest.launch( arrayOf( Manifest.permission.ACCESS_FINE_LOCATION, Manifest.permission.ACCESS_COARSE_LOCATION ) ) }
Ява
private void requestPermissions() { ActivityResultLauncher<String[]> locationPermissionRequest = registerForActivityResult(new ActivityResultContracts .RequestMultiplePermissions(), result -> { Boolean fineLocationGranted = null; Boolean coarseLocationGranted = null; if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) { fineLocationGranted = result.getOrDefault( Manifest.permission.ACCESS_FINE_LOCATION, false); coarseLocationGranted = result.getOrDefault( Manifest.permission.ACCESS_COARSE_LOCATION,false); } if (fineLocationGranted != null && fineLocationGranted) { // Precise location access granted. } else if (coarseLocationGranted != null && coarseLocationGranted) { // Only approximate location access granted. } else { // No location access granted. } } ); // ... // Before you perform the actual permission request, check whether your app // already has the permissions, and whether your app needs to show a permission // rationale dialog. For more details, see Request permissions. locationPermissionRequest.launch(new String[] { Manifest.permission.ACCESS_FINE_LOCATION, Manifest.permission.ACCESS_COARSE_LOCATION }); }
Запросить повышение до точного местоположения
Вы можете попросить пользователя обновить доступ к вашему приложению с примерного местоположения до точного. Однако прежде чем попросить пользователя обновить доступ вашего приложения к точному местоположению, подумайте, действительно ли вариант использования вашего приложения абсолютно требует такого уровня точности. Если вашему приложению необходимо выполнить сопряжение устройства с соседними устройствами через Bluetooth или Wi-Fi, рассмотрите возможность использования сопряжения с сопутствующими устройствами или разрешений Bluetooth вместо запроса разрешения ACCESS_FINE_LOCATION
.
Чтобы запросить у пользователя обновление доступа к местоположению вашего приложения с приблизительного до точного, выполните следующие действия:
- При необходимости объясните, почему вашему приложению требуется разрешение .
- Снова запросите разрешения
ACCESS_FINE_LOCATION
иACCESS_COARSE_LOCATION
вместе. Поскольку пользователь уже разрешил системе предоставлять примерное местоположение вашему приложению, на этот раз системное диалоговое окно будет другим, как показано на рисунках 4 и 5:
Первоначально запрашивайте только местоположение на переднем плане
Даже если некоторые функции вашего приложения требуют доступа к местоположению, вполне вероятно, что только некоторые из них требуют фонового доступа к местоположению. Поэтому рекомендуется, чтобы ваше приложение выполняло дополнительные запросы на получение разрешений на определение местоположения, запрашивая доступ к приоритетному местоположению, а затем доступ к фоновому местоположению. Выполняя дополнительные запросы, вы предоставляете пользователям больше контроля и прозрачности, поскольку они могут лучше понять, каким функциям вашего приложения требуется фоновый доступ к местоположению.
На рис. 6 показан пример приложения, предназначенного для обработки дополнительных запросов. Функции «показать текущее местоположение» и «рекомендовать ближайшие места» требуют доступа к местоположению на переднем плане. Однако только функция «рекомендовать ближайшие места» требует доступа к фоновому местоположению.
Процесс выполнения дополнительных запросов выглядит следующим образом:
Сначала ваше приложение должно направлять пользователей к функциям, требующим доступа к местоположению на переднем плане, таким как функция «поделиться местоположением» на рис. 1 или функция «показать текущее местоположение» на рис. 2.
Рекомендуется отключить доступ пользователей к функциям, требующим доступа к фоновому местоположению, до тех пор, пока ваше приложение не получит доступ к данным о местоположении на переднем плане.
Позже, когда пользователь исследует функции, требующие фонового доступа к местоположению, вы можете запросить доступ к фоновому местоположению .
Дополнительные ресурсы
Для получения дополнительной информации о разрешениях местоположения в Android просмотрите следующие материалы:
Кодлабы
Видео
Образцы
- Пример приложения, демонстрирующий использование разрешений на определение местоположения.