Android: LocationManager vs Google Play Services


151

Я хочу створити додаток, який зосереджується на тому, щоб знайти поточне місцезнаходження користувача, а потім знайти API, який знаходиться поруч із ним / її через API Google Місця на карті .

Шукаючи в Інтернеті місце для початку, я натрапив на кілька навчальних посібників, які використовують LocationManagerклас та деякі інші, які використовують Сервіси Google Play , щоб знайти місцезнаходження користувачів.

З першого погляду вони обидва роблять те саме, але, оскільки я новачок у цьому, я трохи розгубився, і не знаю, який метод найкращим чином відповідає моїм потребам. Отже, я хочу вас запитати:

Які відмінності між цими двома методами пошуку місць (якщо такі є)?


Відповіді:


320

Місцезнаходження користувача на Android

Отримати місцезнаходження користувача на Android трохи простіше, ніж на iOS. Щоб почати плутанину, є два абсолютно різні способи зробити це. Перший - це використання API Android від android.location.LocationListener, а другий - API API Google Play Services com.google.android.gms.location.LocationListener. Переглянемо їх обох.

  1. API розташування Android

    API розташування Android використовують три різних постачальника, щоб отримати місцезнаходження -

    • LocationManager.GPS_PROVIDER- Цей провайдер визначає місцезнаходження за допомогою супутників. Залежно від умов, цей постачальник може зайняти деякий час, щоб повернути виправлення місцеположення.
    • LocationManager.NETWORK_PROVIDER- Цей провайдер визначає місцеположення залежно від наявності стільникових башт та точок доступу Wi-Fi. Результати отримують за допомогою мережевого пошуку.
    • 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);

Посібник з API Google щодо стратегій розташуванняпояснює код досить добре. Але вони також зазначають, що в більшості випадків ви отримаєте кращі показники роботи акумулятора, а також більш відповідну точність, використовуючи натомість API локальних служб Google . Тепер плутанина починається!

  1. API служби локації Google

API локальних служб Google є частиною APK служб Google Play ( ось як його налаштувати ). Вони побудовані на основі API Android. Ці API надають "Постачальника плавного розташування" замість згаданих вище постачальників. Цей постачальник автоматично вибирає, який саме постачальник використовуватиметься, виходячи з точності, використання акумулятора тощо. Це швидко, оскільки ви отримуєте місцезнаходження від загальносистемної служби, яка постійно його оновлює. І ви можете використовувати більш вдосконалені функції, такі як географічне огородження.

Щоб використовувати служби локації Google, ваш додаток повинен підключитися до 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()нулю?

locationClient.getLastLocation()Отримує останнє відоме місце розташування від клієнта. Однак Провайдер злитого розташування підтримуватиме фонове розташування лише в тому випадку, якщо до нього підключений хоча б один клієнт. Після підключення першого клієнта він негайно спробує отримати місцезнаходження. Якщо ваша діяльність є першим клієнтом для підключення і ви дзвоните getLastLocation()відразу в 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.

  • Користувач відключив Служби локації

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

Якщо ваш додаток вимагає, щоб вони ввімкнули послуги локації, ви хочете показати повідомлення чи тост. На жаль, немає можливості перевірити, чи користувач вимкнув служби локації в API локальних служб Google. Для цього вам доведеться вдатися до API Android.

У вашому 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, перш ніж виконувати будь-які завдання щодо локації.


9
Ви можете SettingsApi.checkLocationSettings()перевірити, чи ввімкнув користувач Служби локації (див. Тут: developers.google.com/android/reference/com/google/android/gms/… ).
kaolick

3
LocationClient більше не існує. Щоб отримати оновлене та зрозуміле керівництво про місцезнаходження, перегляньте цю статтю: blog.teamtreehouse.com/beginners-guide-location-android
lm2a

1
І тренувальна сторінка із прикладом SettingsApi: developer.android.com/training/location/…
androidguy

2
Ви також можете створити гео-паркан за допомогою LocationManager! Чи працює злита api-адреса на пристроях, на яких немає служб Google Play?
Мухаммед Бабар

Це може бути ще одним кращим способом перевірити стан включення / відключення GPS fun isLocationEnabled(context: Context): Boolean { val locationMode: Int try { locationMode = Settings.Secure.getInt( context.contentResolver, Settings.Secure.LOCATION_MODE ) } catch (e: SettingNotFoundException) { e.printStackTrace() return false } return locationMode != Settings.Secure.LOCATION_MODE_OFF }
Вахіх Уль Хак

