Android: LocationManager vs usługi Google Play

Chcę zbudować aplikację, która skupia się na uzyskaniu Aktualnej Lokalizacji użytkownika, a następnie znaleźć interesujące punkty (takie jak bary,restauracje itp.), które są blisko niego/jej za pośrednictwem Google Places API.

Szukając w sieci miejsca na start natknąłem się na kilka samouczków, które używają klasy LocationManager i kilka innych, które używają Usługi Google Play w celu znalezienia lokalizacji użytkowników.

Na pierwszy rzut oka obie robią to samo, ale ponieważ jestem w tym nowy, trochę się pogubiłem i nie wiem, Która metoda najbardziej odpowiada moim potrzebom. Więc chcę cię zapytać:

Jakie są różnice między tymi dwoma metodami znajdowania lokalizacji (jeśli istnieją) ?

Author: SoCo, 2015-10-08

7 answers

Lokalizacja użytkownika na Androidzie

[36]}uzyskanie lokalizacji użytkownika na Androidzie jest trochę mniej proste niż na iOS. Aby rozpocząć zamieszanie, istnieją dwa zupełnie różne sposoby, aby to zrobić. Pierwszy z nich to API Androida z android.location.LocationListener, a drugi to API usług Google Play com.google.android.gms.location.LocationListener. Przejrzyjmy je obie.
  1. Android ' s Location API

    [36]}lokalizacyjne interfejsy API Androida używają trzech różnych dostawców, aby uzyskać lokalizacja -
    • LocationManager.GPS_PROVIDER - Ten dostawca określa lokalizację za pomocą satelitów. W zależności od warunków, ten dostawca może trochę potrwać, aby zwrócić poprawkę lokalizacji.
    • LocationManager.NETWORK_PROVIDER - Ten dostawca określa lokalizację na podstawie dostępności wieży komórkowej i punktów dostępowych WiFi. Wyniki są pobierane za pomocą wyszukiwania sieciowego.
    • LocationManager.PASSIVE_PROVIDER - ten dostawca zwróci lokalizacje wygenerowane przez innych dostawców. Pasywnie otrzymujesz aktualizacje lokalizacji, gdy inne aplikacje lub usługi żądają ich, nie żądając samych lokalizacji.

Istotą tego jest to, że otrzymujesz obiekt {[12] } z systemu, zaimplementujesz {[13] } i wywołasz requestLocationUpdates na LocationManager.

Oto fragment kodu:

    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);

Google ' s API Guide on Location Strategies ładnie wyjaśnia kod. Ale wspominają również, że w większości przypadków uzyskasz lepszą wydajność baterii, a także bardziej odpowiednie dokładność, używając zamiast tego Google Location Services API . Teraz zaczyna się zamieszanie!

  1. Google usługi lokalizacyjne API
API usług lokalizacji Google jest częścią APK usług Google Play ( oto jak go skonfigurować ). Są zbudowane na bazie API Androida. Te interfejsy API zapewniają "dostawcę łączonej lokalizacji" zamiast dostawców wymienionych powyżej. Ten dostawca automatycznie wybiera, z którego dostawcy bazowego korzystać, na podstawie na dokładność, zużycie baterii itp. Jest szybki, ponieważ uzyskujesz lokalizację z usługi systemowej, która stale ją aktualizuje. Możesz też korzystać z bardziej zaawansowanych funkcji, takich jak geofencing.

Aby korzystać z usług lokalizacji Google, Twoja aplikacja musi połączyć się z GooglePlayServicesClient. Aby połączyć się z klientem, Twoja aktywność (lub fragment) musi zaimplementować interfejsy GooglePlayServicesClient.ConnectionCallbacks i GooglePlayServicesClient.OnConnectionFailedListener. Oto przykładowy kod:

    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 
    }
  • dlaczego locationClient.getLastLocation() jest null?

The locationClient.getLastLocation() gets the last znana lokalizacja od klienta. Jednak dostawca lokalizacji zespolonej zachowa lokalizację w tle tylko wtedy, gdy przynajmniej jeden klient jest z nią połączony. Gdy pierwszy klient połączy się, natychmiast spróbuje uzyskać lokalizację. Jeśli Twoja aktywność jest pierwszym klientem, który się połączy i zadzwonisz getLastLocation() od razu w onConnected(), może to nie wystarczyć, aby pierwsza lokalizacja przyszła. Spowoduje to, że location będzie null.

