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