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