Jak mogę sprawdzić aktualny stan odbiornika GPS?

90

Jak mogę sprawdzić aktualny stan odbiornika GPS? Sprawdziłem już LocationListener onStatusChangedmetodę, ale jakoś wygląda na to, że nie działa lub po prostu zła możliwość.

Zasadniczo muszę tylko wiedzieć, czy ikona GPS u góry ekranu miga (brak rzeczywistej poprawki) lub świeci (poprawka jest dostępna).

nr1
źródło

Odpowiedzi:

150

Jako twórca SpeedView: prędkościomierza GPS dla Androida, musiałem wypróbować każde możliwe rozwiązanie tego problemu, wszystkie z tym samym negatywnym wynikiem. Powtórzmy, co nie działa:

  1. onStatusChanged () nie jest wywoływany przez Eclair i Froyo.
  2. Zwykłe liczenie wszystkich dostępnych satelitów jest oczywiście bezużyteczne.
  3. Sprawdzenie, czy którykolwiek z satelitów zwraca true dla usedInFix () również nie jest zbyt pomocne. System wyraźnie gubi poprawkę, ale wciąż raportuje, że wciąż jest w nim używanych kilka satów.

Oto jedyne działające rozwiązanie, które znalazłem i to, którego faktycznie używam w mojej aplikacji. Powiedzmy, że mamy tę prostą klasę, która implementuje GpsStatus.Listener:

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, teraz w onLocationChanged () dodajemy:

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

    mLastLocationMillis = SystemClock.elapsedRealtime();

    // Do something.

    mLastLocation = location;
}

I to wszystko. Zasadniczo jest to linia, która robi wszystko:

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

Oczywiście możesz dostosować wartość milisekund, ale radzę ustawić ją na około 3-5 sekund.

To faktycznie działa i chociaż nie spojrzałem na kod źródłowy, który rysuje natywną ikonę GPS, zbliża się to do odtworzenia jej zachowania. Mam nadzieję, że to komuś pomoże.

soundmaven
źródło
Cześć, zastanawiam się, dlaczego liczenie dostępnych satelitów jest bezużyteczne, jak w tym przykładzie? Jeśli liczba znalezionych satelitów wynosi 0, oznacza brak połączenia, czy się mylę? groups.google.com/group/android-developers/browse_thread/thread/ ...
per_jansson
3
Cześć Stephen, czy możesz wyjaśnić, dlaczego działa isGPSFix. Dzięki, Nick
nickfox
Swoją drogą zauważyłem, że w ICS zwiększyli czas do momentu, gdy system zacznie raportować, że utrata pozycji GPS została utracona. Przynajmniej w 4.0.3 to dokładnie 10 sekund.
soundmaven
Działa świetnie, a użycie 10 sekund zamiast 3-5 dla ICS również działa całkiem dobrze. Na szczęście naprawianie nie jest konieczną funkcją mojej aplikacji, ale dobrze jest móc to poznać. Dzięki.
Tom
1
Ale czy to nie psuje się, gdy mLastLocationMilliszostało ustawione przez inne źródło niż GPS? System mógłby wtedy twierdzić, że isGPSFixto prawda, ale w rzeczywistości jest to jakakolwiek poprawka (może jedna z sieci telefonicznej)
avalancha
25

Ikona GPS wydaje się zmieniać swój stan zgodnie z odebranymi intencjami transmisji. Możesz samodzielnie zmienić jego stan za pomocą następujących przykładów kodu:

Powiadom, że GPS został włączony:

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

Powiadom, że GPS odbiera poprawki:

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

Powiadom, że GPS nie otrzymuje już poprawek:

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

Powiadom, że GPS został wyłączony:

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

Przykładowy kod do rejestracji odbiorcy do intencji:

// 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);

Odbierając te intencje transmisji, możesz zauważyć zmiany w stanie GPS. Jednak zostaniesz powiadomiony tylko wtedy, gdy stan się zmieni. W związku z tym nie jest możliwe określenie aktualnego stanu na podstawie tych założeń.

