Als Entwickler von SpeedView: GPS-Tachometer für Android muss ich jede mögliche Lösung für dieses Problem ausprobiert haben, alle mit dem gleichen negativen Ergebnis. Lassen Sie uns wiederholen, was nicht funktioniert:
- onStatusChanged () wird bei Eclair und Froyo nicht aufgerufen.
- Das einfache Zählen aller verfügbaren Satelliten ist natürlich nutzlos.
- Es ist auch nicht sehr hilfreich zu überprüfen, ob einer der Satelliten für usedInFix () true zurückgibt. Das System verliert den Fix eindeutig, meldet jedoch weiterhin, dass noch mehrere Sats darin verwendet werden.
Hier ist die einzige funktionierende Lösung, die ich gefunden habe und die ich tatsächlich in meiner App verwende. Angenommen, wir haben diese einfache Klasse, die den GpsStatus.Listener implementiert:
private class MyGPSListener implements GpsStatus.Listener {
public void onGpsStatusChanged(int event) {
switch (event) {
case GpsStatus.GPS_EVENT_SATELLITE_STATUS:
if (mLastLocation != null)
isGPSFix = (SystemClock.elapsedRealtime() - mLastLocationMillis) < 3000;
if (isGPSFix) { // A fix has been acquired.
// Do something.
} else { // The fix has been lost.
// Do something.
}
break;
case GpsStatus.GPS_EVENT_FIRST_FIX:
// Do something.
isGPSFix = true;
break;
}
}
}
OK, jetzt fügen wir in onLocationChanged () Folgendes hinzu:
@Override
public void onLocationChanged(Location location) {
if (location == null) return;
mLastLocationMillis = SystemClock.elapsedRealtime();
// Do something.
mLastLocation = location;
}
Und das ist es. Grundsätzlich ist dies die Linie, die alles macht:
isGPSFix = (SystemClock.elapsedRealtime() - mLastLocationMillis) < 3000;
Sie können den Millis-Wert natürlich anpassen, aber ich würde vorschlagen, ihn auf 3-5 Sekunden einzustellen.
Dies funktioniert tatsächlich und obwohl ich mir den Quellcode, der das native GPS-Symbol zeichnet, nicht angesehen habe, kommt dies der Replikation seines Verhaltens nahe. Hoffe das hilft jemandem.
mLastLocationMillis
von einer anderen Quelle als dem GPS eingestellt wurde? Das System würde dann behaupten, dass diesisGPSFix
wahr ist, aber in Wirklichkeit ist es nur eine Lösung (vielleicht eine aus dem Telefonnetz)Das GPS-Symbol scheint seinen Status entsprechend den empfangenen Sendeabsichten zu ändern. Sie können den Status selbst mit den folgenden Codebeispielen ändern:
Benachrichtigen Sie, dass das GPS aktiviert wurde:
Benachrichtigen Sie, dass das GPS Korrekturen empfängt:
Benachrichtigen Sie, dass das GPS keine Korrekturen mehr empfängt:
Benachrichtigen Sie, dass das GPS deaktiviert wurde:
Beispielcode zum Registrieren des Empfängers in der Absicht:
Durch den Empfang dieser Broadcast-Absichten können Sie die Änderungen des GPS-Status feststellen. Sie werden jedoch nur benachrichtigt, wenn sich der Status ändert. Daher ist es nicht möglich, den aktuellen Zustand unter Verwendung dieser Absichten zu bestimmen.
quelle
neues Mitglied, daher bin ich leider nicht in der Lage zu kommentieren oder abzustimmen, aber Stephen Dayes Beitrag oben war die perfekte Lösung für genau das gleiche Problem, bei dem ich Hilfe gesucht habe.
eine kleine Änderung an der folgenden Zeile:
zu:
Im Grunde genommen, da ich ein langsames Spiel baue und mein Update-Intervall bereits auf 5 Sekunden eingestellt ist, ist das der richtige Zeitpunkt, um etwas auszulösen, sobald das GPS-Signal für mehr als 10 Sekunden aus ist.
Prost Kumpel, habe ungefähr 10 Stunden damit verbracht, diese Lösung zu lösen, bevor ich deinen Beitrag gefunden habe :)
quelle
Ok, also versuchen wir eine Kombination aller bisherigen Antworten und Updates und machen so etwas:
ACCESS_FINE_LOCATION
Berechtigung zu Ihrem Manifest hinzuLocationManager
GpsStatus.Listener
, die darauf reagiertGPS_EVENT_SATELLITE_STATUS
LocationManager
beiaddGpsStatusListener
Der GPS-Listener könnte ungefähr so aussehen:
Die APIs sind etwas unklar, wann und welche GPS- und Satelliteninformationen bereitgestellt werden, aber ich denke, eine Idee wäre, zu prüfen, wie viele Satelliten verfügbar sind. Wenn es unter drei ist, können Sie keine Lösung finden. Wenn es mehr ist, sollten Sie eine Lösung haben.
Versuch und Irrtum ist wahrscheinlich der richtige Weg, um festzustellen, wie oft Android Satelliteninformationen meldet und welche Informationen jedes
GpsSatellite
Objekt enthält.quelle
GpsSatellite
Objekt abgerufen werden können.LocationManager.requestLocationUpdates
mit den Zeit- und Entfernungseinstellungen auf 0 zu verwenden? Das sollte Ihnen GPS-Korrekturen senden, sobald sie eintreten. Wenn Sie nichts erhalten, haben Sie höchstwahrscheinlich keine Lösung. Sie können dies mit dem obigen Status-Listener kombinieren, wenn Sie möchten.Nachdem ich einige Jahre mit GPS auf Windows Mobile gearbeitet hatte, wurde mir klar, dass das Konzept, einen GPS-Fix zu "verlieren", subjektiv sein kann. Um einfach zu hören, was das GPS Ihnen sagt, können Sie durch Hinzufügen eines NMEAListener und Analysieren des Satzes feststellen, ob der Fix "gültig" war oder nicht. Siehe http://www.gpsinformation.org/dale/nmea.htm#GGA . Leider schwankt dieser Wert bei einigen GPS-Geräten auch während des normalen Betriebs in einem Bereich mit "guter Reparatur" hin und her.
Die andere Lösung besteht darin, die UTC-Zeit des GPS-Standorts mit der Zeit des Telefons zu vergleichen (in UTC konvertiert). Wenn sie einen bestimmten Zeitunterschied voneinander haben, können Sie davon ausgehen, dass Sie die GPS-Position verloren haben.
quelle
Wenn Sie bei der Arbeit an meinem MSc-Projekt auf ein ähnliches Problem stoßen, scheint es, dass Dayes Antwort fälschlicherweise "no fix" gemeldet hat, während sich das Gerät an einem statischen Ort befindet. Ich habe die Lösung nur ein wenig modifiziert, was an einem statischen Ort für mich gut zu funktionieren scheint. Ich weiß nicht, wie sich dies auf die Batterie auswirken würde, da dies nicht mein Hauptanliegen ist, aber hier ist, wie ich es getan habe, indem ich Standortaktualisierungen erneut angefordert habe, wenn ein Fix abgelaufen ist.
quelle
Nun, wenn Sie jeden Arbeitsansatz zusammenstellen, wird dies dazu führen (auch im Umgang mit veralteten
GpsStatus.Listener
):Hinweis: Diese Antwort ist eine Kombination der obigen Antworten.
quelle
Wenn Sie nur wissen müssen, ob ein Fix vorliegt, suchen Sie nach dem letzten bekannten Ort, den der GPS-Empfänger angegeben hat, und überprüfen Sie den Wert .getTime (), um festzustellen, wie alt dieser ist. Wenn es aktuell genug ist (wie ... ein paar Sekunden), haben Sie eine Lösung.
... und vergleichen Sie das schließlich mit der aktuellen Datumszeit (In UTC!). Wenn es aktuell genug ist, haben Sie eine Lösung.
Ich mache das in meiner App und soweit so gut.
quelle
Sie können versuchen, mit LocationManager.addGpsStatusListener aktualisiert zu werden, wenn sich der GPS-Status ändert. Es sieht so aus, als ob GPS_EVENT_STARTED und GPS_EVENT_STOPPED genau das sind, wonach Sie suchen.
quelle
GPS_EVENT_FIRST_FIX
Klängen wie eine engere Anpassung.Ich kann mich irren, aber es scheint, dass die Leute weit vom Thema abweichen
Das ist leicht zu machen
Um zu sehen, ob Sie eine solide Lösung haben, wird es etwas schwieriger:
Wann immer Sie sehen wollen, ob Sie eine Lösung haben?
Wenn Sie Lust haben, können Sie mit System.currentTimeMillis () und loc.getTime () jederzeit eine Zeitüberschreitung haben.
Funktioniert zuverlässig, zumindest auf einem N1 seit 2.1.
quelle
Mit LocationManager können Sie LastKnownLocation () nach getBestProvider () abrufen. Dadurch erhalten Sie ein Location-Objekt mit den Methoden getAccuracy () in Metern und getTime () in UTC-Millisekunden
Gibt dir das genug Infos?
Oder vielleicht können Sie die LocationProvider durchlaufen und herausfinden, ob jeder die Kriterien erfüllt (ACCURACY_COARSE).
quelle
so viele Beiträge ...
Wenn Sie diesen Code mit addGpsListener hinzufügen ... showMessageDialog ... wird nur ein Standarddialogfenster mit der Zeichenfolge angezeigt
habe den Job perfekt für mich gemacht :) Vielen Dank: =) (sry für diesen Beitrag, noch nicht abstimmbar)
quelle
Wenn Sie in dem Moment, in dem das Update verloren geht, kein Update benötigen, können Sie die Lösung von Stephen Daye so ändern, dass Sie über eine Methode verfügen, die überprüft, ob das Update noch vorhanden ist.
Sie können es also einfach überprüfen, wenn Sie GPS-Daten benötigen und diesen GpsStatus.Listener nicht benötigen.
Die "globalen" Variablen sind:
Dies ist die Methode, die in "onLocationChanged ()" aufgerufen wird, um die Aktualisierungszeit und den aktuellen Speicherort zu speichern. Außerdem wird "isGpsFix" aktualisiert:
Diese Methode wird immer dann aufgerufen, wenn ich wissen muss, ob es einen GPS-Fix gibt:
In meiner Implementierung führe ich zuerst checkGpsFix () aus und wenn das Ergebnis wahr ist, verwende ich die Variable "lastKnownLocation" als meine aktuelle Position.
quelle
Ich weiß, das ist etwas spät. Verwenden Sie jedoch den NMEAListener, wenn Sie wissen möchten, ob Sie einen Fix haben. Nach dem, was ich gelesen habe, gibt Ihnen der NMEAListener die NMEA-Sätze und von dort wählen Sie den richtigen Satz aus.
Der RMC-Satz enthält den Fixstatus, der entweder A für OK oder V für Warnung ist. Der GGA-Satz enthält die Fix-Qualität (0 ungültig, 1 GPS oder 2 DGPS).
Ich kann Ihnen keinen Java-Code anbieten, da ich gerade erst mit Android anfange, aber ich habe eine GPS-Bibliothek in C # für Windows-Apps erstellt, die ich mit Xamarin verwenden möchte. Ich bin nur auf diesen Thread gestoßen, weil ich nach Anbieterinformationen gesucht habe.
Nach dem, was ich bisher über das Location-Objekt gelesen habe, bin ich mit Methoden wie getAccuracy () und hasAccuracy () nicht besonders vertraut. Ich bin es gewohnt, aus den NMEA-Sätzen HDOP- und VDOP-Werte zu extrahieren, um festzustellen, wie genau meine Korrekturen sind. Es ist durchaus üblich, einen Fix zu haben, aber einen miesen HDOP, was bedeutet, dass Ihre horizontale Genauigkeit überhaupt nicht sehr gut ist. Wenn Sie beispielsweise an Ihrem Schreibtisch sitzen und mit einem externen Bluetooth-GPS-Gerät gegen ein Fenster debuggen, erhalten Sie wahrscheinlich eine Lösung, aber sehr schlechtes HDOP und VDOP. Stellen Sie Ihr GPS-Gerät in einen Blumentopf draußen oder ähnliches oder fügen Sie dem GPS eine externe Antenne hinzu, und Sie erhalten sofort gute HDOP- und VDOP-Werte.
quelle
Vielleicht ist es die beste Möglichkeit, eine TimerTask zu erstellen, die den empfangenen Speicherort regelmäßig auf einen bestimmten Wert (null?) Setzt. Wenn der GPSListener einen neuen Wert empfängt, wird der Standort mit den aktuellen Daten aktualisiert.
Ich denke, das wäre eine funktionierende Lösung.
quelle
Sie sagen, dass Sie bereits onStatusChanged () ausprobiert haben, aber das funktioniert bei mir.
Hier ist die Methode, die ich verwende (ich lasse die Klasse selbst den onStatusChanged verarbeiten):
Und ich gehe mit onStatusChanged wie folgt um:
Beachten Sie, dass es bei den onProvider {Dis, En} abled () -Methoden darum geht, die GPS-Verfolgung durch den Benutzer zu aktivieren und zu deaktivieren. nicht das, wonach du suchst.
quelle
Das Einstellen des Zeitintervalls für die Überprüfung auf Korrektur ist keine gute Wahl. Ich habe festgestellt, dass onLocationChanged nicht aufgerufen wird, wenn Sie sich nicht bewegen . Was ist verständlich, da sich der Standort nicht ändert :)
Besser wäre zum Beispiel:
quelle