Wie kann ich den aktuellen Status des GPS-Empfängers überprüfen?

89

Wie kann ich den aktuellen Status des GPS-Empfängers überprüfen? Ich habe die LocationListener onStatusChangedMethode bereits überprüft , aber irgendwie scheint das nicht zu funktionieren oder nur die falsche Möglichkeit.

Grundsätzlich muss ich nur wissen, ob das GPS-Symbol oben auf dem Bildschirm blinkt (kein tatsächlicher Fix) oder durchgehend (Fix ist verfügbar).

nr1
quelle

Antworten:

150

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:

  1. onStatusChanged () wird bei Eclair und Froyo nicht aufgerufen.
  2. Das einfache Zählen aller verfügbaren Satelliten ist natürlich nutzlos.
  3. 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.

Soundmaven
quelle
Hallo, ich frage mich, warum das Zählen verfügbarer Satelliten wie in diesem Beispiel nutzlos ist. Wenn die Anzahl der gefundenen Satelliten 0 ist, bedeutet dies, dass keine Verbindung besteht, oder irre ich mich? groups.google.com/group/android-developers/browse_thread/thread/…
per_jansson
3
Hallo Stephen, kannst du bitte erklären, warum isGPSFix funktioniert? Danke, Nick
Nickfox
Übrigens habe ich festgestellt, dass sie in ICS die Zeit verlängert haben, bis das System meldet, dass der GPS-Fix verloren gegangen ist. Zumindest in 4.0.3 sind es genau 10 Sekunden.
Soundmaven
Funktioniert hervorragend und die Verwendung von 10 Sekunden im Gegensatz zu 3-5 Sekunden für ICS funktioniert ebenfalls recht gut. Glücklicherweise ist das Reparieren keine notwendige Funktion meiner App, aber es ist gut, sie kennen zu können. Vielen Dank.
Tom
1
Aber bricht diese Unterbrechung nicht, wenn sie mLastLocationMillisvon einer anderen Quelle als dem GPS eingestellt wurde? Das System würde dann behaupten, dass dies isGPSFixwahr ist, aber in Wirklichkeit ist es nur eine Lösung (vielleicht eine aus dem Telefonnetz)
Patrick
25

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:

Intent intent = new Intent("android.location.GPS_ENABLED_CHANGE");
intent.putExtra("enabled", true);
sendBroadcast(intent);

Benachrichtigen Sie, dass das GPS Korrekturen empfängt:

Intent intent = new Intent("android.location.GPS_FIX_CHANGE");
intent.putExtra("enabled", true);
sendBroadcast(intent);

Benachrichtigen Sie, dass das GPS keine Korrekturen mehr empfängt:

Intent intent = new Intent("android.location.GPS_FIX_CHANGE");
intent.putExtra("enabled", false);
sendBroadcast(intent);

Benachrichtigen Sie, dass das GPS deaktiviert wurde:

Intent intent = new Intent("android.location.GPS_ENABLED_CHANGE");
intent.putExtra("enabled", false);
sendBroadcast(intent);

Beispielcode zum Registrieren des Empfängers in der Absicht:

// MyReceiver must extend BroadcastReceiver
MyReceiver receiver = new MyReceiver();
IntentFilter filter = new IntentFilter("android.location.GPS_ENABLED_CHANGE");
filter.addAction("android.location.GPS_FIX_CHANGE");
registerReceiver(receiver, filter);

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.

sast
quelle
Ich weiß nicht, wie Sie diese Sendung von Ihrer Anwendung aus senden können, da es sich anscheinend um eine systemgeschützte Sendung handelt, dh nur das System kann sie senden. Jede App, die diese Absicht sendet, sollte abstürzen.
JoxTraex
Es war möglich, es vor sechs Jahren zu senden, als ich die Antwort schrieb. Anscheinend haben sie dem System seitdem einen gewissen Schutz hinzugefügt.
Sast
Ich habe diese Absichten verwendet, um festzustellen, wann andere Apps das GPS verwenden. Ich glaube, beginnend mit Nougat kann man nicht einmal mehr auf diese Absichten hören, das oder sie haben sich geändert! Ich möchte nicht mit meiner eigenen App nach dem Standort suchen. Hat jemand andere Ideen?
Flyview
Ja, ich habe diesen Absturz: 05-14 10: 25: 24.113 17344-17344 / xxx.yyy.zzz.debug E / Android Laufzeit: FATAL AUSNAHME: Hauptprozess: xxx.yyy.zzz.debug, PID: 17344 Java. lang.SecurityException: Berechtigungsverweigerung: Broadcast android.location.GPS_FIX_CHANGE darf nicht von pid = 17344, uid = 10416 gesendet werden
unbegrenzt101
19

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:

isGPSFix = (SystemClock.elapsedRealtime() - mLastLocationMillis) < 3000;

zu:

isGPSFix = (SystemClock.elapsedRealtime() - mLastLocationMillis) < (GPS_UPDATE_INTERVAL * 2);

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 :)

chich
quelle
14

Ok, also versuchen wir eine Kombination aller bisherigen Antworten und Updates und machen so etwas:

Der GPS-Listener könnte ungefähr so ​​aussehen:

GpsStatus.Listener listener = new GpsStatus.Listener() {
    void onGpsStatusChanged(int event) {
        if (event == GPS_EVENT_SATELLITE_STATUS) {
            GpsStatus status = mLocManager.getGpsStatus(null);
            Iterable<GpsSatellite> sats = status.getSatellites();
            // Check number of satellites in list to determine fix state
        }
    }
}

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 GpsSatelliteObjekt enthält.

Christopher Orr
quelle
Das Problem beim Zählen der verfügbaren Satelliten besteht darin, dass selbst wenn Sie 5 Satelliten im Blick haben, dies nicht bedeutet, dass immer eine Korrektur möglich ist. (Sie haben es richtig erwähnt, indem Sie geschrieben haben "Wenn es mehr ist, dann sollten Sie eine Lösung haben")
Nr. 1
Tatsächlich. Obwohl ich nicht mehr weiß, welche Informationen erforderlich sind, um einen Fix zu erstellen, oder wie / ob diese von einem GpsSatelliteObjekt abgerufen werden können.
Christopher Orr
Ein anderer Gedanke ... Sie erwähnen dies nicht in Ihrer Frage, aber haben Sie versucht, nur LocationManager.requestLocationUpdatesmit 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.
Christopher Orr
1
Iterieren von "sats" und Überprüfen von usedInFix () in GpsSatellite vielleicht?
DeliriumTremens
8

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.

Justin Breitfeller
quelle
Möchten Sie die Zeitvergleichsmethode erläutern? In Stephen Dayes Antwort verglich er die Zeitunterschiede zwischen dem Zeitpunkt der letzten Korrektur und dem letzten GPS_EVENT_SATELLITE_STATUS-Ereignis ... Ich bin mir nicht sicher, was gemessen wird.
Rokey Ge
7

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.

private class MyGPSListener implements GpsStatus.Listener {
    public void onGpsStatusChanged(int event) {
        switch (event) {
        case GpsStatus.GPS_EVENT_SATELLITE_STATUS:
            if (Global.getInstance().currentGPSLocation != null)
            {
                if((SystemClock.elapsedRealtime() - mLastLocationMillis) < 20000)
                {
                    if (!hasGPSFix) 
                        Log.i("GPS","Fix Acquired");
                    hasGPSFix = true;
                } 
                else
                {
                    if (hasGPSFix) 
                    {
                        Log.i("GPS","Fix Lost (expired)");
                        lm.requestLocationUpdates(LocationManager.GPS_PROVIDER, 2000, 10, locationListener);
                    }
                    hasGPSFix = false;
                }
            }
            break;
        case GpsStatus.GPS_EVENT_FIRST_FIX:
            Log.i("GPS", "First Fix/ Refix");
            hasGPSFix = true;
            break;
        case GpsStatus.GPS_EVENT_STARTED:
            Log.i("GPS", "Started!");
            break;
        case GpsStatus.GPS_EVENT_STOPPED:
            Log.i("GPS", "Stopped");
            break;
        }
    }
}
Jeffery Lee
quelle
5

Nun, wenn Sie jeden Arbeitsansatz zusammenstellen, wird dies dazu führen (auch im Umgang mit veralteten GpsStatus.Listener):

private GnssStatus.Callback mGnssStatusCallback;
@Deprecated private GpsStatus.Listener mStatusListener;
private LocationManager mLocationManager;

