Android: LocationManager vs Google Play Services

Я хочу создать приложение, которое сосредотачивается вокруг получения текущего местоположения пользователя, а затем найдет точки интереса (например, бары, рестораны и т.д.), которые находятся рядом с ним через API Google Адресов. > .

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

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

Каковы различия между этими двумя методами поиска местоположений (если они есть)?

Ответ 1

Расположение пользователя на Android

Получить местоположение пользователя на Android немного проще, чем на iOS. Чтобы начать путаницу, есть два совершенно разных способа сделать это. Первый использует API-интерфейсы Android от android.location.LocationListener, а второй - API-интерфейсы сервисов Google Play com.google.android.gms.location.LocationListener. Давайте пройдем через них обоих.

  1. Android Location API

    API определения местоположения Android используют три разных провайдера для определения местоположения.

    • LocationManager.GPS_PROVIDER - этот провайдер определяет местоположение с помощью спутников. В зависимости от условий этому провайдеру может потребоваться некоторое время для возврата местоположения.
    • LocationManager.NETWORK_PROVIDER - этот поставщик определяет местоположение на основе доступности вышки сотовой связи и точек доступа WiFi. Результаты извлекаются с помощью поиска в сети.
    • LocationManager.PASSIVE_PROVIDER - этот провайдер возвращает местоположения, созданные другими провайдерами. Вы пассивно получаете обновления местоположения, когда другие приложения или службы запрашивают их, фактически не запрашивая местоположения самостоятельно.

Суть его в том, что вы получаете объект LocationManager из системы, внедряете LocationListener и вызываете requestLocationUpdates для LocationManager.

Вот фрагмент кода:

    LocationManager locationManager = (LocationManager) this.getSystemService(Context.LOCATION_SERVICE);
// Define a listener that responds to location updates
LocationListener locationListener = new LocationListener() {
    public void onLocationChanged(Location location) {
      // Called when a new location is found by the network location provider.
      makeUseOfNewLocation(location);
    }

    public void onStatusChanged(String provider, int status, Bundle extras) {}

    public void onProviderEnabled(String provider) {}

    public void onProviderDisabled(String provider) {}
  };

// Register the listener with the Location Manager to receive location updates
locationManager.requestLocationUpdates(LocationManager.NETWORK_PROVIDER, 0, 0, locationListener);

Руководство Googles API по стратегиям размещения довольно хорошо объясняет код. Но они также отмечают, что в большинстве случаев вы получите лучшую производительность батареи, а также более высокую точность, используя вместо этого API Google Location Services. Теперь путаница начинается!

  1. Googles Location Services API

Googles Location Services API является частью Google Play Services APK (вот как его настроить). Они построены на основе Androids API. Эти API предоставляют "Поставщик слияния" вместо провайдеров, упомянутых выше. Этот провайдер автоматически выбирает, какого основного провайдера использовать, основываясь на точности, использовании батареи и т.д. Это происходит быстро, потому что вы получаете местоположение из общесистемной службы, которая постоянно обновляет ее. И вы можете использовать более продвинутые функции, такие как геозоны.

Для использования Служб определения местоположения Googles вашему приложению необходимо подключиться к GooglePlayServicesClient. Чтобы подключиться к клиенту, ваша деятельность (или фрагмент, или около того) должна реализовывать интерфейсы GooglePlayServicesClient.ConnectionCallbacks и GooglePlayServicesClient.OnConnectionFailedListener. Вот пример кода:

    public class MyActivity extends Activity implements ConnectionCallbacks, OnConnectionFailedListener {
    LocationClient locationClient;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_my);
        locationClient = new LocationClient(this, this, this);
    }

    @Override
    public void onConnected(Bundle bundle) {
    Location location = locationClient.getLastLocation() ;
        Toast.makeText(this, "Connected to Google Play Services", Toast.LENGTH_SHORT).show();
    }

    @Override
    public void onDisconnected() {
    Toast.makeText(this, "Connected from Google Play Services.", Toast.LENGTH_SHORT).show();
    }

    @Override
    public void onConnectionFailed(ConnectionResult connectionResult) {
        // code to handle failed connection
        // this code can be found here — http://developer.android.com/training/location/retrieve-current.html 
    }
  • Почему locationClient.getLastLocation() null?

