How can I check the current status of the GPS receiver?

How can I check the current status of the GPS receiver? I already checked the LocationListener onStatusChanged method but somehow it seems that is not working, or just the wrong possibility.

Basically I just need to know if the GPS icon at the top of the screen is blinking (no actual fix) or solid (fix is available).


Asked by: Rubie314 | Posted: 25-01-2022






Answer 1

As a developer of SpeedView: GPS speedometer for Android, I must have tried every possible solution to this problem, all with the same negative result. Let's reiterate what doesn't work:

  1. onStatusChanged() isn't getting called on Eclair and Froyo.
  2. Simply counting all available satellites is, of course, useless.
  3. Checking if any of the satellites return true for usedInFix() isn't very helpful also. The system clearly loses the fix but keeps reporting that there are still several sats that are used in it.

So here's the only working solution I found, and the one that I actually use in my app. Let's say we have this simple class that implements the 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, now in onLocationChanged() we add the following:

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

    mLastLocationMillis = SystemClock.elapsedRealtime();

    // Do something.

    mLastLocation = location;
}

And that's it. Basically, this is the line that does it all:

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

You can tweak the millis value of course, but I'd suggest to set it around 3-5 seconds.

This actually works and although I haven't looked at the source code that draws the native GPS icon, this comes close to replicating its behaviour. Hope this helps someone.

Answered by: Kellan244 | Posted: 26-02-2022



Answer 2

The GPS icon seems to change its state according to received broadcast intents. You can change its state yourself with the following code samples:

Notify that the GPS has been enabled:

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

Notify that the GPS is receiving fixes:

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

Notify that the GPS is no longer receiving fixes:

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

Notify that the GPS has been disabled:

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

Example code to register receiver to the intents:

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

By receiving these broadcast intents you can notice the changes in GPS status. However, you will be notified only when the state changes. Thus it is not possible to determine the current state using these intents.

Answered by: Wilson421 | Posted: 26-02-2022



Answer 3

new member so unfortunately im unable to comment or vote up, however Stephen Daye's post above was the perfect solution to the exact same problem that i've been looking for help with.

a small alteration to the following line:

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

to:

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

basically as im building a slow paced game and my update interval is already set to 5 seconds, once the gps signal is out for 10+ seconds, thats the right time to trigger off something.

cheers mate, spent about 10 hours trying to solve this solution before i found your post :)

Answered by: Edgar335 | Posted: 26-02-2022



Answer 4

Ok, so let's try a combination of all the answers and updates so far and do something like this:

The GPS listener could be something like this:

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

The APIs are a bit unclear about when and what GPS and satellite information is given, but I think an idea would be to look at how many satellites are available. If it's below three, then you can't have a fix. If it's more, then you should have a fix.

Trial and error is probably the way to go to determine how often Android reports satellite info, and what info each GpsSatellite object contains.

Answered by: Alfred596 | Posted: 26-02-2022



Answer 5

After a few years of working with GPS on windows mobile, I realized that the concept of "losing" a GPS fix can be subjective. To simply listen to what the GPS tells you, adding a NMEAListener and parsing the sentence will tell you whether the fix was "valid" or not. See http://www.gpsinformation.org/dale/nmea.htm#GGA . Unfortunately with some GPSes this value will fluctuate back and forth even during the normal course of operation in a "good fix" area.

So, the other solution is to compare the UTC time of the GPS location against the phone's time (converted to UTC). If they are a certain time difference apart, you can assume you lost the GPS position.

Answered by: Adelaide662 | Posted: 26-02-2022



Answer 6

get into similar problem while working on my MSc project, it seems that Daye's answer mistakenly reported "no fix" while the device stays in a static location. I've modified the solution just a little bit which seems to work fine for me in a static location. I don't how would it affect the battery as it is not my main concern, but here's how i did it by re-requesting location updates when a fix has timed out.

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

Answered by: Arthur705 | Posted: 26-02-2022



Answer 7

Well, putting together every working approach will result in this (also dealing with deprecated 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) {

}

Note: this answer is a combination of the answers above.

Answered by: Sawyer964 | Posted: 26-02-2022



Answer 8

