How to check the current status of the GPS receiver?

How to check the current status of the GPS receiver? I already checked the LocationListener onStatusChanged method, but for some reason it seems like it is not working or just the wrong opportunity.

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

+85
android gps
Jan 07
source share
17 answers

As a developer of SpeedView: GPS speedometer for Android, I had to try all possible solutions to this problem, all with the same negative result. Repeat what does not work:

  • onStatusChanged () does not receive a call in Eclair and Froyo.
  • Just counting all available satellites is of course useless.
  • Checking that any of the satellites returns true for usedInFix () also does not help much. The system clearly loses the fix, but continues to report that it still uses several sats.

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

 @Override public void onLocationChanged(Location location) { if (location == null) return; mLastLocationMillis = SystemClock.elapsedRealtime(); // Do something. mLastLocation = location; } 

What is it. Basically, this is the line that does all this:

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

Of course, you can adjust the millis value, but I would suggest setting it for about 3-5 seconds.

This really works, and although I have not looked at the source code that draws my own GPS icon, it comes close to replicating its behavior. Hope this helps someone.

+142
Sep 14 '10 at 20:40
source share

The GPS icon appears to change state according to broadcast intentions. You can change your state yourself using the following code samples:

Report GPS enabled:

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

Report GPS getting corrections:

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

Report that GPS no longer receives corrections:

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

Report that GPS is disabled:

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

Example code for registering the receiver: [/ p>

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

After receiving these broadcasts, you may notice a change in GPS status. However, you will only be notified if the status changes. Therefore, it is not possible to determine the current state using these intentions.

+25
Nov 03 '10 at 6:56
source share

new member, unfortunately, I could not comment or vote, however, the above post by Stephen Day was the perfect solution for the same problem I was looking for help with.

slight change to the next line:

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

at

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

basically, since I am creating a slow game, and my update interval is already set to 5 seconds, as soon as the gps signal goes off for 10+ seconds, this is the right time to release something.

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

+17
08 Oct 2018-10-10
source share

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

A GPS receiver might look 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 provided, but I think the idea is to see how many satellites are available. If it is below three, then you cannot fix it. If this is more, then you should have a fix.

Probably a trial version and an error to determine how often Android reports satellite information, and what information each GpsSatellite object GpsSatellite .

+14
Jan 07 '10 at 19:03
source share

After several years of working with GPS on Windows mobile devices, I realized that the concept of “losing” a GPS solution can be subjective. To just listen to what the GPS says, adding the NMEAListener and parsing the sentence will tell you if the fix was “valid” or not. See http://www.gpsinformation.org/dale/nmea.htm#GGA . Unfortunately, with some GPS devices this value will fluctuate back and forth even during the normal course of work in the “good fix” area.

Thus, another solution is to compare the UTC time of the GPS location with the phone time (converted to UTC). If they differ from the time difference, you can assume that you have lost the GPS position.

+8
Aug 6 '10 at 18:40
source share

encountering a similar problem while working on my MSc project, it seems that Daye's answer mistakenly said “no fix” while the device remains in a static location. I changed the solution a bit, which seems to work fine for me in a static place. I do not know how this will affect the battery, since this is not my main problem, but here is how I did it by repeatedly requesting location updates when the time is right.

 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; } } } 
+7
Jul 21 '11 at 20:12
source share

If you just need to know if there is a fix, then check the last known location provided by the GPS receiver and check the .getTime () value to see how many years have passed. If this is recent enough (e.g. 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 this with the current date time (in UTC!). If it's recent enough, you have a fix.

I do this in my application and so far so good.

+3
May 28 '12 at 14:06
source share

You can try to use LocationManager.addGpsStatusListener to update when GPS status changes. It looks like GPS_EVENT_STARTED and GPS_EVENT_STOPPED might be what you are looking for.

+2
Jan 07
source share

I may be mistaken, but it seems that people seem to go off topic for

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

This is easy to do with

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

To find out if you have a reliable 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 that you want to know if you are fixed?

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

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

Works reliably, at least on N1 since 2.1.

+2
May 11 '11 at 18:42
source share

Using LocationManager you can getLastKnownLocation () after getBestProvider (). This gives you a Location object that has getAccuracy () methods in meters and getTime () in UTC milliseconds

Does this give you enough information?

Or maybe you could iterate over LocationProviders and find out if each criterion matches Criteria (ACCURACY_COARSE)

+1
Mar 11 '10 at 21:09
source share

so many messages ...

 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 with a line

did a great job for me :) Thanks a lot: =) (sry for this post, not yet able to vote)

+1
Jun 28 '10 at 0:13
source share

If you do not need an update at the moment the fix is ​​lost, you can change Stephen Daye's solution so that you have a method that checks if the fix is ​​present.

This way you can just check it when you need GPS data and you don't need this GpsStatus.Listener.

"Global" variables:

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

This is the method that is called inside "onLocationChanged ()" to remember the update time and current location. In addition, it updates "isGpsFix":

 private void handlePositionResults(Location location) { if(location == null) return; lastKnownLocation = location; lastKnownLocationTimeMillis = SystemClock.elapsedRealtime(); checkGpsFix(); // optional } 

This 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 correct, I use the variable "lastKnownLocation" as my current position.

+1
Oct 28 '10 at 21:34
source share

I know this is a little late. However, why not use NMEAListener if you want to find out if you have a fix. From what I read, NMEAListener will provide you with NMEA suggestions, and from there you will choose the right suggestion.

The RMC clause contains commit status, which is A for OK or V for warning. GGA offer contains quality fixes (0 invalid, 1 GPS or 2 DGPS)

I cannot offer you any java code since I am just starting to work with Android, but I have made a GPS library in C # for Windows applications, which I am going to use with Xamarin. I just came across this topic because I was looking for information about the provider.

From what I have read so far about the Location object, I don’t like everything so much with methods like getAccuracy () and hasAccuracy (). I'm used to extracting HDOP and VDOP sentences from NMEA sentences to determine how accurate my corrections are. Its quite common to have a fix, but have a lousy HDOP, which means that your horizontal accuracy is not very good. For example, sitting on your desk, debugging an external Bluetooth GPS device that is very opposed to the window, you will most likely receive a fix, but very poor HDOP and VDOP. Place the GPS device in a flower pot outside or something similar, or add an external antenna to the GPS and immediately get good HDOP and VDOP values.

+1
Mar 10 '13 at 6:48
source share

Well, as a result, every working approach will lead to this (also applies to obsolete 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.

+1
04 Sep '17 at 16:37 on
source share

Perhaps this is the best opportunity to create a TimerTask that regularly sets the accepted location to a specific value (null?). If a new value is received by GPSListener, it will update the location with current data.

I think that would be a working solution.

0
Jan 13 '10 at 19:50
source share

You say you already tried onStatusChanged (), but this works for me.

Here is the method I use (I myself process the class 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 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 relate to enabling or disabling GPS tracking by the user; not what you are looking for.

0
May 12 '10 at 18:49
source share

Setting a time interval for checking a patch is not a good choice. I noticed that onLocationChanged is not called if you are not moving .. which is understandable since the location does not change :)

Best would be:

  • check interval to last found location (in gpsStatusChanged)
  • if this interval is more than 15 with the given variable: long_interval = true
  • remove the location listener and add it again, usually after that you get an updated position if the location is really accessible, if not - you probably lost the location.
  • In onLocationChanged, you just set long_interval to false.
0
Jul 23 '13 at 19:04 on
source share



All Articles