sast
źródło
Nie wiem, w jaki sposób możesz wysłać tę transmisję z aplikacji, ponieważ wygląda na to, że jest to transmisja chroniona przez system, co oznacza, że ​​tylko system może ją wysłać. Każda aplikacja wysyłająca taki zamiar powinna ulec awarii.
JoxTraex
Można było to wysłać sześć lat temu, kiedy pisałem odpowiedź. Najwyraźniej od tego czasu dodali trochę ochrony do systemu.
obchodzony
Używałem tych zamiarów, aby powiedzieć, kiedy inne aplikacje używają GPS. Myślę, że zaczynając od Nougata, nie możesz już nawet słuchać tych zamiarów, że albo się zmieniły! Nie chcę nasłuchiwać lokalizacji za pomocą własnej aplikacji. Czy ktoś ma jakieś inne pomysły?
Flyview
Tak, mam tę awarię: 05-14 10: 25: 24.113 17344-17344 / xxx.yyy.zzz.debug E / AndroidRuntime: KRYTYCZNY WYJĄTEK: główny proces: xxx.yyy.zzz.debug, PID: 17344 java. lang.SecurityException: Permission Denial: nie można wysyłać transmisji android.location.GPS_FIX_CHANGE z pid = 17344, uid = 10416
bez ograniczeń
19

nowy członek, więc niestety nie mogę komentować ani głosować, jednak powyższy post Stephena Daye był idealnym rozwiązaniem tego samego problemu, z którym szukałem pomocy.

mała zmiana w następującym wierszu:

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

do:

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

Zasadniczo, ponieważ buduję wolną grę, a mój interwał aktualizacji jest już ustawiony na 5 sekund, gdy sygnał GPS wyłączy się przez ponad 10 sekund, jest to właściwy czas, aby coś uruchomić.

Pozdrawiam kolego, spędziłem około 10 godzin próbując rozwiązać to rozwiązanie, zanim znalazłem twój post :)

chich
źródło
14

Ok, więc wypróbujmy kombinację wszystkich dotychczasowych odpowiedzi i aktualizacji i zróbmy coś takiego:

Odbiornikiem GPS może być coś takiego:

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

Interfejsy API są nieco niejasne, kiedy i jakie informacje GPS i satelity są podawane, ale myślę, że pomysł polegałby na sprawdzeniu, ile satelitów jest dostępnych. Jeśli jest poniżej trzech, nie możesz znaleźć rozwiązania. Jeśli jest więcej, powinieneś mieć poprawkę.

Próba i błąd to prawdopodobnie sposób na określenie, jak często Android zgłasza informacje o satelitach i jakie informacje GpsSatellitezawiera każdy obiekt.

Christopher Orr
źródło
Problem z liczeniem dostępnych satelitów polega na tym, że nawet jeśli masz na widoku 5 satelitów, nie oznacza to, że zawsze jest możliwa naprawa. (Wspomniałeś o tym poprawnie, pisząc "Jeśli jest więcej, to powinieneś mieć poprawkę")
nr1
W rzeczy samej. Chociaż nie wiem już więcej o tym, jakie informacje są wymagane, aby utworzyć poprawkę, ani jak / czy można je pobrać z GpsSatelliteobiektu.
Christopher Orr,
Inna myśl ... nie wspominasz o tym w swoim pytaniu, ale czy próbowałeś używać tego LocationManager.requestLocationUpdatesz ustawieniami czasu i odległości ustawionymi na 0? Powinno to wysyłać poprawki GPS, gdy tylko się pojawią. Jeśli nic nie otrzymujesz, najprawdopodobniej nie masz rozwiązania. Jeśli chcesz, możesz to połączyć z odbiornikiem stanu powyżej.
Christopher Orr,
1
Iterowanie "sats" i sprawdzanie usedInFix () w GpsSatellite może?
DeliriumTremens
8

Po kilku latach pracy z GPS na urządzeniach mobilnych z systemem Windows zdałem sobie sprawę, że koncepcja „utraty” pozycji GPS może być subiektywna. Aby po prostu posłuchać tego, co mówi GPS, dodanie NMEAListenera i przeanalizowanie zdania powie, czy poprawka była „poprawna”, czy nie. Zobacz http://www.gpsinformation.org/dale/nmea.htm#GGA . Niestety w przypadku niektórych odbiorników GPS wartość ta będzie się wahać w przód iw tył, nawet podczas normalnej pracy w obszarze „dobrego ustalenia”.

Tak więc innym rozwiązaniem jest porównanie czasu UTC lokalizacji GPS z czasem telefonu (przeliczonym na UTC). Jeśli różnią się od siebie pewną różnicą czasu, możesz założyć, że utraciłeś pozycję GPS.

Justin Breitfeller
źródło
Czy zechciałbyś wyjaśnić metodę porównywania czasu? W odpowiedzi Stephena Daye'a porównał różnice czasu między datą ostatniej poprawki a ostatnim zdarzeniem GPS_EVENT_SATELLITE_STATUS ... Nie jestem pewien, co mierzy.
Rokey Ge
7

