Chcę zbudować aplikację, która koncentruje się na uzyskiwaniu aktualnej lokalizacji użytkownika, a następnie znajdowaniu interesujących miejsc (takich jak bary, restauracje itp.), Które są blisko niego za pośrednictwem interfejsu API Miejsc Google .
Po przeszukaniu sieci w poszukiwaniu miejsca, w którym można by zacząć, natknąłem się na kilka samouczków wykorzystujących tę LocationManager
klasę i kilka innych, które używają usług Google Play w celu znalezienia lokalizacji użytkownika.
Na pierwszy rzut oka obaj robią to samo, ale ponieważ jestem nowy w tej dziedzinie, trochę się pogubiłem i nie wiem, która metoda najlepiej odpowiada moim potrzebom. Więc chcę cię zapytać:
Jakie są różnice między tymi dwoma metodami znajdowania lokalizacji (jeśli takie istnieją)?
źródło
Odpowiedzi:
Lokalizacja użytkownika na Androidzie
Pobieranie lokalizacji użytkownika w systemie Android jest nieco mniej proste niż w systemie iOS. Aby rozpocząć zamieszanie, możesz to zrobić na dwa zupełnie różne sposoby. Pierwsza korzysta z interfejsów API systemu Android od
android.location.LocationListener
, a druga korzysta z interfejsów API usług Google Playcom.google.android.gms.location.LocationListener
. Przejdźmy przez oba z nich.Interfejs API lokalizacji systemu Android
Interfejsy API lokalizacji systemu Android używają trzech różnych dostawców do pobierania lokalizacji -
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ępu Wi-Fi. Wyniki są pobierane za pomocą wyszukiwania sieciowego.LocationManager.PASSIVE_PROVIDER
- Ten dostawca zwróci lokalizacje wygenerowane przez innych dostawców. Biernie otrzymujesz aktualizacje lokalizacji, gdy inne aplikacje lub usługi o nie żądają, bez konieczności samodzielnego żądania lokalizacji.Istotą jest to, że pojawi się przedmiot
LocationManager
z systemu, wdrożeniaLocationListener
i nazwaćrequestLocationUpdates
naLocationManager
.Oto fragment kodu:
Przewodnik API Google dotyczący strategii lokalizacjiładnie wyjaśnia kod. Ale wspominają również, że w większości przypadków uzyskasz lepszą wydajność baterii, a także bardziej odpowiednią dokładność, używając zamiast tego interfejsu API usług lokalizacyjnych Google . Teraz zaczyna się zamieszanie!Interfejs API usług lokalizacyjnych Google jest częścią pakietu APK usług Google Play ( tutaj opisano , jak go skonfigurować ). Są zbudowane w oparciu o API Androida. Te interfejsy API zapewniają „dostawcę lokalizacji połączonej” zamiast dostawców wymienionych powyżej. Ten dostawca automatycznie wybiera bazowego dostawcę na podstawie dokładności, zużycia baterii itp. Jest szybki, ponieważ uzyskujesz lokalizację z usługi ogólnosystemowej, która stale ją aktualizuje. Możesz też korzystać z bardziej zaawansowanych funkcji, takich jak geofencing.
Aby korzystać z usług lokalizacyjnych Google, Twoja aplikacja musi łączyć się z
GooglePlayServicesClient
. Aby połączyć się z klientem, Twoja aktywność (lub fragment, lub coś takiego) musi zostać zaimplementowanaGooglePlayServicesClient.ConnectionCallbacks
iGooglePlayServicesClient.OnConnectionFailedListener
interfejsy. Oto przykładowy kod:locationClient.getLastLocation()
null?locationClient.getLastLocation()
Dostaje ostatnią znaną lokalizację z klientem. Jednak dostawca lokalizacji połączonej będzie utrzymywał lokalizację w tle tylko wtedy, gdy jest z nią połączony co najmniej jeden klient. Gdy pierwszy klient połączy się, natychmiast spróbuje uzyskać lokalizację. Jeśli Twoja aktywność jest pierwszym klientem, który się połączy i dzwoniszgetLastLocation()
od razuonConnected()
, to może nie wystarczyć czasu na pojawienie się pierwszej lokalizacji. To spowoduje,location
że będziesznull
.Aby rozwiązać ten problem, musisz poczekać (nieokreślony), aż dostawca otrzyma lokalizację, a następnie zadzwonić
getLastLocation()
, co jest niemożliwe do ustalenia . Inną (lepszą) opcją jest zaimplementowaniecom.google.android.gms.location.LocationListener
interfejsu do otrzymywania okresowych aktualizacji lokalizacji (i wyłączanie go po otrzymaniu pierwszej aktualizacji).W tym kodzie sprawdzasz, czy klient ma już ostatnią lokalizację (w
onConnected
). Jeśli nie, prosisz o aktualizacje lokalizacji i wyłączasz żądania (wonLocationChanged()
oddzwonieniu), gdy tylko otrzymasz aktualizację.Pamiętaj, że
locationClient.requestLocationUpdates(locationRequest, this);
musi znajdować się wonConnected
wywołaniu zwrotnym, w przeciwnym razie otrzymasz wiadomość,IllegalStateException
ponieważ będziesz próbować zażądać lokalizacji bez połączenia z klientem usług Google Play.Często użytkownik miałby wyłączone usługi lokalizacyjne (aby oszczędzać baterię lub ze względów prywatności). W takim przypadku powyższy kod nadal będzie żądał aktualizacji lokalizacji, ale
onLocationChanged
nigdy nie zostanie wywołany. Możesz zatrzymać żądania, sprawdzając, czy użytkownik wyłączył usługi lokalizacyjne.Jeśli Twoja aplikacja wymaga od nich włączenia usług lokalizacyjnych, zechcesz wyświetlić 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 interfejsu API Androida.
W Twojej
onCreate
metodzie:I użyj
locationEnabled
flagi w swojejonConnected
metodzie w następujący sposób:AKTUALIZACJA
Dokument jest aktualizowany, LocationClient jest usuwany, a interfejs API umożliwia włączenie GPS jednym kliknięciem w oknie dialogowym:
Połącz https://developer.android.com/training/location/change-location-settings#prompt
Nowy klient lokalizacji: FusedLocationProviderClient
Zaleca się, aby przed wykonaniem jakichkolwiek zadań lokalizacyjnych przejść przez stronę https://developer.android.com/training/location .
źródło
SettingsApi.checkLocationSettings()
aby sprawdzić, czy użytkownik włączył usługi lokalizacji (patrz tutaj: developers.google.com/android/reference/com/google/android/gms/… ).LocationManager
! Czy interfejs API połączonej lokalizacji działa na urządzeniach, które nie mają usług Google Play?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 }
Z mojego doświadczenia wynika, że „bardziej odpowiednia dokładność” nie oznacza w żaden sposób lepszej. O ile czegoś nie brakuje, jeśli chcesz mieć pewność, że używany jest GPS, LocationManager jest jedynym sposobem. Śledzimy pojazdy za pomocą naszej aplikacji i znowu, jeśli czegoś nie brakuje, Usługi Google Play dość często udostępniają bardzo niedokładne lokalizacje.
źródło
Należy użyć interfejsu API lokalizacji usług Google Play zamiast LocationManager. Według dokumentów:
O tym, dlaczego się przełączyć, Google mówi tak:
źródło
Korzystam z interfejsu API usług lokalizacyjnych Google od dłuższego czasu. Ma zalety, ponieważ obejmuje złożoność posiadania kilku źródeł do określania pozycji. Jednak hermetyzuje zbyt mocno , więc gdy otrzymasz dziwną pozycję, nie masz możliwości określenia, skąd pochodzi ta dziwna pozycja.
W prawdziwym życiu pojawiło się kilka dziwacznych wartości, znajdujących się 10 kilometrów od rzeczywistej pozycji. Jedynym wyjaśnieniem jest to, że te szalone lokalizacje wynikają z błędów w bazach danych Google Wi-Fi lub NWK - błędów, które zawsze będą tam, ponieważ topologie Wi-Fi i sieci zmieniają się każdego dnia. Ale niestety (i zaskakująco) API nie daje żadnych informacji o tym, w jaki sposób została wyprowadzona indywidualna pozycja.
Pozostawia to problemy związane z koniecznością odfiltrowania dziwnych wartości w oparciu o sprawdzenie wiarygodności prędkości, przyspieszenia, łożyska itp.
... albo wróć do starego, dobrego interfejsu API i używaj tylko GPS, co postanowiłem zrobić, dopóki Google nie ulepszy połączonego API.
źródło
Interfejs API usług lokalizacyjnych Google , część usług Google Play, zapewnia bardziej wydajną strukturę wysokiego poziomu, która automatycznie obsługuje dostawców lokalizacji , ruch użytkowników i dokładność lokalizacji . Obsługuje również planowanie aktualizacji lokalizacji na podstawie podanych parametrów zużycia energii. W większości przypadków uzyskasz lepszą wydajność baterii , a także bardziej odpowiednią dokładność, korzystając z interfejsu API usług lokalizacyjnych.
Bardziej szczegółowe różnice między dwoma interfejsami API lokalizacji usług Google Play i API lokalizacji Android Framework można znaleźć tutaj
źródło
Tak, interfejs API usług lokalizacyjnych Google Play może podawać bardzo mylące informacje o lokalizacji. Modemy Wi-Fi są przenoszone, modemy Wi-Fi są aktualizowane za pomocą nieprawidłowych informacji o lokalizacji (tj. Jeśli lokalizacja jest sfałszowana przez urządzenie z Androidem, które aktualizuje lokalizację modemu Wi-Fi) i istnieje szereg innych okoliczności, które mogą powodować nieprawidłowe dane lokalizacji z triangulacji modemu Wi-Fi. We wszystkich naszych aplikacjach, w których dokładna lokalizacja jest obowiązkowa, używamy tylko GPS.
źródło
Różnice między dwoma interfejsami API lokalizacji usługi Google Play i API platformy Android Framework opartymi na usłudze GPS
FusedLocationProviderClient
requestLocationUpdates()
metody do pobrania lokalizacji.locationRequest.setInterval(milliseconds)
asetFastestInterval(milliseconds)
nie na niejLocationManager Api
Pobieranie lokalizacji na podstawie zmiany lokalizacji użytkownika i odstępów czasu
locationManager.requestLocationUpdates(LocationManager.GPS_PROVIDER, milliseconds, mindistance, Mylocationlistener)
Zwrócona wartość LatLng zawiera 14 wartości dziesiętnych (np .: 11,94574594963342 79,81166719458997) dokładne wartości lokalizacji
źródło