If you just need to know if there's a fix, then check for the last known location provided by the GPS receiver and check the .getTime() value to know how old is that. If it's recent enough (like... a few seconds) you have a fix.

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

... and finally compare that to current date time (In UTC!). If it's recent enough you have a fix.

I do that in my app and so far so good.

Answered by: Elise911 | Posted: 26-02-2022



Answer 9

You could try using LocationManager.addGpsStatusListener to get updated when the GPS status changes. It looks like GPS_EVENT_STARTED and GPS_EVENT_STOPPED might be what you're looking for.

Answered by: Catherine682 | Posted: 26-02-2022



Answer 10

I may be wrong but it seems people seem to be going way off-topic for

i just need to know if the gps icon at the top of the screen is blinking (no actual fix)

That is easily done with

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

To see if you have a solid fix, things get a little trickier:

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

Now whenever you want to see if you have fix?

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

If you want to be fancy you can always have a timeout using System.currentTimeMillis() and loc.getTime()

Works reliably, at least on an N1 since 2.1.

Answered by: Kelsey449 | Posted: 26-02-2022



Answer 11

With LocationManager you can getLastKnownLocation() after you getBestProvider(). This gives you a Location object, which has the methods getAccuracy() in meters and getTime() in UTC milliseconds

Does this give you enough info?

Or perhaps you could iterate over the LocationProviders and find out if each one meetsCriteria( ACCURACY_COARSE )

Answered by: Charlie487 | Posted: 26-02-2022



Answer 12

so many posts...

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

adding this code, with addGpsListener... showMessageDialog ... just shows a standard dialog window with the string

did the job perfectly for me :) thanks a lot :=) (sry for this post, not yet able to vote)

Answered by: Brooke939 | Posted: 26-02-2022



Answer 13

If you do not need an update on the very instant the fix is lost, you can modify the solution of Stephen Daye in that way, that you have a method that checks if the fix is still present.

So you can just check it whenever you need some GPS data and and you don't need that GpsStatus.Listener.

The "global" variables are:

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

This is the method that is called within "onLocationChanged()" to remember the update time and the current location. Beside that it updates "isGpsFix":

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

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

        checkGpsFix(); // optional
    }

That method is called whenever I need to know if there is a GPS fix:

private boolean checkGpsFix(){

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

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

In my implementation I first run checkGpsFix() and if the result is true I use the variable "lastKnownLocation" as my current position.

Answered by: Lenny421 | Posted: 26-02-2022



Answer 14

I know this is a little late. However why not use the NMEAListener if you want to know if you have a fix. From what I've read, the NMEAListener will give you the NMEA sentences and from there you pick the correct sentence.

The RMC sentence contains the fix status which is either A for OK or V for warning. The GGA sentence contains the Fix Quality (0 invalid, 1 GPS or 2 DGPS)

I can't offer you any java code as I'm only just starting out with Android, but I have done a GPS library in C# for Windows apps, which I'm looking to use with Xamarin. I only came across this thread because I was looking for provider information.

From what I've read so far about the Location object I'm not all that comfortable about methods like getAccuracy() and hasAccuracy(). I'm used to extracting from the NMEA sentences HDOP and VDOP values to determine how accurate my fixes are. Its quite common to have a fix, but have a lousy HDOP which means your horizontal accuracy is not very good at all. For example sitting at your desk debugging with an external Bluetooth GPS device hard up against a window, you are quite likely to get a fix, but very poor HDOP and VDOP. Place your GPS device in a flower pot outside or something similar or add an external aerial to the GPS and immediately you get good HDOP and VDOP values.

Answered by: John451 | Posted: 26-02-2022



Answer 15

Maybe it's the best possiblity to create a TimerTask that sets the received Location to a certain value (null?) regularly. If a new value is received by the GPSListener it will update the location with the current data.

I think that would be a working solution.

Answered by: Samantha156 | Posted: 26-02-2022



Answer 16

You say that you already tried onStatusChanged(), but that does work for me.

Here's the method I use (I let the class itself handle the 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);
}

And I handle the onStatusChanged as follows:

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