locationClient.getLastLocation() получает последнее известное местоположение от клиента. Однако провайдер Fused Location будет поддерживать фоновое местоположение только в том случае, если к нему подключен хотя бы один клиент. Как только первый клиент подключится, он сразу попытается определить местоположение. Если ваша деятельность является первым клиентом, подключившимся, и вы сразу же getLastLocation() в onConnected(), этого может не хватить времени для onConnected() первого местоположения. Это приведет к тому, что location будет null.

Чтобы решить эту проблему, нужно подождать (неопределенно), пока провайдер не получит местоположение, а затем вызвать getLastLocation(), что невозможно узнать. Другой (лучший) вариант - реализовать интерфейс com.google.android.gms.location.LocationListener для получения периодических обновлений местоположения (и отключать его после первого обновления).

    public class MyActivity extends Activity implements ConnectionCallbacks, OnConnectionFailedListener, LocationListener {
    // . . . . . . . . more stuff here 
    LocationRequest locationRequest;
    LocationClient locationClient;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        // . . . . other initialization code
        locationClient = new LocationClient(this, this, this);
    locationRequest = new LocationRequest();
    // Use high accuracy
    locationRequest.setPriority(LocationRequest.PRIORITY_HIGH_ACCURACY);
        // Set the update interval to 5 seconds
    locationRequest.setInterval(UPDATE_INTERVAL);
        // Set the fastest update interval to 1 second
    locationRequest.setFastestInterval(FASTEST_INTERVAL);
    }
    // . . . . . . . . other methods 
    @Override
    public void onConnected(Bundle bundle) {
        Location location = locationClient.getLastLocation();
        if (location == null)
            locationClient.requestLocationUpdates(locationRequest, this);
        else
            Toast.makeText(getActivity(), "Location: " + location.getLatitude() + ", " + location.getLongitude(), Toast.LENGTH_SHORT).show();
    }
    // . . . . . . . . other methods
    @Override
    public void onLocationChanged(Location location) {
        locationClient.removeLocationUpdates(this);
        // Use the location here!!!
    }

В этом коде вы проверяете, есть ли у клиента последнее местоположение (в onConnected). Если нет, вы запрашиваете обновления местоположения и отключаете запросы (в onLocationChanged()), как только вы получаете обновление.

Обратите внимание, что locationClient.requestLocationUpdates(locationRequest, this); должен быть внутри обратного вызова onConnected, иначе вы получите IllegalStateException поскольку вы будете пытаться запрашивать местоположения, не подключенные к клиенту Google Play Services.

  • Пользователь отключил Службы определения местоположения

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

Если ваше приложение требует, чтобы они включили службы определения местоположения, вы хотели бы показать сообщение или тост. К сожалению, нет способа проверить, отключил ли пользователь сервисы определения местоположения в Googles Location Services API. Для этого вам придется вернуться к Androids API.

В вашем методе onCreate:

    LocationManager manager = (LocationManager) getActivity().getSystemService(Context.LOCATION_SERVICE);
if (!manager.isProviderEnabled(LocationManager.GPS_PROVIDER) && !manager.isProviderEnabled(LocationManager.NETWORK_PROVIDER)) {
    locationEnabled = false;
    Toast.makeText(getActivity(), "Enable location services for accurate data", Toast.LENGTH_SHORT).show();
}
else locationEnabled = true;

И используйте флаг locationEnabled в вашем методе onConnected следующим образом:

    if (location != null) {
    Toast.makeText(getActivity(), "Location: " + location.getLatitude() + ", " + location.getLongitude(), Toast.LENGTH_SHORT).show();
}
else if (location == null && locationEnabled) {
    locationClient.requestLocationUpdates(locationRequest, this);
}

благодаря Рахулу Джиресалу

ОБНОВИТЬ

Документ обновлен, LocationClient удален и API поддерживает включение GPS одним щелчком мыши из диалогового окна:

