LocationManager
API na Androida wydaje się, że jest to trochę uciążliwe, aby wykorzystać do wniosku, że potrzebuje tylko od czasu do czasu i szorstkie przybliżenie lokalizacji użytkownika.
Aplikacja, nad którą pracuję, nie jest sama w sobie aplikacją lokalizacyjną, ale musi uzyskać lokalizację użytkownika, aby wyświetlić listę pobliskich firm. Nie trzeba się martwić, czy użytkownik się porusza, czy coś w tym rodzaju.
Oto, co chciałbym zrobić:
- Pokaż użytkownikowi listę pobliskich lokalizacji.
- Załaduj wstępnie lokalizację użytkownika, aby do czasu, gdy będę go potrzebować w
Activity
X, będzie ona dostępna. - Nie dbam szczególnie o dokładność lub częstotliwość aktualizacji. Wystarczy chwycić jedną lokalizację, o ile nie jest daleko. Może jeśli chcę być fantazyjny, będę aktualizować lokalizację co kilka minut, ale to nie jest duży priorytet.
- Pracuj na dowolnym urządzeniu, o ile ma ono GPS lub dostawcę lokalizacji sieciowej.
Wydaje się, że nie powinno to być takie trudne, ale wydaje mi się, że muszę rozdzielić dwóch różnych dostawców lokalizacji (GPS i SIEĆ) i zarządzać cyklem życia każdego z nich. Nie tylko to, ale muszę zduplikować ten sam kod w wielu działaniach, aby spełnić # 2. W getBestProvider()
przeszłości próbowałem ograniczyć to rozwiązanie do korzystania tylko z jednego dostawcy lokalizacji, ale wydaje się, że daje to tylko najlepszego dostawcę „teoretycznego”, a nie dostawcę, który faktycznie da najlepsze wyniki.
Czy istnieje prostszy sposób na osiągnięcie tego?
Odpowiedzi:
Oto co robię:
Oto jak korzystam z mojej klasy:
A oto klasa MyLocation:
Ktoś może również chcieć zmodyfikować moją logikę. Na przykład, jeśli dostaniesz aktualizację od operatora sieci, nie zatrzymuj nasłuchiwania, ale nadal czekaj. GPS podaje dokładniejsze dane, dlatego warto na nie poczekać. Jeśli licznik czasu upłynie, a otrzymasz aktualizację z sieci, ale nie z GPS, możesz użyć wartości dostarczonej z sieci.
Jeszcze jednym podejściem jest użycie LocationClient http://developer.android.com/training/location/retrieve-current.html . Ale wymaga aplikacji Google Play Services do zainstalowania na urządzeniu użytkownika.
źródło
Po poszukiwaniu najlepszej implementacji, w jaki sposób uzyskać najlepszą dokładną lokalizację użytkownika, udało mi się połączyć wszystkie najlepsze metody i wymyślić następującą klasę:
Ta klasa próbuje połączyć się z
min_gps_sat_count
satelitami, jeśli GPS jest włączony. W przeciwnym razie zwracaLocationManager.getBestProvider()
lokalizację. Sprawdź kod!źródło
import java.util.Iterator; import android.content.Context; import android.location.Criteria; import android.location.GpsSatellite; import android.location.GpsStatus; import android.location.Location; import android.location.LocationListener; import android.location.LocationManager; import android.os.Bundle; import android.os.Handler;
Dzięki rozwiązaniu Fedora wielokrotnie występowało oddzwanianie
gotLocation
. Wydaje się, że jest to spowodowane warunkami wyścigu w przesłoniętejLocationListener.onLocationChanged
metodzie, gdy metoda gotLocation jest „wystarczająco długa” . Nie jestem pewien, ale myślę, żeremoveUpdates
zapobiega kolejkowaniu nowych wiadomości w kolejce Looper, ale nie usuwa tych, które zostały już w kolejce, ale jeszcze nie zostały zużyte. Stąd stan wyścigu.Aby zmniejszyć prawdopodobieństwo tego niewłaściwego zachowania, można wywołać removeUpdates przed odpaleniem zdarzenia onLocationChanged, ale nadal mamy warunki wyścigu.
Najlepszym rozwiązaniem, jakie znalazłem, jest zastąpienie
requestLocationUpdates
gorequestSingleUpdate
.To jest moja wersja, oparta na rozwiązaniu Fedora, wykorzystująca moduł obsługi do wysyłania wiadomości do wątku looper:
Korzystam z tej klasy z niestandardowego wątku looper, takiego jak następujący:
gdzie Współrzędne to prosta klasa o dwóch właściwościach: szerokości i długości geograficznej.
źródło
Stworzyłem małą aplikację z opisem krok po kroku, aby uzyskać współrzędne GPS bieżących lokalizacji.
Kompletny przykładowy kod źródłowy w poniższym adresie URL:
Zobacz jak to działa :
Wszystko, co musimy zrobić, to dodać to uprawnienie do pliku manifestu
i utwórz instancję LocationManager w ten sposób
Sprawdź, czy GPS jest włączony czy nie
następnie zaimplementuj LocationListener i uzyskaj współrzędne
oto przykładowy kod do zrobienia
źródło
Zawsze możesz po prostu użyć LocationManager.getLastKnownLocation (), ale jak to mówi, może to być nieaktualne.
A prostym sposobem na uzyskanie ogólnej lokalizacji może być rejestracja w sieci (zazwyczaj dość szybko).
a potem robiąc
w
onLocationChanged()
metodzie słuchacza.źródło
Napisałem szczegółowy samouczek obejmujący bieżącą lokalizację tutaj na demonuts.com . Możesz znaleźć więcej opisu tutaj, a także możesz pobrać cały kod źródłowy wersji demonstracyjnej dla lepszego zrozumienia.
Istnieje już wiele odpowiedzi, ale chcę pokazać najnowszy sposób uzyskania lokalizacji za pomocą Google API, aby nowi programiści mogli zastosować nową metodę:
Przede wszystkim umieść to w pliku gradle
następnie zaimplementuj niezbędne interfejsy
deklarować instancje
włóż to
onCreate()
W końcu zastąp wszystkie niezbędne metody
Nie zapomnij uruchomić GPS w urządzeniu przed uruchomieniem aplikacji.
źródło
W rzeczywistości możemy korzystać z dwóch dostawców (GPS i SIEĆ). I po prostu udostępniają publicznego słuchacza:
Jest to konieczne, ponieważ
OnLocationChanged()
metodę należy zawsze wywołać na czas.źródło
Nie jestem pewien, czy usługi oparte na lokalizacji mogą uzyskać lokalizację z innych infrastruktur innych niż GPS, ale zgodnie z tym artykułem wydaje się możliwe:
źródło
Użyj poniższego kodu, aby dać najlepszego dostępnego dostawcę:
źródło
Zalecanym sposobem na to jest użycie
LocationClient
:Najpierw zdefiniuj wartości interwału aktualizacji lokalizacji. Dostosuj to do swoich potrzeb.
Wyraź swoją
Activity
wdrożeniaGooglePlayServicesClient.ConnectionCallbacks
,GooglePlayServicesClient.OnConnectionFailedListener
orazLocationListener
.Następnie uruchamiamy
LocationClient
wonCreate()
sposób dokonaniaActivity
:Dodaj wymagane metody do swojego
Activity
;onConnected()
to metoda wywoływana podczasLocationClient
łączenia.onLocationChanged()
jest to miejsce, w którym pobierzesz najbardziej aktualną lokalizację.Pamiętaj, aby podłączyć / odłączyć,
LocationClient
aby zużywał dodatkową baterię tylko wtedy, gdy jest to absolutnie konieczne, aby GPS nie działał w nieskończoność.LocationClient
Muszą być połączone w celu uzyskania danych z niego.Uzyskaj lokalizację użytkownika. Najpierw spróbuj użyć
LocationClient
; jeśli to się nie powiedzie, wróć doLocationManager
.źródło
Mimo że odpowiedź jest już tutaj podana. Chciałem po prostu podzielić się tym ze światem, aby nie spotkać takiego scenariusza.
Moim wymaganiem było to, że potrzebowałem uzyskać bieżącą lokalizację użytkownika w ciągu maksymalnie 30 do 35 sekund, więc oto rozwiązanie, które podjąłem po odpowiedzi Nirav Ranpara .
1. Zrobiłem MyLocationManager.java klasę, która obsługuje wszystkie rzeczy GPS i sieci
2. Zrobiłem interfejs Onback (Callback) OnLocationDetectectionListener.java w celu przekazania wyników z powrotem do fragmentu lub działania wywołującego
3. Następnie wykonałem działanie MainAppActivty.java, które implementuje
OnLocationDetectectionListener
interfejs i oto jak otrzymuję w nim moją lokalizację4. Dodaj następujące uprawnienia do pliku manifestu
Mam nadzieję, że jest to pomocne dla innych :)
źródło
Od ponad roku korzystam z kombinacji GPS_PROVIDER i NETWORK_PROVIDER, aby uzyskać bieżącą lokalizację i działała dobrze, ale od kilku ostatnich miesięcy uzyskuję lokalizację z dużym opóźnieniem, więc przełączyłem się na najnowszy interfejs API FusedLocationProviderClient i działa całkiem dobrze.
Oto klasa, którą napisałem, aby uzyskać bieżącą lokalizację za pomocą FusedLocationProviderClient. W poniższym kodzie użyłem timera, aby poczekać, aż uzyskasz aktualną lokalizację, zaplanowałem minutnik 15 sekund opóźnienia, możesz go zmienić według własnego uznania.
Nazywam to od aktywności, oto kod
Dodaj następujące wpisy w pliku AndroidManifest.xml
źródło
źródło
Jest to kod, który podaje bieżącą lokalizację użytkownika
utwórz mapy Aktywność:
main.xml:
i zdefiniuj następujące zezwolenie w manifeście:
źródło
W ten sposób żądam uprawnień użytkownika.
Poza tagiem aplikacji w AndroidManifest.xml dodaj te prośby o uprawnienia.
Następnie dodaj zależności lokalizacji Google w pliku oceny aplikacji.
Teraz zadeklaruj niektóre zmienne globalne.
W metodzie OnCreate Twojej aktywności (nie byłem w stanie poprawnie sformatować kodu, przepraszam za to)
Teraz utwórz obie funkcje.
Druga metoda
Dla Constant.kt
źródło
Ulepszenia rozwiązania @ Fedor. Zamiast żądać lokalizacji z interwałem „0” i odległości „0”, możemy użyć metody requestSingleUpdate menedżera lokalizacji . Zaktualizowany kod (wersja kotlin)
Aby uzyskać lokalizację, wystarczy wywołać metodę getLocation jako -
Uwaga: Przed wywołaniem metody getLocation należy udzielić wymaganego pozwolenia na lokalizację.
źródło
Aby uzyskać i wyświetlić bieżącą lokalizację użytkownika, możesz również użyć
MyLocationOverlay
. Załóżmy, że maszmapView
pole w swojej działalności. Wszystko, co musisz zrobić, aby pokazać lokalizację użytkownika, to:Pobiera bieżącą lokalizację z GPS lub sieci. Jeśli oba zawiodą,
enableMyLocation()
wrócifalse
.Jeśli chodzi o lokalizacje rzeczy w okolicy,
ItemizedOverlay
należy załatwić sprawę.Mam nadzieję, że nie zrozumiałem źle twojego pytania. Powodzenia.
źródło
EDYCJA: Zaktualizowana o najnowszy interfejs API usługi lokalizacji z biblioteki usług Google Play (lipiec 2014)
Polecam korzystanie z nowego interfejsu API usługi lokalizacji , dostępnego w bibliotece usług Google Play, który zapewnia bardziej zaawansowaną strukturę wysokiego poziomu, która automatyzuje zadania, takie jak wybór dostawcy lokalizacji i zarządzanie energią. Zgodnie z oficjalną dokumentacją: „... Interfejs API lokalizacji ułatwia tworzenie aplikacji rozpoznających lokalizację, bez konieczności skupiania się na szczegółach podstawowej technologii lokalizacji. Pozwalają również zminimalizować zużycie energii dzięki wykorzystaniu wszystkich możliwości sprzętu urządzenia ”.
Więcej informacji na stronie: Making A App Location-Aware
Aby zobaczyć pełny przykład z wykorzystaniem najnowszej wizyty interfejsu API usługi lokalizacji: klasa LocationClient systemu Android jest przestarzała, ale używana w dokumentacji
źródło
Prosty i najlepszy sposób na GeoLokalizację.
źródło
Trochę późno tutaj, ale w takiej sytuacji chciałbym użyć interfejsu API Map Google i oznaczyć pobliskie lokalizacje za pomocą długiego i długiego interfejsu API map Google. Plus doświadczenie użytkownika jest lepsze, jeśli możesz pokazać jego / jej lokalizację na mapie. Nie musisz zawracać sobie głowy aktualizacją lokalizacji użytkownika lub szukaniem w interfejsie Android. Pozwól, aby mapy Google obsługiwały elementy wewnętrzne za Ciebie
@emmby mógł rozwiązać ten problem w swojej aplikacji, ale w celu zapoznania się z nim w przyszłości warto zapoznać się z interfejsem API map Google dla konkretnych lokalizacji, co polecam innym programistom.
Edycja: Link do wyświetlania lokalizacji użytkownika na mapach Google
źródło
Wymaga wielu rzeczy, aby uzyskać aktualizacje lokalizacji w Androidzie, wymaga dużo kodu bolierplate.
Musisz się zająć
Stworzyłem Android-EasyLocation (mała biblioteka Androida), który zajmie się wszystkimi tymi rzeczami i możesz skupić się na logice biznesowej.
Wszystko czego potrzebujesz to rozszerzyć EasyLocationActivity i to
lub
Kasa przykładowa aplikacja i kroki potrzebne tutaj na https://github.com/akhgupta/Android-EasyLocation
źródło
Oto co robię:
mFinalLocation
).onDestroy()
metodzie usługi przestaje nasłuchiwać aktualizacji lokalizacji dla każdego dostawcy.Poniżej znajduje się kod usługi. Możesz go uruchomić w oparciu o częstotliwość aktualizacji lokalizacji, której potrzebujesz.
źródło
Odpowiedź @Fedor Greate na wersję Kotlin :
użycie klasy:
MyLocation
Klasa :źródło
W klasie aktywności tworzy niestandardową metodę:
Utwórz nazwę klasy UserDefined LocationGetter: -
źródło
Korzystając z FusedLocationProviderApi, który jest najnowszym API i najlepszym spośród dostępnych możliwości uzyskania lokalizacji w Androidzie. dodaj to do pliku build.gradle
pełny kod źródłowy można uzyskać pod tym adresem URL http://javapapers.com/android/android-location-fused-provider/
źródło
Niedawno przebudowano, aby uzyskać lokalizację kodu, poznać kilka dobrych pomysłów, a na koniec udało się uzyskać stosunkowo idealną bibliotekę i wersję demonstracyjną.
Cały kod: https://github.com/bingerz/FastLocation/blob/master/fastlocationlib/src/main/java/cn/bingerz/fastlocation/FastLocation.java
* Każde żądanie uzupełnienia lokalizacji najlepiej usunąć Aktualizacje, w przeciwnym razie na pasku stanu telefonu zawsze będzie wyświetlana ikona pozycjonowania.
źródło
Po obejrzeniu wszystkich odpowiedzi i pytania ( najprostsze i niezawodne ). Kliknąłem tylko o bibliotekę Android-ReactiveLocation .
Kiedy stworzyłem aplikację do śledzenia lokalizacji. Potem zdałem sobie sprawę, że bardzo typowe jest obsługiwanie śledzenia lokalizacji za pomocą zoptymalizowanego akumulatora.
Chcę więc powiedzieć odświeżającym, a także programistom, którzy nie chcą utrzymywać swojego kodu lokalizacji przy przyszłych optymalizacjach. Użyj tej biblioteki.
Zależności do umieszczenia w build.gradle na poziomie aplikacji
Profesjonaliści używający tej biblioteki:
źródło