📜 ⬆️ ⬇️

Determining GPS availability in Android

Greetings, habrasoobschestvo!

This article, I hope, will be a good help to beginners in the field of programming for Android. And maybe even experienced pros get something.

So, I needed to somehow determine whether the GPS fix is ​​currently available. It would seem that LBS (location-based service) is a promising and popular thing, and Google, knowing this very well, will provide an easy-to-use tool for their development. Yeah, I ran away ... It’s not all that simple, so I have to excel to a certain extent.
')
Well, what's the problem here? Problem in determining the current location of the user. There are several types, but TK orders to use GPS and positioning along cellular towers. The task is to determine the current coordinates with maximum accuracy, i.e. ideally on gps. If it is not available, then on the towers. If there is a GPS signal, then everything is easy and simple - we take the coordinates from the satellite and do anything with them. If there is no signal, then with the processing of coordinates you risk running into null, in which there is very little good, and with improper handling of exceptions there may be something with sad consequences. So, we need to somehow determine, and if we have a fix?

Well, the problem is visible - we will solve!

Let's start with picking the LocationManager. It has a curious property isProviderEnabled (), which returns a boolean value. Hooray? Sooner ... This value only describes whether the GPS receiver of your phone is on or not (in fact, it was possible to guess from the name). The first pancake turned out as always, go ahead.

Climb into the interior LocationListener. What do we see? Bah, yes, this is an onStatusChanged () handler! Ideally, it responds to the change in the status of the provider by setting appropriate values. Ideally ... He does not react to anything since android 2.1! With sadness we pass by.

Continue? Of course we will continue! The next feint with ears looks obvious - comparing the time of the last fix that came with the current system time. It would seem logical - once the fix is ​​old, the GPS is unavailable. Not quite like this: fixes come only when moving, so you can confuse the inaccessibility of satellites with a simple seat in place. Agree, it will not be entirely pleasant if you sit for yourself, and then suddenly - oppa! - and your phone decided that you teleported 400-500 meters. Again, not that, but remember the trick - it will come in handy.

Now let's look towards GpsStatus.Listener, which implements the onGpsStatusChanged method (int event). The event variable can take several values, but we are interested in GPS_EVENT_SATELLITE_STATUS. The occurrence of such an event indicates that your receiver is analyzing GPS satellites. This is what we need! Then everything is simple and understandable - we take the current GPS status and pull available satellites out of it. In the simplest case, we are just interested in their number.

A small digression for beginners in the field of navigation. To determine the current coordinate, we generally need three satellites (for a three-dimensional coordinate). But this is if you have an atomic clock, which is very, very rare in the case of mobile devices. Therefore, to synchronize the time we need another satellite.

The status handler will look something like this:
LocationManager lm = (LocationManager) getSystemService(Context.LOCATION_SERVICE); GpsStatus.Listener lGPS = new GpsStatus.Listener() { public void onGpsStatusChanged(int event) { if( event == GpsStatus.GPS_EVENT_SATELLITE_STATUS){ GpsStatus status = lm.getGpsStatus(null); Iterable<GpsSatellite> sats = status.getSatellites(); doSomething(); } } }; lm.addGpsStatusListener(lGPS); 

The status variable contains information about all available satellites.

So, then everything is quite wonderful - we look at the number of satellites, if there are less than four, then there is no fix and there can be no other means of positioning (sorry, but I will not describe the specific implementation). This method can be crossed with the juxtaposition of the times described a couple of paragraphs above. So you can set a certain period of "trust" fix

Let's make a balance. All of the above does not give you precise guarantees for determining the availability of a fix. In fact, they just cut off situations in which there is definitely no fix. This, of course, is not quite what I wanted, but already something!

UPD : Looks like a solution is found! It happened thanks to r_ii .
So, your GPS receiver, when turned on, constantly receives signals in accordance with the NMEA protocol. That is what we need!
To view these signals, add the following to the code:

 lm.addNmeaListener(new GpsStatus.NmeaListener() { public void onNmeaReceived(long timestamp, String nmea) { parseNMEA(nmea); }}); 


For this code, thanks to this topic 2m0nd . A full description of the protocol here (pdf, eng).

Actually, it's small - to parse the resulting string. In this case, we are interested in the lines with the key (first) field $ GPGGA, and in them the parameter number 6, cleverly called GPS Quality Indicator. It takes the following values:
Bingo!

PS In no case do I claim to authorship of these methods, since All found exclusively with the help of Google. The purpose of the article is to collect all the information in one heap and some of its structuring so that those who travel to the fabulous world of navigation and programming of mobile devices with a small green creature do not waste time and nerves.
PPS Obviously, the method is far from ideal, so its improvement continues. Any help and criticism (objective) is welcome!

Source: https://habr.com/ru/post/123397/


All Articles