task.addOnSuccessListener(this, new OnSuccessListener<LocationSettingsResponse>() {
@Override
public void onSuccess(LocationSettingsResponse locationSettingsResponse) {
    // All location settings are satisfied. The client can initialize
    // location requests here.
    // ...
}
});

task.addOnFailureListener(this, new OnFailureListener() {
    @Override
    public void onFailure(@NonNull Exception e) {
        if (e instanceof ResolvableApiException) {
            // Location settings are not satisfied, but this can be fixed
            // by showing the user a dialog.
            try {
                // Show the dialog by calling startResolutionForResult(),
                // and check the result in onActivityResult().
                ResolvableApiException resolvable = (ResolvableApiException) e;
                resolvable.startResolutionForResult(MainActivity.this,
                        REQUEST_CHECK_SETTINGS);
            } catch (IntentSender.SendIntentException sendEx) {
                // Ignore the error.
            }
        }
    }
});

Ссылка https://developer.android.com/training/location/change-location-settings#prompt

Новый клиент местоположения: FusedLocationProviderClient

  private FusedLocationProviderClient fusedLocationClient;

@Override
protected void onCreate(Bundle savedInstanceState) {
    fusedLocationClient = LocationServices.getFusedLocationProviderClient(this);
}

Рекомендуется пройти через https://developer.android.com/training/location перед выполнением каких-либо задач определения местоположения.

Ответ 2

По моему опыту, "более подходящая точность" вовсе не означает лучшего. Если я что-то не хватает, если вы хотите убедиться, что GPS используется, LocationManager - единственный способ пойти. Мы отслеживаем транспортные средства с нашим приложением, и, опять же, если я чего-то не хватает, службы Google Play предоставляют довольно неточные местоположения довольно часто.

Ответ 3

Вместо LocationManager вы должны использовать местоположение Google Play Services api. Согласно документам:

API местоположения сервисов Google Play предпочтительнее, чем Android API определения местоположения (android.location) как способ добавления местоположения осведомленность о вашем приложении. Если вы в настоящее время используете Android API определения местоположения, вам настоятельно рекомендуется переключиться на API Google Apps для сервисов Google как можно скорее.

Что касается того, зачем переключаться, Google говорит следующее:

API служб геолокации Google, входящий в состав Служб Google Play, обеспечивает более мощную, высокоуровневую структуру, которая автоматически обрабатывает поставщиков местоположения, перемещение пользователей и точность определения местоположения. Это также обрабатывает планирование обновления местоположения на основе энергопотребления параметры, которые вы предоставляете. В большинстве случаев вы получите лучшую батарею производительности, а также более подходящую точность, используя API служб местоположения.

Ответ 4

Я уже давно пользуюсь API Google Location Services. Он имеет свои преимущества, поскольку включает в себя сложность наличия нескольких источников для определения позиций. Однако он слишком сильно инкапсулируется, поэтому, когда вы получаете странную позицию, у вас нет возможности определить, откуда эта странная позиция появилась.

В реальной жизни у меня появилось несколько странных ценностей, находящихся в 10 километрах от реальной позиции. Единственное объяснение состоит в том, что эти сумасшедшие местоположения происходят из-за ошибок в базах данных Googles Wi-Fi или NWK - ошибок, которые будут всегда, поскольку топологии Wi-Fi и сети меняются каждый день. Но, к сожалению (и удивительно), API не дает вам никакой информации о том, как была получена отдельная позиция.

enter image description here

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

... или вернитесь к старому доброму API фреймворка и используйте только GPS, что я и решил делать, пока Google не улучшит слитый API.

Ответ 5

API Google Location Services API, входящий в состав Google Play Services, предоставляет более мощную инфраструктуру высокого уровня, которая автоматически обрабатывает поставщиков местоположения, пользовательское перемещение и точность определения местоположения. Он также обрабатывает планирование обновления местоположения на основе параметров энергопотребления, которые вы предоставляете. В большинстве случаев вы получите лучшую производительность батареи, а также более подходящую точность, используя API служб местоположения.

