Прежде чем запрашивать доступ к данным о местоположении во время выполнения, ознакомьтесь с вариантами и рекомендациями по доступу к данным о местоположении и руководством по минимизации запросов разрешений. Эти ресурсы помогут вам решить, какое разрешение запрашивать и подходит ли для вашего случая кнопка геолокации.
Рекомендации по получению доступа к данным о местоположении
Общие правила, которым нужно следовать при принятии решения о том, как реализовать доступ к местоположению в приложении.
Доступ к местоположению в контексте
Если для работы функции в приложении требуется доступ к данным о местоположении, запрашивайте разрешение только после того, как пользователь начнет взаимодействовать с этой функцией. Это соответствует рекомендациям по запросу динамических разрешений в контексте, как описано в руководстве по запросу разрешений для приложения.
На рисунке 1 показано, как это сделать. В приложении есть функция "Поделиться местоположением", для которой требуется доступ к данным о местоположении в активном режиме. Однако приложение не запрашивает доступ к данным о местоположении, пока пользователь не нажмет кнопку Поделиться местоположением.
Пользователь может предоставить доступ только к приблизительному местоположению
Пользователи ОС Android 12 (уровень API 31) и более поздних версий могут ограничивать точность определения местоположения, даже если приложение использует динамическое разрешение ACCESS_FINE_LOCATION.
Чтобы избежать этого, не запрашивайте разрешение ACCESS_FINE_LOCATION отдельно. Вместо этого запросите разрешение ACCESS_FINE_LOCATION и разрешение ACCESS_COARSE_LOCATION в одном динамическом запросе. Если вы попытаетесь запросить только ACCESS_FINE_LOCATION, система проигнорирует запрос в некоторых выпусках Android 12. Если целевой уровень API вашего приложения – 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 можно найти в следующих материалах:
Практические работы
Видео
Образцы
- Пример приложения, в котором показано, как использовать разрешения на доступ к данным о местоположении.