@Override
public void onCreate() {
    mLocationManager = (LocationManager) getSystemService(LOCATION_SERVICE);

    mLocationManager = (LocationManager) this.getSystemService(Context.LOCATION_SERVICE);
    if (checkPermission()) {
       mLocationManager.requestLocationUpdates(LocationManager.GPS_PROVIDER, GPS_UPDATE_INTERVAL, MIN_DISTANCE, this);
    }

    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
        mGnssStatusCallback = new GnssStatus.Callback() {
            @Override
            public void onSatelliteStatusChanged(GnssStatus status) {
                satelliteStatusChanged();
            }

            @Override
            public void onFirstFix(int ttffMillis) {
                gpsFixAcquired();

            }
        };
        mLocationManager.registerGnssStatusCallback(mGnssStatusCallback);
    } else {
        mStatusListener = new GpsStatus.Listener() {
            @Override
            public void onGpsStatusChanged(int event) {
                switch (event) {
                    case GpsStatus.GPS_EVENT_SATELLITE_STATUS:
                        satelliteStatusChanged();
                        break;
                    case GpsStatus.GPS_EVENT_FIRST_FIX:
                        // Do something.
                        gpsFixAcquired();
                        break;
                }
            }
        };
        mLocationManager.addGpsStatusListener(mStatusListener);
    }
}

private void gpsFixAcquired() {
    // Do something.
    isGPSFix = true;
}

private void satelliteStatusChanged() {
    if (mLastLocation != null)
        isGPSFix = (SystemClock.elapsedRealtime() - mLastLocationMillis) < (GPS_UPDATE_INTERVAL * 2);

    if (isGPSFix) { // A fix has been acquired.
        // Do something.
    } else { // The fix has been lost.
        // Do something.
    }
}

@Override
public void onLocationChanged(Location location) {
    if (location == null) return;

    mLastLocationMillis = SystemClock.elapsedRealtime();

    mLastLocation = location;
}

@Override
public void onStatusChanged(String s, int i, Bundle bundle) {

}

@Override
public void onProviderEnabled(String s) {

}

@Override
public void onProviderDisabled(String s) {

}

Hinweis: Diese Antwort ist eine Kombination der obigen Antworten.

Gregory Stein
quelle
1
Solange Sie andere Autoren gutschreiben, ist es kein Problem, eigene Upvotes für neue oder abgeleitete Arbeiten zu erhalten. Die Regeln hier sind eher besorgt darüber, dass Leute die Antworten anderer Leute plagiieren und sie an anderer Stelle auf Stack Overflow verwenden, um unredlich Vertreter anzuziehen. Da Sie erwähnt haben, dass Sie auf anderen Antworten aufgebaut haben, denke ich, dass dies in Ordnung ist.
Halfer
3

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.

   LocationManager lm = (LocationManager)context.getSystemService(LOCATION_SERVICE); 
   Location loc = lm.getLastKnownLocation(LocationManager.GPS_PROVIDER);

   // Get the time of the last fix
   long lastFixTimeMillis = loc.getTime(); 

... 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.

Adan
quelle
+1 scheint einen Versuch wert zu sein, wenn Sie sofort wissen möchten, ob es eine Lösung gibt.
AgentKnopf
2

Ich kann mich irren, aber es scheint, dass die Leute weit vom Thema abweichen

Ich muss nur wissen, ob das GPS-Symbol oben auf dem Bildschirm blinkt (keine tatsächliche Korrektur).

Das ist leicht zu machen

LocationManager lm = (LocationManager) getSystemService(LOCATION_SERVICE);
boolean gps_on = lm.isProviderEnabled(LocationManager.GPS_PROVIDER);

Um zu sehen, ob Sie eine solide Lösung haben, wird es etwas schwieriger:

public class whatever extends Activity {
    LocationManager lm;
    Location loc;
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main);        
        lm = (LocationManager) getSystemService(LOCATION_SERVICE);
        loc = null;
        request_updates();        
    }

    private void request_updates() {
        if (lm.isProviderEnabled(LocationManager.GPS_PROVIDER)) {
            // GPS is enabled on device so lets add a loopback for this locationmanager
            lm.requestLocationUpdates(LocationManager.GPS_PROVIDER,0, 0, locationListener);
        }      
    }

    LocationListener locationListener = new LocationListener() {
        public void onLocationChanged(Location location) {
            // Each time the location is changed we assign loc
            loc = location;
        }

         // Need these even if they do nothing. Can't remember why.
         public void onProviderDisabled(String arg0) {}
         public void onProviderEnabled(String provider) {}
         public void onStatusChanged(String provider, int status, Bundle extras) {}
    };

Wann immer Sie sehen wollen, ob Sie eine Lösung haben?

if (loc != null){
    // Our location has changed at least once
    blah.....
}

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.

Regomodo
quelle
3
Ihre Lösung ist für das, was sie tut, überkomplex. Es macht jedoch sehr wenig. Was ist, wenn ich, nachdem GPS meinen Standort aufgelöst hat, zur U-Bahnstation gehe, wodurch GPS den Fix verliert?
Meandre
1

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).

Mark Borgerding
quelle
1