Более подробные различия между двумя apis API-интерфейсом Google Play Service API и Android Framework Location API можно найти здесь

Ответ 6

Да, API Служб определения местоположения Служб Google Play может вводить в заблуждение информацию о Местоположении. Модемы WiFi перемещаются, модемы WiFi обновляются с неверной информацией о местоположении (то есть, если местоположение подделывается устройством Android, которое обновляет местоположение модема WiFi), и существует множество других обстоятельств, которые могут привести к неправильным данным местоположения из триангуляции модема WiFi. Во всех наших приложениях, где точное местоположение является обязательным, мы используем только GPS.

Ответ 7

Различия между двумя API API определения местоположения службы Google Play и API определения местоположения Android Framework на основе службы GPS

FusedLocationProviderClient

  1. Для 1-го извлечения местоположение не должно быть нулевым (т.е. некоторые другие приложения должны обновить последнее известное местоположение в базе данных GoogleplayService. Если оно пустое, необходимо обойти это)
  2. Для следующей последовательной выборки используется метод requestLocationUpdates() для извлечения местоположения.
  3. Выборка местоположения основана только на locationRequest.setInterval(milliseconds) и setFastestInterval(milliseconds), а не на изменении местоположения пользователя
  4. Возвращенное значение LatLng содержит только 7 десятичных значений (например: 11.9557996, 79.8234599), не так точно
  5. Рекомендуется, когда требование вашего приложения принимает текущее местоположение на расстоянии, пренебрежимо малом (точность 50 - 100 метров)
  6. Эффективно при использовании аккумулятора.

LocationManager Api

  1. Выборка местоположения пользователя вызывается с помощью locationManager.requestLocationUpdates()
  2. Выбор местоположения на основе изменения местоположения пользователя и временных интервалов locationManager.requestLocationUpdates(LocationManager.GPS_PROVIDER, milliseconds, mindistance, Mylocationlistener)

  3. Возвращенное значение LatLng содержит 14 десятичных значений (например:11.94574594963342 79.81166719458997) точныезначения местоположения

  4. Рекомендуется для приложения на основе определения местоположения, когда требуется большая точность даже в метрах.
  5. Использование батареи зависит от интервала выборки и расстояния выборки.

Ответ 8

LocationManager

Как указано в официальной документации, этот класс позволяет вам использовать службы для местоположения, периодически обновлять географическое положение устройства или отправлять "намерения" приложениям, чтобы сказать, что устройство близко заранее определенное место. API требует ACCESS_COARSE_LOCATION или ACCESS_FINE_LOCATION

Службы API определения местоположения Google

Он полностью несовместим с LocationManager, но в отношении работы в реальном времени существуют некоторые принципиальные различия.

Преимущества и недостатки

Что касается Google Location API Services, то если мы сравним его с LocationManager, то заметим значительное повышение производительности и стабильности во время использования. Например, была общая проблема с LocationManager, получающим предыдущие местоположения или обновления карты, когда параметры были установлены для минимального периода времени и расстояния, на которое устройство должно быть смещено для последующих обновлений; один из параметров обычно игнорировался. В Google Location API Services эта проблема не встречалась. Кроме того, Службы определения местоположения Google потребляют меньше заряда аккумулятора.

В результате сервисы Google Location API работали лучше во всех случаях. Однако есть и некоторые недостатки. Чтобы использовать Службы определения местоположения, необходимо установить Службы Google Play.

Поэтому на устройствах с обычной прошивкой, которые не поддерживаются Google или в которых недоступны службы Google, приложение не будет работать. Это очень важный момент, который необходимо учитывать. Исследования в этой области выявили тот факт, что большинство пользователей не имеют Google Play Services. Например, они недоступны в Китае из-за национальной политики, и это значительная часть рынка, которую нельзя игнорировать. В этом случае необходимо обратиться к LocationManager.

Google Location API Services - лучшее решение для работы с картами. Этот API позволяет работать с самыми точными координатами и с минимальными затратами с точки зрения мобильных ресурсов, если пользователь установил Сервисы Google Play; в противном случае единственным решением является LocationManager.

Подробнее здесь