Aby rozwiązać ten problem, musisz poczekać (nieokreślony) do dostawca dostaje lokalizację, a następnie zadzwonić getLastLocation(), co jest niemożliwe do poznania. Inną (lepszą) opcją jest zaimplementowanie interfejsu com.google.android.gms.location.LocationListener do otrzymywania okresowych aktualizacji lokalizacji (i wyłączenie go po otrzymaniu pierwszej aktualizacji).

    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!!!
    }

W tym kodzie sprawdzasz, czy klient ma już ostatnią lokalizację(w onConnected). Jeśli nie, żądasz aktualizacji lokalizacji i wyłączasz żądania (w wywołaniu zwrotnym onLocationChanged()), gdy tylko otrzymasz aktualizację.

Zauważ, że locationClient.requestLocationUpdates(locationRequest, this); musi być wewnątrz onConnected callback, albo otrzymasz IllegalStateException, ponieważ będziesz próbował poprosić o lokalizacje bez połączenia z klientem usług Google Play.

  • użytkownik wyłączył Usługi lokalizacji

Wiele razy użytkownik miał wyłączone usługi lokalizacji (w celu oszczędzania baterii lub ze względów prywatności). W takim przypadku powyższy kod nadal będzie wymagał aktualizacji lokalizacji, ale onLocationChanged nigdy nie zostanie wywołany. Możesz zatrzymać żądania poprzez sprawdzenie, czy użytkownik wyłączył usługi lokalizacyjne.

Jeśli Twoja aplikacja wymaga, aby włączyć usługi lokalizacyjne, chcesz pokazać wiadomość lub Toast. Niestety, nie ma możliwości sprawdzenia, czy użytkownik wyłączył usługi lokalizacyjne w interfejsie API usług lokalizacyjnych Google. W tym celu będziesz musiał wrócić do API Androida.

W metodzie 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;

I użyj znacznika locationEnabled w metodzie onConnected Jak to:

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

UPDATE

[[36]}dokument jest aktualizowany, LocationClient jest usuwany, a api obsługuje włączanie GPS za pomocą jednego kliknięcia w oknie dialogowym: [39]}
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.
            }
        }
    }
});

Link https://developer.android.com/training/location/change-location-settings#prompt

Nowy klient lokalizacji: FusedLocationProviderClient

  private FusedLocationProviderClient fusedLocationClient;

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

Zaleca się, aby przejść przez https://developer.android.com/training/location przed wykonaniem jakichkolwiek zadań lokalizacyjnych.

 328
Author: pRaNaY,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2020-05-05 03:03:32

Z mojego doświadczenia wynika, że" bardziej odpowiednia dokładność " wcale nie oznacza lepszej. O ile czegoś mi nie brakuje, Jeśli chcesz się upewnić, że GPS jest używany, LocationManager jest jedynym sposobem, aby przejść. Śledzimy Pojazdy za pomocą naszej aplikacji i znowu, o ile czegoś nie przeoczyłem, usługi Google Play dość często zapewniają bardzo niedokładne lokalizacje.

 34
Author: Kit,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2015-11-30 17:14:32

Powinieneś używać API lokalizacji usług Google Play zamiast LocationManager. Według docs:

[[0]} API lokalizacyjne usług Google Play są preferowane w stosunku do Androida Framework location API (android.lokalizacja) jako sposób dodawania lokalizacji świadomość Twojej aplikacji. Jeśli obecnie używasz systemu Android framework location API, gorąco zachęcamy do przełączenia się na API lokalizacyjne usług Google Play tak szybko, jak to możliwe.

Dlaczego do switch, Google mówi tak:

Google Location Services API, część usług Google Play, zapewnia potężniejsze ramy wysokiego poziomu, które automatycznie obsługuje dostawców lokalizacji, ruch użytkowników i dokładność lokalizacji. Informatyka obsługuje również harmonogramowanie aktualizacji lokalizacji w oparciu o zużycie energii parametry, które podajesz. W większości przypadków dostaniesz lepszą baterię wydajności, a także bardziej odpowiedniej dokładności, dzięki zastosowaniu API usług lokalizacji.

 27
Author: NoChinDeluxe,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2015-10-08 17:58:25

Używam Google Location Services API od dłuższego czasu. Ma to swoje zalety, ponieważ ujmuje złożoność posiadania kilku źródeł do określania pozycji. Jednak jest zbyt mocno osadzony , tak że kiedy masz dziwną pozycję, nie masz sposobu, aby określić, skąd ta dziwna pozycja pochodzi.