napotkałem podobny problem podczas pracy nad moim projektem magisterskim, wydaje się, że odpowiedź Daye omyłkowo zgłosiła „brak poprawki”, podczas gdy urządzenie pozostaje w statycznej lokalizacji. Trochę zmodyfikowałem rozwiązanie, które wydaje mi się dobrze działać w statycznej lokalizacji. Nie wiem, jak to wpłynie na baterię, ponieważ nie jest to moim głównym zmartwieniem, ale oto jak to zrobiłem, ponownie prosząc o aktualizacje lokalizacji, gdy upłynął limit czasu naprawy.

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
źródło
5

Cóż, połączenie wszystkich metod pracy spowoduje to (również radzenie sobie z przestarzałymi 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) {

}

Uwaga: ta odpowiedź jest połączeniem powyższych odpowiedzi.

Gregory Stein
źródło
1
O ile podajesz uznanie innych autorów, nie ma problemu z uzyskaniem własnych głosów za nowych lub pochodnych prac. Zasady tutaj są bardziej zaniepokojone tym, że ludzie plagiatują odpowiedzi innych ludzi i używają ich w innym miejscu w Stack Overflow w celu nieuczciwego przyciągnięcia reputacji. Ponieważ wspomniałeś, że zbudowałeś inne odpowiedzi, myślę, że to jest w porządku.
halfer
3

Jeśli chcesz tylko wiedzieć, czy istnieje poprawka, sprawdź ostatnią znaną lokalizację dostarczoną przez odbiornik GPS i sprawdź wartość .getTime (), aby wiedzieć, ile ma lat. Jeśli jest wystarczająco niedawna (np. Kilka sekund), masz rozwiązanie.

   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(); 

... i na koniec porównaj to z aktualną datą i czasem (w UTC!). Jeśli jest wystarczająco nowy, masz poprawkę.

Robię to w mojej aplikacji i jak na razie dobrze.

Adan
źródło
+1 wydaje się warte wypróbowania, jeśli od razu chcesz wiedzieć, czy istnieje rozwiązanie.
AgentKnopf,
2

Może się mylę, ale wydaje się, że ludzie odchodzą od tematu

Muszę tylko wiedzieć, czy ikona GPS na górze ekranu miga (brak rzeczywistej poprawki)

Można to łatwo zrobić

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

Aby sprawdzić, czy masz solidną poprawkę, sprawy stają się nieco trudniejsze:

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) {}
    };

Teraz, kiedy chcesz sprawdzić, czy masz poprawkę?

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

Jeśli chcesz być fantazyjny, zawsze możesz ustawić limit czasu za pomocą System.currentTimeMillis () i loc.getTime ()

Działa niezawodnie, przynajmniej na N1 od 2.1.

regomodo
źródło
3
Twoje rozwiązanie jest zbyt skomplikowane ze względu na to, co robi. Jednak robi bardzo niewiele. Co jeśli po tym, jak GPS ustali moją lokalizację, udam się na stację metra, przez co GPS utraci połączenie?
meandre
1

Dzięki LocationManager możesz uzyskaćLastKnownLocation () po wykonaniu metody getBestProvider (). Daje to obiekt Location, który ma metody getAccuracy () w metrach i getTime () w milisekundach UTC

Czy to daje wystarczająco dużo informacji?

A może możesz iterować przez LocationProviders i dowiedzieć się, czy każdy z nich spełnia kryteria (ACCURACY_COARSE)

Mark Borgerding
źródło
1

tak wiele postów ...

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

dodanie tego kodu za pomocą addGpsListener ... showMessageDialog ... po prostu pokazuje standardowe okno dialogowe z ciągiem znaków

wykonał robotę idealnie dla mnie :) wielkie dzięki: =) (prosze za ten post, jeszcze nie moge glosowac)

cV2
źródło
To tylko pierwsza poprawka. A jeśli wejdziesz do tunelu?
Leos Literak
1

Jeśli nie potrzebujesz aktualizacji natychmiast po utracie poprawki, możesz zmodyfikować rozwiązanie Stephena Daye w ten sposób, aby mieć metodę, która sprawdza, czy poprawka jest nadal obecna.

Możesz więc po prostu to sprawdzić, gdy potrzebujesz danych GPS i nie potrzebujesz tego GpsStatus.Listener.

Zmienne „globalne” to:

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

Jest to metoda wywoływana w ramach metody „onLocationChanged ()” w celu zapamiętania czasu aktualizacji i bieżącej lokalizacji. Oprócz tego aktualizuje „isGpsFix”:

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

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

        checkGpsFix(); // optional
    }

Ta metoda jest wywoływana za każdym razem, gdy chcę wiedzieć, czy istnieje poprawka GPS:

private boolean checkGpsFix(){

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

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

W mojej implementacji najpierw uruchamiam checkGpsFix () i jeśli wynik jest prawdziwy, używam zmiennej „lastKnownLocation” jako mojej aktualnej pozycji.

Sebastian Mauthofer
źródło
1

Wiem, że to trochę późno. Jednak dlaczego nie skorzystać z NMEAListener, jeśli chcesz wiedzieć, czy masz poprawkę. Z tego, co przeczytałem, NMEAListener poda Ci zdania NMEA i stamtąd wybierzesz prawidłowe zdanie.

Zdanie RMC zawiera status poprawki, który jest A dla OK lub V dla ostrzeżenia. Zdanie GGA zawiera poprawkę jakości (0 nieważne, 1 GPS lub 2 DGPS)

Nie mogę zaoferować Ci żadnego kodu java, ponieważ dopiero zaczynam od Androida, ale zrobiłem bibliotekę GPS w C # dla aplikacji Windows, której chcę używać z Xamarin. Trafiłem na ten wątek tylko dlatego, że szukałem informacji o dostawcy.

Z tego, co do tej pory przeczytałem o obiekcie Location, nie czuję się dobrze w metodach takich jak getAccuracy () i hasAccuracy (). Jestem przyzwyczajony do wyodrębniania ze zdań NMEA wartości HDOP i VDOP, aby określić, jak dokładne są moje poprawki. Dość często ma się poprawkę, ale ma kiepski HDOP, co oznacza, że ​​twoja dokładność pozioma nie jest wcale dobra. Na przykład siedząc przy biurku podczas debugowania za pomocą zewnętrznego urządzenia Bluetooth GPS mocno przy oknie, prawdopodobnie otrzymasz poprawkę, ale bardzo słabe HDOP i VDOP. Umieść urządzenie GPS w doniczce na zewnątrz lub w czymś podobnym lub dodaj zewnętrzną antenę do GPS, a natychmiast uzyskasz dobre wartości HDOP i VDOP.

user2153142
źródło
0

Być może jest to najlepsza możliwość, aby utworzyć TimerTask, które regularnie ustawia otrzymaną lokalizację na określoną wartość (null?). Jeśli GPSListener otrzyma nową wartość, zaktualizuje lokalizację aktualnymi danymi.

Myślę, że byłoby to działające rozwiązanie.

nr1
źródło
0

Mówisz, że próbowałeś już StatusChanged (), ale to działa dla mnie.

Oto metoda, której używam (pozwoliłem samej klasie obsługiwać onStatusChanged):

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);
}

I obsługuję onStatusChanged w następujący sposób:

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;
    }
}

Zwróć uwagę, że metody onProvider {Dis, En} abled () dotyczą włączania i wyłączania śledzenia GPS przez użytkownika; nie to, czego szukasz.

CvR
źródło
Niestety często nie działa. onLocationChanged () jest wywoływana raz na sekundę, ale onStatusChanged w ogóle nie jest wywoływana. Czasami chciałbym po prostu zapytać o aktualny status, zamiast czekać na powiadomienie, które może nie nadejść przez długi czas lub nigdy.
Edward Falk
2
Dobrze. Sam nauczyłem się kilku rzeczy po tej poprzedniej odpowiedzi, a jedną z nich jest to, że nie wszystkie platformy Androida są podobne. Zdecydowanie widzę wezwania do onStatusChanged zarówno na moim HTC Hero, jak i na moim Archos 5, ale nie jestem zaskoczony, że nie działa wszędzie. A co z planem B: używasz GPSStatusListener, który jest pokazany w innej odpowiedzi i po prostu sprawdzasz, czy któryś z satelitów zwraca true dla usedInFix (). Z mojego doświadczenia wynika, że ​​jest to najbliższe zachowaniu standardowej ikony GPS. (Czy próbowałeś znaleźć źródło, które implementuje tę standardową ikonę, BTW?)
CvR,
0

Ustawienie odstępu czasu w celu sprawdzenia poprawności nie jest dobrym wyborem. Zauważyłem, że onLocationChanged nie jest wywoływany, jeśli się nie ruszasz .. co jest zrozumiałe, ponieważ lokalizacja się nie zmienia :)

Lepszym sposobem byłoby na przykład:

  • interwał sprawdzania ostatniej otrzymanej lokalizacji (w gpsStatusChanged)
  • jeśli ten interwał jest dłuższy niż 15 sekund, ustaw zmienną: long_interval = true
  • usuń odbiornik lokalizacji i dodaj go ponownie, zwykle wtedy otrzymasz zaktualizowaną pozycję, jeśli lokalizacja jest naprawdę dostępna, jeśli nie - prawdopodobnie straciłeś lokalizację
  • w onLocationChanged po prostu ustawisz long_interval na false ..
Wytrzymały
źródło