Die LocationManager
API unter Android scheint für eine Anwendung, die nur gelegentlich und grob eine Annäherung an den Standort des Benutzers benötigt, etwas mühsam zu sein.
Die App, an der ich arbeite, ist eigentlich keine Standort-App an sich, aber sie muss den Standort des Benutzers ermitteln, um eine Liste der Unternehmen in der Nähe anzuzeigen. Es muss sich keine Sorgen machen, ob sich der Benutzer bewegt oder so etwas.
Folgendes möchte ich tun:
- Zeigen Sie dem Benutzer eine Liste der Standorte in der Nähe.
- Laden Sie den Standort des Benutzers vor
Activity
, damit er verfügbar ist, sobald ich ihn in X benötige . - Die Genauigkeit oder Häufigkeit der Aktualisierung ist mir nicht besonders wichtig. Es reicht aus, nur einen Ort zu ergattern, solange er nicht weit entfernt ist. Wenn ich Lust habe, aktualisiere ich den Standort vielleicht alle paar Minuten oder so, aber das hat keine große Priorität.
- Arbeiten Sie für jedes Gerät, solange es über ein GPS oder einen Netzwerkstandortanbieter verfügt.
Es scheint, dass es nicht so schwer sein sollte, aber es scheint mir, dass ich zwei verschiedene Standortanbieter (GPS und NETWORK) hochfahren und den Lebenszyklus jedes einzelnen verwalten muss. Nicht nur das, sondern ich muss den gleichen Code in mehreren Aktivitäten duplizieren, um # 2 zu erfüllen. Ich habe getBestProvider()
in der Vergangenheit versucht, die Lösung auf nur einen Standortanbieter zu reduzieren, aber das scheint Ihnen nur den besten "theoretischen" Anbieter zu bieten, anstatt den Anbieter, der Ihnen tatsächlich die besten Ergebnisse liefert.
Gibt es einen einfacheren Weg, dies zu erreichen?
Antworten:
Folgendes mache ich:
So benutze ich meine Klasse:
Und hier ist die MyLocation-Klasse:
Jemand möchte vielleicht auch meine Logik ändern. Wenn Sie beispielsweise ein Update vom Netzwerkanbieter erhalten, stoppen Sie die Listener nicht, sondern warten Sie weiter. GPS liefert genauere Daten, daher lohnt es sich, darauf zu warten. Wenn der Timer abgelaufen ist und Sie ein Update vom Netzwerk, aber nicht vom GPS erhalten haben, können Sie den vom Netzwerk bereitgestellten Wert verwenden.
Ein weiterer Ansatz ist die Verwendung von LocationClient http://developer.android.com/training/location/retrieve-current.html . Es erfordert jedoch, dass Google Play Services apk auf dem Benutzergerät installiert ist.
quelle
Nachdem ich nach der besten Implementierung gesucht hatte, um den genauesten Benutzerstandort zu erhalten, gelang es mir, die besten Methoden zu kombinieren und die folgende Klasse zu finden:
Diese Klasse versucht, eine Verbindung zu
min_gps_sat_count
Satelliten herzustellen, wenn GPS aktiviert ist. Andernfalls wird derLocationManager.getBestProvider()
Standort zurückgegeben. Überprüfen Sie den Code!quelle
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;
Mit der Fedor-Lösung habe ich den Rückruf mehrfach ausgeführt
gotLocation
. Es scheint , aufgrund einer sein Race - Bedingung in der überschriebenenLocationListener.onLocationChanged
Methode, wenn gotLocation Methode ist ‚lange genug‘ . Ich bin mir nicht sicher, aber ich denke, esremoveUpdates
verhindert das Einreihen neuer Nachrichten in die Looper-Warteschlange, aber es entfernt nicht die bereits eingereihten, aber noch nicht verbrauchten Nachrichten. Daher die Rennbedingung.Um die Wahrscheinlichkeit dieses falschen Verhaltens zu verringern, können Sie removeUpdates aufrufen, bevor Sie das Ereignis onLocationChanged auslösen. Wir haben jedoch weiterhin die Race-Bedingung.
Die beste Lösung, die ich gefunden habe, ist das Ersetzen
requestLocationUpdates
durchrequestSingleUpdate
.Dies ist meine Version, die auf der Fedor-Lösung basiert und einen Handler verwendet, um eine Nachricht an den Looper-Thread zu senden:
Ich verwende diese Klasse aus einem angepassten Looper-Thread wie dem folgenden:
Dabei ist Koordinaten eine einfache Klasse mit zwei Eigenschaften: Breiten- und Längengrad.
quelle
Ich habe eine kleine Anwendung mit einer schrittweisen Beschreibung erstellt, um die GPS-Koordinaten der aktuellen Standorte abzurufen.
Vollständiger Beispielquellcode in der folgenden URL:
Sehen, wie es funktioniert :
Wir müssen diese Berechtigung lediglich in die Manifestdatei einfügen
und erstellen Sie die LocationManager-Instanz wie folgt
Überprüfen Sie, ob GPS aktiviert ist oder nicht
Implementieren Sie dann LocationListener und Get Coordinates
Hier ist der Beispielcode
quelle
Sie könnten immer nur LocationManager.getLastKnownLocation () verwenden, aber wie es heißt, könnte es veraltet sein.
Ein einfacher Weg, um einen allgemeinen Standort zu erhalten, könnte die Registrierung für das Netzwerk sein (normalerweise ziemlich schnell).
und dann tun
in der
onLocationChanged()
Methode des Hörers.quelle
Ich habe ein detailliertes Tutorial über den aktuellen Standort hier aufodemuts.com geschrieben. Weitere Beschreibungen finden Sie hier. Zum besseren Verständnis können Sie auch den gesamten Demo-Quellcode herunterladen.
Es gibt dort bereits viele Antworten, aber ich möchte den neuesten Weg zeigen, um mithilfe der Google-API den Standort zu ermitteln, damit neue Programmierer neue Methoden verwenden können:
Legen Sie dies zunächst in eine Gradle-Datei
Implementieren Sie dann die erforderlichen Schnittstellen
Instanzen deklarieren
Gib das ein
onCreate()
Überschreiben Sie schließlich die erforderlichen Methoden
Vergessen Sie nicht, GPS auf Ihrem Gerät zu starten, bevor Sie die App ausführen.
quelle
Tatsächlich können wir die beiden Anbieter (GPS & NETWORK) verwenden. Und sie teilen nur einen öffentlichen Zuhörer:
Dies ist notwendig, da die
OnLocationChanged()
Methode immer rechtzeitig aufgerufen werden muss.quelle
Ich bin nicht sicher, ob die standortbasierten Dienste den Standort von anderen Infrastrukturen als GPS abrufen können, aber laut diesem Artikel scheint dies möglich zu sein:
quelle
Verwenden Sie den folgenden Code, um den besten verfügbaren Anbieter zu erhalten:
quelle
Der empfohlene Weg, dies zu tun, ist
LocationClient
:Definieren Sie zunächst die Werte für das Standortaktualisierungsintervall. Passen Sie dies an Ihre Bedürfnisse an.
Haben Sie Ihre
Activity
implementierenGooglePlayServicesClient.ConnectionCallbacks
,GooglePlayServicesClient.OnConnectionFailedListener
undLocationListener
.Richten Sie dann eine
LocationClient
in deronCreate()
Methode IhresActivity
:Fügen Sie die erforderlichen Methoden zu Ihrem hinzu
Activity
;onConnected()
ist die Methode, die aufgerufen wird, wenn dieLocationClient
Verbindung hergestellt wird.onLocationChanged()
Hier finden Sie den aktuellsten Speicherort.Stellen Sie sicher,
LocationClient
dass Sie das Gerät anschließen / trennen, damit nur dann ein zusätzlicher Akku verwendet wird, wenn dies unbedingt erforderlich ist und das GPS nicht unbegrenzt läuft. DieLocationClient
müssen verbunden sein, um Daten daraus zu erhalten.Holen Sie sich den Standort des Benutzers. Versuchen Sie zuerst, die
LocationClient
; Wenn dies fehlschlägt, greifen Sie auf dieLocationManager
.quelle
Auch wenn die Antwort hier schon gegeben ist. Ich wollte dies nur der Welt mitteilen, falls ich auf ein solches Szenario stoße.
Meine Anforderung war, dass ich den aktuellen Standort eines Benutzers innerhalb von maximal 30 bis 35 Sekunden ermitteln musste. Hier ist die Lösung, die ich nach Nirav Ranparas Antwort gefunden habe .
1. Ich habe die MyLocationManager.java- Klasse erstellt, die alle GPS- und Netzwerkaufgaben übernimmt
2. Ich habe eine Schnittstelle (Rückruf) OnLocationDetectectionListener.java erstellt , um die Ergebnisse an das aufrufende Fragment oder die aufrufende Aktivität zurückzusenden
3. Dann habe ich eine MainAppActivty.java- Aktivität erstellt, die die
OnLocationDetectectionListener
Schnittstelle implementiert , und hier ist, wie ich meinen Standort darin erhalte4. Fügen Sie Ihrer Manifestdatei die folgenden Berechtigungen hinzu
Hoffe das ist hilfreich für andere :)
quelle
In den letzten mehr als einem Jahr habe ich die Kombination aus GPS_PROVIDER und NETWORK_PROVIDER verwendet, um den aktuellen Standort zu ermitteln, und es hat gut funktioniert. In den letzten Monaten habe ich den Standort jedoch nach einer langen Verzögerung ermittelt, sodass ich auf die neueste API FusedLocationProviderClient und umgestellt habe es funktioniert ziemlich gut.
Hier ist die Klasse, die ich geschrieben habe, um mithilfe von FusedLocationProviderClient den aktuellen Standort abzurufen. Im folgenden Code habe ich einen Timer verwendet, um zu warten, bis der aktuelle Standort abgerufen wurde. Ich habe einen Timer mit einer Verzögerung von 15 Sekunden eingeplant. Sie können ihn nach Ihren Wünschen ändern.
Und dies aus Aktivität genannt, hier ist der Code
Fügen Sie die folgenden Einträge in die Datei AndroidManifest.xml ein
quelle
quelle
Dies ist der Code, der den aktuellen Standort des Benutzers angibt
Karten erstellen Aktivität:
main.xml:
und definieren Sie folgende Berechtigung im Manifest:
quelle
Auf diese Weise fordere ich Benutzerberechtigungen an.
Fügen Sie diese Berechtigungsanforderungen außerhalb Ihres Anwendungs-Tags in AndroidManifest.xml hinzu.
Fügen Sie dann die Standortabhängigkeiten von Google in die App Gradle-Datei ein.
Deklarieren Sie nun einige globale Variablen.
In der OnCreate-Methode Ihrer Aktivität (Ich konnte den Code nicht richtig formatieren, Entschuldigung dafür)
Erstellen Sie nun beide Funktionen.
Zweite Methode
Für Constant.kt
quelle
Verbesserungen an der @ Fedor-Lösung. Anstatt einen Standort mit dem Zeitintervall '0' und der Entfernung '0' anzufordern, können wir die requestSingleUpdate- Methode des Standortmanagers verwenden. Aktualisierter Code (Kotlin-Version)
Um den Standort abzurufen, rufen Sie einfach die Methode getLocation als - auf
Hinweis: Vor dem Aufrufen der getLocation-Methode muss die erforderliche Standortberechtigung erteilt werden.
quelle
Sie können auch den aktuellen Standort des Benutzers abrufen und anzeigen
MyLocationOverlay
. Angenommen, Sie haben einmapView
Feld in Ihrer Aktivität. Alles, was Sie tun müssten, um den Benutzerstandort anzuzeigen, ist Folgendes:Dadurch wird der aktuelle Standort entweder vom GPS oder vom Netzwerk abgerufen. Wenn beide fehlschlagen,
enableMyLocation()
wird zurückgegebenfalse
.Was die Standorte der Dinge in der Umgebung betrifft,
ItemizedOverlay
sollte man den Trick machen.Ich hoffe, ich habe Ihre Frage nicht falsch verstanden. Viel Glück.
quelle
BEARBEITEN: Aktualisiert mit der neuesten Location Service-API aus der Google Play Services-Bibliothek (Juli 2014)
Ich würde Ihnen empfehlen, die neue Location Service-API zu verwenden , die in der Google Play Services-Bibliothek verfügbar ist und ein leistungsfähigeres Framework auf hoher Ebene bietet, das Aufgaben wie die Auswahl des Standortanbieters und die Energieverwaltung automatisiert. In der offiziellen Dokumentation heißt es: "... Mit der Standort-API können Sie auf einfache Weise standortbezogene Anwendungen erstellen, ohne sich auf die Details der zugrunde liegenden Standorttechnologie konzentrieren zu müssen. Außerdem können Sie den Stromverbrauch minimieren, indem Sie alle Funktionen nutzen der Gerätehardware. "
Weitere Informationen finden Sie unter: Machen Sie Ihre App standortbewusst
Ein vollständiges Beispiel mit der neuesten Location Service-API finden Sie unter: Die Android LocationClient-Klasse ist veraltet, wird jedoch in der Dokumentation verwendet
quelle
Einfacher und bester Weg für GeoLocation.
quelle
Ein bisschen spät hier, aber in einer solchen Situation würde ich die Google Maps-API verwenden und die nahe gelegenen Standorte mit der Lat- und Long-API von Google Maps markieren. Außerdem ist die Benutzererfahrung besser, wenn Sie seinen Standort auf einer Karte anzeigen können. Sie müssen sich nicht um die Aktualisierung des Benutzerstandorts oder das Durchsuchen mit der Android-API kümmern. Lassen Sie Google Maps die Interna für Sie erledigen.
@emmby hat es möglicherweise in seiner App gelöst, aber als zukünftige Referenz empfehle ich anderen Entwicklern einen Blick auf die Google Maps-API für standortspezifische Dinge.
Bearbeiten: Link zum Anzeigen des Nutzerstandorts in Google Maps
quelle
Es erfordert viele Dinge, um Standortaktualisierungen in Android zu erhalten, erfordert viel Bolierplate-Code.
Sie müssen sich kümmern
Ich habe Android-EasyLocation (kleine Android-Bibliothek) erstellt, die sich um all diese Dinge kümmert, und Sie können sich auf die Geschäftslogik konzentrieren.
Alles was Sie brauchen, ist EasyLocationActivity zu erweitern und dies
oder
Checkout-Beispiel-App und erforderliche Schritte finden Sie hier unter https://github.com/akhgupta/Android-EasyLocation
quelle
Folgendes mache ich:
mFinalLocation
).onDestroy()
der Dienstmethode auf Standortaktualisierungen für jeden Anbieter wartet.Unten finden Sie den Code für den Service. Sie können es basierend auf der Häufigkeit der benötigten Standortaktualisierung ausführen.
quelle
Kotlin-Version von @Fedor Greate Antwort:
Verwendung der Klasse:
MyLocation
Klasse:quelle
In der Aktivitätsklasse wird eine angepasste Methode erstellt:
Erstellen Sie einen benutzerdefinierten Klassennamen. LocationGetter: -
quelle
Durch die Verwendung von FusedLocationProviderApi, der neuesten API und der besten unter den verfügbaren Möglichkeiten, den Standort in Android zu ermitteln. Fügen Sie dies in die Datei build.gradle ein
Den vollständigen Quellcode erhalten Sie unter dieser URL: http://javapapers.com/android/android-location-fused-provider/
quelle
Kürzlich überarbeitet, um den Speicherort des Codes zu ermitteln, einige gute Ideen zu erlernen und schließlich eine relativ perfekte Bibliothek und Demo zu erhalten.
Vollständiger Code: https://github.com/bingerz/FastLocation/blob/master/fastlocationlib/src/main/java/cn/bingerz/fastlocation/FastLocation.java
* Bei jeder Anforderung zum Vervollständigen des Standorts entfernen Sie am besten Aktualisierungen. Andernfalls wird in der Statusleiste des Telefons immer das Positionierungssymbol angezeigt.
quelle
Nachdem Sie alle Antworten und Fragen gesehen haben (am einfachsten und am robustesten ). Ich habe nur über die Bibliothek Android-ReactiveLocation geklickt .
Als ich eine Standortverfolgungs-App erstellt habe. Dann wurde mir klar, dass es sehr typisch ist, die Standortverfolgung mit optimierter Batterie durchzuführen.
Deshalb möchte ich Neulingen und auch Entwicklern mitteilen, die ihren Standortcode nicht mit zukünftigen Optimierungen pflegen möchten. Verwenden Sie diese Bibliothek.
Abhängigkeiten, die in build.gradle auf App-Ebene eingefügt werden sollen
Vorteile, um diese Bibliothek zu verwenden:
quelle