Данные о местоположении

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

Примеры кода

Репозиторий ApiDemos на сайте GitHub содержит пример, который демонстрирует использование данных о местоположении на карте.

Работа с данными о местоположении

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

  • Слой Мое местоположение представляет собой простой способ отобразить местонахождение устройства на карте. Он не возвращает никаких данных.
  • Для всех программных запросов данных рекомендуется использовать Location API сервисов Google Play.
  • Интерфейс LocationSource позволяет использовать собственный источник данных о местоположении.

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

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

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

  • android.permission.ACCESS_COARSE_LOCATION позволяет использовать точки доступа Wi-Fi и/или мобильные данные, чтобы определять приблизительное местоположение устройства. API предоставляет информацию о местоположении с точностью примерно до городского квартала.
  • android.permission.ACCESS_FINE_LOCATION позволяет API максимально точно определять местоположение на основании информации, предоставляемой поставщиками данных о местоположении, включая глобальную систему позиционирования (GPS), сеть Wi-Fi и мобильные данные.

Добавление разрешений в манифест приложения

Добавьте одно из следующих разрешений в качестве дочернего для элемента <manifest> в манифесте Android. Укажите разрешение для данных о приблизительном местоположении:

<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="com.example.myapp" >
  ...
  <uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION"/>
  ...
</manifest>

Или разрешение для данных о точном местоположении:

<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="com.example.myapp" >
  ...
  <uses-permission android:name="android.permission.ACCESS_FINE_LOCATION"/>
  ...
</manifest>

Запрос разрешений в среде выполнения

В Android 6.0 (Marshmallow) представлена новая модель работы с разрешениями, которая оптимизирует процесс установки и обновления приложений пользователями. Если ваше приложение предназначено для API уровня 23 или более позднего, вы можете использовать новую модель разрешений.

Если приложение поддерживает новую модель разрешений, а на устройстве используется Android 6.0 (Marshmallow) или более новая версия, пользователю не нужно предоставлять какие-либо разрешения при установке приложения или его обновлении. Пользователь увидит диалоговое окно с просьбой предоставить соответствующее разрешение.

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

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

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

В следующем примере кода проверка разрешения выполняется с использованием библиотеки поддержки перед включением слоя "Мое местоположение":

if (ContextCompat.checkSelfPermission(this, Manifest.permission.ACCESS_FINE_LOCATION)
        == PackageManager.PERMISSION_GRANTED) {
    if (mMap != null) {
        mMap.setMyLocationEnabled(true);
    }
} else {
    // Permission to access the location is missing. Show rationale and request permission
    PermissionUtils.requestPermission(this, LOCATION_PERMISSION_REQUEST_CODE,
        Manifest.permission.ACCESS_FINE_LOCATION, true);
}

В следующем примере результат запроса разрешения обрабатывается путем реализации ActivityCompat.OnRequestPermissionsResultCallback из библиотеки поддержки.

@Override
public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {
    if (requestCode != LOCATION_PERMISSION_REQUEST_CODE) {
        return;
    }

    if (PermissionUtils.isPermissionGranted(permissions, grantResults, Manifest.permission.ACCESS_FINE_LOCATION)) {
        // Enable the my location layer if the permission has been granted.
        enableMyLocation();
    } else {
        // Permission was denied. Display an error message
        // ...
    }
}

Другие примеры кода и практические рекомендации для работы с разрешениями в среде выполнения Android приведены в документации для модели разрешений Android.

Слой "Мое местоположение"

Слой "Мое местоположение" и одноименная кнопка позволяют пользователям видеть свое актуальное местоположение на карте. Чтобы включить слой "Мое местоположение", вызовите mMap.setMyLocationEnabled().

Простой пример использования слоя "Мое местоположение":

public class MyLocationDemoActivity extends FragmentActivity
    implements OnMyLocationButtonClickListener,
        OnMyLocationClickListener,
        OnMapReadyCallback {

  private GoogleMap mMap;

  @Override
  protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.my_location_demo);

    SupportMapFragment mapFragment =
        (SupportMapFragment) getSupportFragmentManager().findFragmentById(R.id.map);
    mapFragment.getMapAsync(this);
  }

  @Override
  public void onMapReady(GoogleMap map) {
    mMap = map;
    // TODO: Before enabling the My Location layer, you must request
    // location permission from the user. This sample does not include
    // a request for location permission.
    mMap.setMyLocationEnabled(true);
    mMap.setOnMyLocationButtonClickListener(this);
    mMap.setOnMyLocationClickListener(this);
  }

  @Override
  public void onMyLocationClick(@NonNull Location location) {
    Toast.makeText(this, "Current location:\n" + location, Toast.LENGTH_LONG).show();
  }

  @Override
  public boolean onMyLocationButtonClick() {
    Toast.makeText(this, "MyLocation button clicked", Toast.LENGTH_SHORT).show();
    // Return false so that we don't consume the event and the default behavior still occurs
    // (the camera animates to the user's current position).
    return false;
  }
}

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

На скриншоте ниже вы можете увидеть кнопку "Мое местоположение" справа вверху и синюю точку в центре карты.

Чтобы предотвратить показ кнопки "Мое местоположение", вызовите UiSettings.setMyLocationButtonEnabled(false).

Ваше приложение может реагировать на следующие события:

  • Если пользователь нажимает кнопку "Мое местоположение", ваше приложение получает обратный вызов onMyLocationButtonClick() от прослушивателя GoogleMap.OnMyLocationButtonClickListener.
  • Если пользователь нажимает кнопку "Мое местоположение", ваше приложение получает обратный вызов onMyLocationClick() от прослушивателя GoogleMap.OnMyLocationClickListener.

Важный пункт Условий использования

Обеспечивайте конфиденциальность пользователей,
информируйте их о том, что происходит в приложении.

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

Подробнее…

Location API сервисов Google Play

Данные о местоположении в приложениях для Android лучше всего обрабатывать с помощью Location API сервисов Google Play. Он позволяет выполнять следующие задачи:

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

Разные варианты Location API упрощают работу с данными в приложении и помогают экономить ресурсы системы. Как и Maps SDK for Android, Location API распространяется как часть SDK сервисов Google Play. Дополнительную информацию вы можете найти в учебном материале об использовании в приложении данных о местоположении, а также в документации по Location API. Примеры кода содержатся в SDK сервисов Google Play.