Note that the onProvider{Dis,En}abled() methods are about enabling and disabling GPS tracking by the user; not what you're looking for.

Answered by: Joyce977 | Posted: 26-02-2022



Answer 17

Setting time interval to check for fix is not a good choice.. i noticed that onLocationChanged is not called if you are not moving.. what is understandable since location is not changing :)

Better way would be for example:

  • check interval to last location received (in gpsStatusChanged)
  • if that interval is more than 15s set variable: long_interval = true
  • remove the location listener and add it again, usually then you get updated position if location really is available, if not - you probably lost location
  • in onLocationChanged you just set long_interval to false..

Answered by: Elise534 | Posted: 26-02-2022



Similar questions

android - Any receiver for sent SMS messages?

Hi we get an event when new sms come in android but can we get any event when user send a messages, in short is there any receiver to track sending sms as we track incoming sms.


how to use intent from receiver android

I've got a working SMS receiver but when I try to load another class using: Intent intent = new Intent(SMSReceiver.this, SMSNotifier.class); startActivityForResult(intent, 0); I get this error: The constructor Intent(SMSReceiver, Class) is undefined for the first line and: The method startActivityForResult(Intent, int) i...


How i can use broad cast receiver in android

How i can use broad cast receiver in android, Please give me example or a reference to follow. Thanks


Android + SMS Receiver + Toast = FAIL

I am trying to get this code to work on my Dell Streak but when I receive an SMS I still dont get a Toast notification... I have added the 'receive' tag in the manifest.xml file... I am a complete noob at this and need a little help getting started :) package net.learn2develop.SMSMessaging; import android.content.BroadcastReceiver; import android.content.Context; import android.content.Intent; import andro...


Android: How to link sms draft with information about the receiver (like the name)?

if I write a new text message in the Android standard sms app and fill in a receiver and some body text and press the back button Android will save this as a draft. If the receiver is currently in my address book Android tells me also in the draft overview the name or, if the receiver is not in the address book, the number. So far, so good. Now I tried to do exactly the same thing on my own and I'm not quite sure w...


android 2.2 sms receiver wont work

guys. I am new to android and i am using android 2.2 for some sms_receive thing: when an sms received, just a notification. but it won't work... Nothing happens when sms received, seems like the receiver has not been registered. help! Code for androidmanifest.xml: &lt;?xml version="1.0" encoding="utf-8"?&gt; &lt;manifest xmlns:android="http://schemas.android.com/apk/res/android" pac...


filter - what is the action to hear in receiver for alarm clock android

&lt;receiver android:name=".receiver.AReceiver"&gt; &lt;intent-filter&gt; &lt;action android:name="com.android.alarmclock.ALARM_ALERT" /&gt; &lt;action android:name="alarm_killed" /&gt; &lt;action android:name="cancel_snooze" /&gt; &lt;/intent-filter&gt; &lt;/receiver&gt; This is my code in manifest and this is what I use to hear in my receiver on OnReceive(). I want to do something in the ...


Android SMS Receiver not working

I am new to android programming please help me in resolving a problem. My code to receive sms is not working. the manifest file is &lt;receiver android:name=".SMSReceiver"&gt; &lt;intent-filter&gt; &lt;action android:name= "android.provider.Telephony.SMS_RECEIVED" /&gt; &lt;/intent-filter&gt; &lt;/receiver&gt; &lt;/appli...


Android SMS Receiver Crash

I am trying to capture incoming sms messages for my application. In order to do that I am using a BroadcastReceiver. I have setup permissions and a filter in the manifest file. Whenever I receive a text the application crashes, when I try to debug the program it doesn't even get to the first line of code in the receiver. Does anyone know what I am doing wrong? Here is the code for the receiver: im...


java - How to use the GPS receiver without using the internet?

I am planning to use a GPS enabled Android phone to create an application that will not use the internet to access the user's current position. What I need to know is how to code it in Eclipse. Can you share a piece of code in Java that will return the longitude and latitude of the GPS user without accessing the internet? Also, is it possible to make it so that it will not access the cell network- getting ...






Still can't find your answer? Check out these communities...



Android Google Support | Android Community | Android Community (Facebook) | Dev.io Android



top