Запросить разрешения на определение местоположения

Чтобы защитить конфиденциальность пользователей, приложения, использующие службы определения местоположения, должны запрашивать разрешения на определение местоположения.

При запросе разрешений на определение местоположения следуйте тем же рекомендациям, что и для любого другого разрешения во время выполнения . Одним из важных отличий, когда речь идет о разрешениях на местоположение, является то, что система включает в себя несколько разрешений, связанных с местоположением. Какие разрешения вы запрашиваете и как вы их запрашиваете, зависит от требований к местоположению для варианта использования вашего приложения.

На этой странице описаны различные типы требований к местоположению и приведены инструкции о том, как запросить разрешения на определение местоположения в каждом случае.

Типы доступа к местоположению

Каждое разрешение имеет комбинацию следующих характеристик:

Расположение на переднем плане

Если ваше приложение содержит функцию, которая передает или получает информацию о местоположении только один раз или в течение определенного периода времени, то для этой функции требуется доступ к приоритетному местоположению. Некоторые примеры включают следующее:

  • В навигационном приложении функция позволяет пользователям получать пошаговые инструкции.
  • В приложении для обмена сообщениями есть функция, позволяющая пользователям делиться своим текущим местоположением с другим пользователем.

Система считает, что ваше приложение использует местоположение на переднем плане, если функция вашего приложения обращается к текущему местоположению устройства в одной из следующих ситуаций:

  • Видно действие, принадлежащее вашему приложению.
  • В вашем приложении запущена служба переднего плана. Когда служба приоритетного режима запущена, система повышает осведомленность пользователей, показывая постоянное уведомление. Ваше приложение сохраняет доступ, когда оно находится в фоновом режиме, например, когда пользователь нажимает кнопку «Домой» на своем устройстве или выключает дисплей своего устройства.

    Кроме того, рекомендуется объявить приоритетный тип службы location , как показано в следующем фрагменте кода. В Android 10 (уровень API 29) и более поздних версиях необходимо объявить этот тип службы переднего плана.

    <!-- Recommended for Android 9 (API level 28) and lower. -->
    <!-- Required for Android 10 (API level 29) and higher. -->
    <service
        android:name="MyNavigationService"
        android:foregroundServiceType="location" ... >
        <!-- Any inner elements would go here. -->
    </service>
    

Вы заявляете о необходимости определения местоположения на переднем плане, когда ваше приложение запрашивает либо разрешение ACCESS_COARSE_LOCATION , либо разрешение ACCESS_FINE_LOCATION , как показано в следующем фрагменте:

<manifest ... >
  <!-- Always include this permission -->
  <uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />

  <!-- Include only if your app benefits from precise location access. -->
  <uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
</manifest>

Фоновое расположение

Приложению требуется доступ к фоновому местоположению, если функция в приложении постоянно передает местоположение другим пользователям или использует API геозон . Несколько примеров включают следующее:

  • В приложении для обмена семейным местоположением функция позволяет пользователям постоянно делиться своим местоположением с членами семьи.
  • В приложении IoT функция позволяет пользователям настраивать свои домашние устройства таким образом, чтобы они выключались, когда пользователь выходит из дома, и снова включались, когда пользователь возвращается домой.

Система считает, что ваше приложение использует фоновое местоположение, если оно обращается к текущему местоположению устройства в любой ситуации, кроме описанной в разделе о местоположении на переднем плане . Точность фонового местоположения такая же, как и точность местоположения переднего плана , которая зависит от разрешений на местоположение, объявленных вашим приложением.

В Android 10 (уровень API 29) и более поздних версиях вы должны объявить разрешение ACCESS_BACKGROUND_LOCATION в манифесте вашего приложения, чтобы запрашивать фоновый доступ к местоположению во время выполнения. В более ранних версиях Android, когда ваше приложение получает доступ к местоположению на переднем плане, оно также автоматически получает доступ к местоположению в фоновом режиме.

<manifest ... >
  <!-- Required only when requesting background location access on
       Android 10 (API level 29) and higher. -->
  <uses-permission android:name="android.permission.ACCESS_BACKGROUND_LOCATION" />
</manifest>

Точность

Android поддерживает следующие уровни точности определения местоположения:

Приблизительный
Обеспечивает оценку местоположения устройства. Если эта оценка местоположения получена из LocationManagerService или FusedLocationProvider , точность этой оценки составляет около 3 квадратных километров (около 1,2 квадратных миль). Ваше приложение может получать местоположения с этим уровнем точности, если вы объявите разрешение ACCESS_COARSE_LOCATION , но не разрешение ACCESS_FINE_LOCATION .
Точный
Обеспечивает максимально точную оценку местоположения устройства. Если оценка местоположения получена с помощью LocationManagerService или FusedLocationProvider , эта оценка обычно находится в пределах около 50 метров (160 футов) и иногда достигает точности в пределах нескольких метров (10 футов) или лучше. Ваше приложение может получать местоположения с этим уровнем точности, если вы объявите разрешение ACCESS_FINE_LOCATION .

