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.
Jakie są różnice między tymi dwoma metodami znajdowania lokalizacji (jeśli istnieją) ?
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 zandroid.location.LocationListener
, a drugi to API usług Google Play com.google.android.gms.location.LocationListener
. Przejrzyjmy je obie.
-
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!
- Google usługi lokalizacyjne API
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.
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.
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.
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.
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.
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
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
- 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ść)
- do następnego sekwencyjnego pobierania używa metody
requestLocationUpdates()
do pobierania lokalizacji. - Lokalizacja fetch jest oparty tylko na
locationRequest.setInterval(milliseconds)
isetFastestInterval(milliseconds)
, a nie na zmianie lokalizacji użytkownika - zwrócona wartość LatLng zawiera tylko 7 wartości dziesiętnych (np.: 11.9557996, 79.8234599), nie tak dokładne
- zalecane, gdy aplikacja wymaga Aktualnej Lokalizacji Odległość pomijalna (Dokładność 50-100 metrów) [[13]}skuteczne w zużyciu baterii.
LocationManager Api
- pobranie lokalizacji użytkownika jest wywołane przy użyciu menedżera lokalizacji.requestLocationUpdates ()
Pobieranie lokalizacji na podstawie przedziałów czasowych użytkownika zmiana lokalizacjii
locationManager.requestLocationUpdates(LocationManager.GPS_PROVIDER, milliseconds, mindistance, Mylocationlistener)
Zwracana wartość LatLng zawiera 14 wartości dziesiętnych (np.: 11.94574594963342 79.81166719458997) dokładne wartości lokalizacji
- zalecane dla aplikacji opartych na lokalizacji, gdy wymaga większej dokładności nawet w metrach.
- zużycie baterii opiera się na Przedział pobierania i odległość pobierania.
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.
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