W prawdziwym życiu miałem kilka dziwacznych wartości wyskakujących, będąc 10 kilometrów od rzeczywistej pozycji. Jedyne wytłumaczenie jest takie, że te szalone lokalizacje wynikają z błędów w Googles Wi-Fi lub bazach danych NWK-błędy, które zawsze tam będą, ponieważ Wi-Fi i topologie sieci zmieniają się każdego dnia. Ale niestety (i zaskakująco) API nie daje żadnych informacji o tym, w jaki sposób dana pozycja została uzyskana.

Tutaj wpisz opis obrazka

To pozostawia Ci problemy z koniecznością odfiltrowania wartości freak na podstawie sprawdzania wiarygodności prędkości, przyspieszenia, łożyska itp.

... albo wrócić do starego, dobrego framework API i używaj tylko GPS, co postanowiłem zrobić, dopóki Google nie ulepszy fused API.

 27
Author: j3App,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2020-07-07 11:06:08

interfejs API usług lokalizacji Google, część usług Google Play, zapewnia potężniejsze ramy wysokiego poziomu, które automatycznie obsługują dostawców lokalizacji , ruch użytkownika i dokładność lokalizacji . Obsługuje również harmonogramowanie aktualizacji lokalizacji w oparciu o podane parametry zużycia energii. W większości przypadków otrzymasz lepsza wydajność baterii, jak również bardziej odpowiednią dokładność, korzystając z usług lokalizacji API.

Bardziej szczegółowe różnice między dwoma API Google Play Service Location API i Android Framework Location API można znaleźć tutaj

 8
Author: Dhruvam Gupta,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2016-10-05 09:49:11

[[4]} różnice pomiędzy dwoma API lokalizacji usługi Google Play API i Android Framework lokalizacji API na podstawie usługi GPS

FusedLocationProviderClient

  1. dla pierwszego pobierania lokalizacja nie może być null (tzn.: inna aplikacja musi zaktualizować ostatnią lokalizację w bazie danych GoogleplayService. jeśli jest null, trzeba obejść)
  2. do następnego sekwencyjnego pobierania używa metody requestLocationUpdates() do pobierania lokalizacji.
  3. Lokalizacja fetch jest oparty tylko na locationRequest.setInterval(milliseconds)i setFastestInterval(milliseconds), a nie na zmianie lokalizacji użytkownika
  4. zwrócona wartość LatLng zawiera tylko 7 wartości dziesiętnych (np.: 11.9557996, 79.8234599), nie tak dokładne
  5. zalecane, gdy aplikacja wymaga Aktualnej Lokalizacji Odległość pomijalna (Dokładność 50-100 metrów)
  6. [[13]}skuteczne w zużyciu baterii.

LocationManager Api

  1. pobranie lokalizacji użytkownika jest wywołane przy użyciu menedżera lokalizacji.requestLocationUpdates ()
  2. Pobieranie lokalizacji na podstawie przedziałów czasowych użytkownika zmiana lokalizacjii locationManager.requestLocationUpdates(LocationManager.GPS_PROVIDER, milliseconds, mindistance, Mylocationlistener)

  3. Zwracana wartość LatLng zawiera 14 wartości dziesiętnych (np.: 11.94574594963342 79.81166719458997) dokładne wartości lokalizacji

  4. zalecane dla aplikacji opartych na lokalizacji, gdy wymaga większej dokładności nawet w metrach.
  5. zużycie baterii opiera się na Przedział pobierania i odległość pobierania.
 7
Author: Sackurise,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2019-08-09 04:58:56

Tak, API usług lokalizacyjnych usług Google Play może podawać bardzo mylące informacje o lokalizacji. Modemy WiFi zostać przeniesiony, modemy WiFi uzyskać aktualizowane z błędnych informacji o lokalizacji (tj. jeśli lokalizacja jest fałszowane przez urządzenie z Androidem, który aktualizuje lokalizację modemu WiFi) i istnieje wiele innych okoliczności, które mogą spowodować nieprawidłowe dane lokalizacji z modemu WiFi triangulacji. We wszystkich naszych aplikacjach, w których dokładna lokalizacja jest obowiązkowa, używamy tylko GPS.

 5
Author: user1608385,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2019-07-20 23:20:44