Если пользователь предоставляет разрешение на приблизительное местоположение , ваше приложение имеет доступ только к приблизительному местоположению, независимо от того, какие разрешения на определение местоположения объявлены в вашем приложении.

Ваше приложение должно по-прежнему работать, даже если пользователь предоставляет только приблизительный доступ к местоположению. Если функция вашего приложения абсолютно требует доступа к точному местоположению с использованием разрешения ACCESS_FINE_LOCATION , вы можете попросить пользователя разрешить вашему приложению доступ к точному местоположению .

Запросить доступ к местоположению во время выполнения

Если какой-либо функции вашего приложения требуется доступ к местоположению, подождите, пока пользователь не начнет взаимодействовать с этой функцией, прежде чем отправлять запрос на разрешение. Этот рабочий процесс соответствует передовой практике запроса разрешений во время выполнения в контексте, как описано в руководстве, объясняющем, как запрашивать разрешения для приложений .

На рис. 1 показан пример выполнения этого процесса. Приложение содержит функцию «поделиться местоположением», для которой требуется доступ к местоположению на переднем плане. Однако приложение не запрашивает разрешение на определение местоположения, пока пользователь не нажмет кнопку «Поделиться местоположением» .

После того, как пользователь нажмет кнопку «Поделиться местоположением», появится диалоговое окно разрешения на определение местоположения в системе.
Рис. 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 или более поздней версии.

Диалог относится только к приблизительному местоположению и содержит 3 кнопки, расположенные одна над другой.
Рисунок 2. Диалоговое окно системных разрешений, которое появляется, когда ваше приложение запрашивает только ACCESS_COARSE_LOCATION .
В диалоговом окне есть два набора параметров, один над другим.
Рисунок 3. Диалоговое окно системных разрешений, которое появляется, когда ваше приложение запрашивает 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 в коде, аналогичном следующему, или вы можете использовать библиотеки платформы, где вы сами управляете кодом запроса разрешения .

Котлин

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.
locationPermissionRequest.launch(arrayOf(
    Manifest.permission.ACCESS_FINE_LOCATION,
    Manifest.permission.ACCESS_COARSE_LOCATION))

Ява