so viele Beiträge ...

GpsStatus.Listener gpsListener = new GpsStatus.Listener() {
                        public void onGpsStatusChanged(int event) {
                            if( event == GpsStatus.GPS_EVENT_FIRST_FIX){
                                showMessageDialog("GPS fixed");
                            }
                        }
                 };

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)

cV2
quelle
Dies ist nur die erste Lösung. Was ist, wenn Sie einen Tunnel betreten?
Leos Literak
1

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:

private Location lastKnownLocation;
private long lastKnownLocationTimeMillis = 0;
private boolean isGpsFix = false;

Dies ist die Methode, die in "onLocationChanged ()" aufgerufen wird, um die Aktualisierungszeit und den aktuellen Speicherort zu speichern. Außerdem wird "isGpsFix" aktualisiert:

private void handlePositionResults(Location location) {
        if(location == null) return;

        lastKnownLocation = location;
        lastKnownLocationTimeMillis = SystemClock.elapsedRealtime();

        checkGpsFix(); // optional
    }

Diese Methode wird immer dann aufgerufen, wenn ich wissen muss, ob es einen GPS-Fix gibt:

private boolean checkGpsFix(){

    if (SystemClock.elapsedRealtime() - lastKnownLocationTimeMillis < 3000) {
        isGpsFix = true;

    } else {
        isGpsFix = false;
        lastKnownLocation = null;
    }
    return isGpsFix;
}

In meiner Implementierung führe ich zuerst checkGpsFix () aus und wenn das Ergebnis wahr ist, verwende ich die Variable "lastKnownLocation" als meine aktuelle Position.

Sebastian Mauthofer
quelle
1

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.

user2153142
quelle
0

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.

nr1
quelle
0

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):

private void startLocationTracking() {
    final int updateTime = 2000; // ms
    final int updateDistance = 10; // meter
    final Criteria criteria = new Criteria();
    criteria.setCostAllowed(false);
    criteria.setAccuracy(Criteria.ACCURACY_FINE);
    final String p = locationManager.getBestProvider(criteria, true);
    locationManager.requestLocationUpdates(p, updateTime, updateDistance,
            this);
}

Und ich gehe mit onStatusChanged wie folgt um:

void onStatusChanged(final String provider, final int status,
        final Bundle extras) {
    switch (status) {
    case LocationProvider.OUT_OF_SERVICE:
        if (location == null || location.getProvider().equals(provider)) {
            statusString = "No Service";
            location = null;
        }
        break;
    case LocationProvider.TEMPORARILY_UNAVAILABLE:
        if (location == null || location.getProvider().equals(provider)) {
            statusString = "no fix";
        }
        break;
    case LocationProvider.AVAILABLE:
        statusString = "fix";
        break;
    }
}

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.

CvR
quelle
Leider funktioniert es oft nicht. onLocationChanged () wird einmal pro Sekunde aufgerufen, onStatusChanged wird jedoch überhaupt nicht aufgerufen. Manchmal wünschte ich, ich könnte einfach den aktuellen Status abfragen, anstatt auf eine Benachrichtigung zu warten, die möglicherweise nicht lange oder nie kommt.
Edward Falk
2
Richtig. Nach dieser vorherigen Antwort habe ich selbst einige Dinge gelernt, und eine davon ist, dass nicht alle Android-Plattformen gleich sind. Ich sehe definitiv Aufrufe von onStatusChanged sowohl auf meinem HTC Hero als auch auf meinem Archos 5, aber ich bin nicht überrascht, dass das nicht überall funktioniert. Wie wäre es mit Plan B: Sie verwenden den GPSStatusListener, der in einer anderen Antwort angezeigt wird, und prüfen einfach, ob einer der Satelliten für usedInFix () true zurückgibt. Nach meiner Erfahrung kommt dies dem Verhalten des Standard-GPS-Symbols am nächsten. (Haben Sie versucht, die Quelle zu finden, die dieses Standardsymbol implementiert,
übrigens
0

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:

  • Prüfintervall bis zum letzten empfangenen Ort (in gpsStatusChanged)
  • Wenn dieses Intervall länger als 15 Sekunden ist, setzen Sie die Variable: long_interval = true
  • Entfernen Sie den Standort-Listener und fügen Sie ihn erneut hinzu. In der Regel erhalten Sie dann eine aktualisierte Position, wenn der Standort wirklich verfügbar ist. Wenn nicht, haben Sie wahrscheinlich den Standort verloren
  • In onLocationChanged haben Sie long_interval einfach auf false gesetzt.
Winterhart
quelle