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