Если функция вашего приложения требует доступа к данным о местоположении, дождитесь, пока пользователь взаимодействует с этой функцией, прежде чем запрашивать разрешение. Этот рабочий процесс соответствует передовой практике запроса разрешений во время выполнения в контексте, как описано в руководстве, объясняющем, как запрашивать разрешения для приложения .
На рисунке 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_COARSE_LOCATION
. ACCESS_FINE_LOCATION
и ACCESS_COARSE_LOCATION
в одном запросе времени выполнения. Выбор пользователя влияет на предоставление разрешений
В следующей таблице показаны разрешения, которые система предоставляет вашему приложению на основе параметров, которые пользователь выбирает в диалоговом окне разрешений во время выполнения:
Точный | Приблизительный | |
---|---|---|
Во время использования приложения | 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 можно найти в следующих материалах:
Codelabs
Видео
Образцы
- Пример приложения , демонстрирующего использование разрешений на определение местоположения.