ActivityResultLauncher<String[]> locationPermissionRequest =
    registerForActivityResult(new ActivityResultContracts
        .RequestMultiplePermissions(), result -> {
            Boolean fineLocationGranted = result.getOrDefault(
                    Manifest.permission.ACCESS_FINE_LOCATION, false);
            Boolean 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 .

Чтобы запросить у пользователя обновление доступа к местоположению вашего приложения с приблизительного до точного, выполните следующие действия:

  1. При необходимости объясните, почему вашему приложению требуется разрешение .
  2. Снова запросите разрешения ACCESS_FINE_LOCATION и ACCESS_COARSE_LOCATION вместе. Поскольку пользователь уже разрешил системе предоставлять приблизительное местоположение вашему приложению, на этот раз системное диалоговое окно будет другим, как показано на рисунках 4 и 5 :
Диалоговое окно содержит параметры «Изменить точное местоположение», «Только в этот раз» и «Запретить».
Рис. 4. Пользователь ранее выбрал «Приблизительно» и «При использовании приложения» (в диалоговом окне на рис. 3 ).
Диалог содержит параметры «Только в этот раз» и «Запретить».
Рисунок 5. Ранее пользователь выбрал «Приблизительно» и «Только в этот раз» (в диалоге с рисунка 3 ).

Первоначально запрашивайте только местоположение на переднем плане

Даже если некоторые функции вашего приложения требуют доступа к местоположению, вполне вероятно, что только некоторые из них требуют фонового доступа к местоположению. Поэтому рекомендуется, чтобы ваше приложение выполняло дополнительные запросы на получение разрешений на определение местоположения, запрашивая доступ к приоритетному местоположению, а затем доступ к фоновому местоположению. Выполняя дополнительные запросы, вы предоставляете пользователям больше контроля и прозрачности, поскольку они могут лучше понять, каким функциям вашего приложения требуется фоновый доступ к местоположению.

На рис. 6 показан пример приложения, предназначенного для обработки дополнительных запросов. Для функций «показать текущее местоположение» и «рекомендовать ближайшие места» требуется доступ к местоположению на переднем плане. Однако только функция «рекомендовать ближайшие места» требует доступа к фоновому местоположению.

Кнопка, которая включает доступ к местоположению на переднем плане, расположена на половине длины экрана от кнопки, которая включает доступ к местоположению на заднем плане.
Рисунок 6. Обе функции требуют доступа к местоположению, но только функция «рекомендовать близлежащие функции» требует доступа к фоновому местоположению.

Процесс выполнения дополнительных запросов выглядит следующим образом:

  1. Сначала ваше приложение должно направлять пользователей к функциям, требующим доступа к местоположению на переднем плане, таким как функция «поделиться местоположением» на рис. 1 или функция «показать текущее местоположение» на рис. 2.

    Рекомендуется отключить доступ пользователей к функциям, требующим доступа к фоновому местоположению, до тех пор, пока ваше приложение не получит доступ к данным о местоположении на переднем плане.

  2. Позже, когда пользователь изучает функции, требующие фонового доступа к местоположению, вы можете запросить доступ к фоновому местоположению .

При необходимости запросите фоновое местоположение.

Рис. 7. На странице настроек есть опция « Разрешить постоянно» , которая предоставляет фоновый доступ к местоположению.

Содержимое диалогового окна разрешений зависит от целевой версии SDK.

Когда функция вашего приложения запрашивает фоновое местоположение на устройстве под управлением Android 10 (уровень API 29), в диалоговом окне системных разрешений появляется параметр «Разрешить все время» . Если пользователь выберет этот вариант, функция вашего приложения получит доступ к фоновому местоположению.

Однако в Android 11 (уровень API 30) и более поздних версиях системное диалоговое окно не включает параметр «Разрешить постоянно» . Вместо этого пользователи должны включить фоновое расположение на странице настроек, как показано на рисунке 7.

Вы можете помочь пользователям перейти на эту страницу настроек, следуя рекомендациям при запросе разрешения на фоновое местоположение. Процесс предоставления разрешения зависит от целевой версии SDK вашего приложения.

Приложение предназначено для Android 11 или более поздней версии

Если вашему приложению не предоставлено разрешение ACCESS_BACKGROUND_LOCATION и shouldShowRequestPermissionRationale() возвращает true , покажите пользователям обучающий пользовательский интерфейс, который включает в себя следующее:

  • Четкое объяснение того, почему функции вашего приложения необходим доступ к фоновому местоположению.
  • Видимая пользователем метка параметра настроек, предоставляющая фоновое расположение (например, «Разрешить все время» на рис. 7). Вы можете вызвать getBackgroundPermissionOptionLabel() чтобы получить эту метку. Возвращаемое значение этого метода локализовано в соответствии с языковыми предпочтениями устройства пользователя.
  • Возможность для пользователей отклонить разрешение. Если пользователи откажутся от доступа к фоновому местоположению, они смогут продолжить использовать ваше приложение.
Пользователи могут нажать на системное уведомление, чтобы изменить настройки местоположения для приложения.
Рисунок 8. Уведомление, напоминающее пользователю, что он предоставил приложению доступ к фоновому местоположению.

Приложение предназначено для Android 10 или более ранней версии

Когда функция вашего приложения запрашивает доступ к фоновому местоположению, пользователи видят системное диалоговое окно. В этом диалоговом окне есть возможность перейти к параметрам разрешения местоположения вашего приложения на странице настроек.

Поскольку ваше приложение уже следует рекомендациям по запросу разрешений на определение местоположения, вам не нужно вносить какие-либо изменения для поддержки такого поведения.

Пользователь может повлиять на точность определения местоположения в фоновом режиме

Если пользователь запрашивает приблизительное местоположение , выбор пользователя в диалоговом окне разрешений местоположения также применяется к фоновому местоположению. Другими словами, если пользователь предоставляет вашему приложению разрешение ACCESS_BACKGROUND_LOCATION , но предоставляет только приблизительный доступ к местоположению на переднем плане, ваше приложение также имеет только приблизительный доступ к местоположению в фоновом режиме.

Напоминание о предоставлении фонового местоположения

В Android 10 и более поздних версиях, когда функция вашего приложения впервые получает доступ к местоположению устройства в фоновом режиме после того, как пользователь предоставляет доступ к фоновому местоположению, система планирует отправку пользователю уведомления. Это уведомление напоминает пользователю, что он разрешил вашему приложению постоянно получать доступ к местоположению устройства. Пример уведомления показан на рисунке 8.

Проверьте требования к местоположению в зависимостях SDK вашего приложения.

Проверьте, использует ли ваше приложение какие-либо SDK, зависящие от разрешений на местоположение, особенно разрешение ACCESS_FINE_LOCATION . Прочитайте эту статью на Medium о том , как узнать поведение зависимостей вашего SDK .

Дополнительные ресурсы

Для получения дополнительной информации о разрешениях местоположения в Android просмотрите следующие материалы:

Кодлабы

Видео

Образцы

  • Пример приложения, демонстрирующий использование разрешений на определение местоположения.