32

На мій досвід, "більш відповідна точність" жодним чином не означає кращого. Якщо я щось не пропускаю, якщо ви хочете переконатися, що GPS використовується, то LocationManager - єдиний шлях. Ми відстежуємо транспортні засоби за допомогою нашої програми, і знову, якщо я щось не пропускаю, Служби Google Play доволі часто надають деякі дуже неточні місця.


2
Так, із мого досвіду Служби Google Play кілька разів надають неточне місцеположення.
VY

2
Так, API служб локації служб Google Play може дати дуже оманливу інформацію про місцезнаходження. Моделі WiFi пересуваються, WiFi модеми оновлюються неправильною інформацією про місцеположення (тобто, якщо розташування підробляється пристроєм Android, який оновлює місцезнаходження Wi-Fi модему), і існує безліч інших обставин, які можуть призвести до неправильних даних про місцезнаходження від триангуляції WiFi модему. У всіх наших додатках, де точне розташування є обов'язковим, ми використовуємо лише GPS.
user1608385

27

Ви повинні використовувати api розташування служб Google Play замість LocationManager. Згідно з документами:

API API розташування служб Google Play віддають перевагу більше, ніж API рамкового розташування Android (android.location) як спосіб додати інформацію про місцездатність до вашої програми. Якщо ви зараз використовуєте API-системи API розташування Android, вам настійно рекомендується якнайшвидше перейти на API розташування служб Google Play.

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

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


2
Чи є у вас посилання на цю документацію, з якої ці цитати? Було б цікаво подивитися, чи Google зараз говорить щось інше.
Едвард Брей

3
Звичайно, вони говорять про це, тому що хочуть ваших даних про місцезнаходження!
Flyview

Коли ви додасте служби Google Play у свій додаток, якщо користувач встановить ваш додаток, йому буде запропоновано "оновити" служби Google Play для використання вашого додатка. Якщо його / її телефон майже заповнений (із пам’ятками WhatsApp та іншим) або користувач не має даних, вибачте, мій друг
Д-р Део

2
@Flyview Yep! Лол, те, як вони говорять, звучить так, що це магічне рішення! Найбільший недолік - те, що вам потрібні сервіси Google Play на пристрої !!!
varun

25

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

У реальному житті у мене з’явилося декілька дивакових значень, знаходячись за 10 кілометрів від фактичного положення. Єдине пояснення полягає в тому, що ці божевільні місця виникають з помилок у базах даних Google-Wi-Fi або NWK - помилок, які завжди будуть, оскільки топології Wi-Fi та мережі змінюються щодня. Але, на жаль (і на диво) API не дає ніякої інформації щодо того, як була виведена окрема позиція.

введіть тут опис зображення

Це залишає перед вами проблеми з необхідністю відфільтрувати значення виродків на основі перевірки правдоподібності швидкості, прискорення, підшипника тощо.

... або повернутися до старого хорошого API-рамки та використовувати лише GPS, що я вирішив зробити, поки Google не покращить плавлений API.


7

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

Більш докладні відмінності між двома apis API Google Play Location Location та API API Framework Android можна знайти тут


Я використав вашу відповідь, щоб відповісти на моє власне питання, якщо це нормально. Дуже дякую! stackoverflow.com/questions/39852955 / ...
Leniaal

@Leniaal, тож ти не вважаєш, що моя відповідь заслуговує на підвищення?
Друвам Гупта

Це трирічний документ. Але ось плюс 1
Дрю

5

Так, API служб локації служб Google Play може дати дуже оманливу інформацію про місцезнаходження. Моделі WiFi пересуваються, WiFi модеми оновлюються неправильною інформацією про місцеположення (тобто, якщо розташування підробляється пристроєм Android, який оновлює місцезнаходження Wi-Fi модему), і існує безліч інших обставин, які можуть призвести до неправильних даних про місцезнаходження від триангуляції WiFi модему. У всіх наших додатках, де точне розташування є обов'язковим, ми використовуємо лише GPS.


3

Відмінність між двома apis API розташування служби Google Play та API API Framework Android на основі послуги GPS

FusedLocationProviderClient

  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. Використання акумулятора базується на інтервалі вибору та відстані добування.

ей! 1 ° - максимум 111_111 метр (20_000_000 / 180). Отже, 0,0000001 ° - 0,011м = 1 див. Я не знаю, де вам потрібна краща роздільна здатність GPS. І я навіть не знаю, як можна досягти кращого дозволу GPS.
Бабай
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.