B4A Library GNSS library - an updated GPS library

The GNSSS library is an updated GPS library that allows you to get information about visible satellites from the phone's GNSSS device using an enhancement introduced in Android API version 24.

The GNSS receivers in devices will vary in which constellations that they will recognize depending on when they were designed. Devices from 2019 and later will probably recognise all four of the GPS, GALILEO, GLONASS and BEIDOU constellations. Android devices, if capable, will report location information using all available constellations. However only limited satellite information is available in the original GpsStatus event.

To access additional data on the satellites a new GnssStatus event is available in Android API 24 and later. This library exposes that event. The library can be used without problem on earlier devices but on these the GnssStatus event will never be raised. The GnssStatus event passes a single GnssStatus object as its only parameter which contains information for the visible satellites of all the constellations available.

This library is a strict superset of the original GPS library and can be used as a drop-in replacement for the GPS library merely by deselecting the GPS library, selecting the GNSS library and changing the GPS type to GNSS in the code.

In fact, as I found when I was playing with this library on my latest device, which can see four GNSS constellations, the new GnssStatus data is not really necessary to identify the constellation to which a satellite belongs (which was the original reason for me to implement the GnssStatus event) and so is only useful if you need the other additional information it provides.

It seems that the GPSSatellite list returned by the GpsStatus event in the existing GPS library contains every satellite visible to the device with the Prn adjusted to avoid duplication by adding a constant value depending upon which constellation the satellite belongs to. I found this by inspection and have not seen this documented anywhere.

The base values for each constellation are as returned by GnssStatus.Svid(). GPS PRNs are unadjusted and are in the range 1 to 32. Glonass FCNs/OSNs have 64 added and are in the range 65 to 88 or possibly 157 to 172. Beidou PRNs have 200 added and are in the range 201 to 237. Galileo PRNs have 300 added and are in the range 301 to 326. The included demo illustrates this.

If your app targets SDK 31 or later and has a GpsStatus event Sub in your code you may get an 'UnsupportedOperationException: GpsStatus APIs not supported, please use GnssStatus APIs instead' error when running your app. The GpsStatus class was deprecated in API level 24 and Google is now enforcing the deprecation. This applies to the original GPS library and to this one. You will need to use this library and its GnssStatus event instead. All the same information, and more, is available from the GnssStatus event as was available in the GpsStatus event.
 

Attachments

  • GNSS_v1.0.zip
    27 KB · Views: 2,044
Last edited:

emexes

Expert
Licensed User
It seems that the GPSSatellite list returned by the GpsStatus event in the existing GPS library contains every satellite visible to the device with the Prn adjusted to avoid duplication by adding a constant value depending upon which constellation the satellite belongs to. I found this by inspection and have not seen this documented anywhere.
I saw this information a couple of months back, but not sure where. I recall that I was investigating augmentation / local offsets, so it might even have been in GPS World journal or similar. Or perhaps in the datasheet for a GNSS module. Naturally, now I can't find it - but I'm sure I will soon, milliseconds after I click "Post Reply"... :)
 

emexes

Expert
Licensed User
I found this by inspection and have not seen this documented anywhere.
Yikes! You're right about the sparsity of documentation, and I suspect the reason for it might be touched upon in this forum posting:

It is unfortunate that more information is not available about NMEA satellite identification. The NMEA organization only provides this information as a for-sale publication, and, even if those publications are purchased, the buyer is forbidden to disclose the information they contain. It is only through third-party disclosures, such as the programming guide for devices that utilize NMEA protocols, that any knowledge is provided about the details.

Page 7 of this document has a comprehensive table of GNSS satellite numbering systems. I bought a couple of U-Blox USB dongles last year, they work with both GPS and GLONASS, but turns out that it's one-or-the-other, not both at the same time. Boy, was I sad about that. I had the inverse problem with my iPhone 4S - I've always been impressed by how well the GPS works in that (esp. given the antennagate kerfuffle) and it was six years later that I first found out that the hardware supports GLONASS too (not sure if it uses it, but... it sure feels like it does ;-)
 
Last edited:

agraham

Expert
Licensed User
Longtime User
I bought a couple of U-Blox USB dongles last year, they work with both GPS and GLONASS, but turns out that it's one-or-the-other, not both at the same time
Yes, I've just bought a U-Blox USB device to play with and encountered that problem :(

Gnss device support for NMEA sentences supporting Beidou and Galileo seems a mess with various manufacturers doing it differently. I've found that NMEA sentences are also inconsistent across Android devices but the LocationManager API does seems solid and consistent. For NMEA, whatever the dongle or device, at least you seem to be able to rely on getting a GPRMC or a GNRMC sentence, sometimes both!, for the actual fix.
 

agraham

Expert
Licensed User
Longtime User
As a matter of information some people might be interested in this. I've been looking at using my Android devices as Bluetooth GNSS devices to feed NMEA sentences to a Window laptop or tablet running my mapping program. This would be useful as my latest devices seem to have very sensitive receivers and decent Bluetooth stand-alone receivers supporting Beidou and Galileo are rather expensive. I was going to write my own but before doing that I looked at what was available in the Play Store. As might be expected what I could find was mainly crappily written rubbish - that about sums up my usual experience with apps from the Play Store: mostly ad-ridden rubbish.

However I did find this which seems to be the best of a bad bunch

https://play.google.com/store/apps/details?id=com.meowsbox.btgps&hl=en_US

Unlike other attempts this does seem to connect consistently to my PC with my several Android devices, though you have to know what you are doing at the Windows end to enable SPP on the connected device. Also you need to be in their beta program to get something that more or less works on Android 8+. I am in conversation with them about a couple of problems I have found but in the mean time it does provide a fix and satellite information although which constellation a satellite belongs to is not presently correctly implemented.
 

marcick

Well-Known Member
Licensed User
Longtime User
@ I bought a couple of U-Blox USB dongles last year, they work with both GPS and GLONASS, but turns out that it's one-or-the-other, not both at the same time

I've never played with uBlox USB dongle and I don't know your which uBlox module has inside, but wich constelation the module works with (GPS, Glonass or both) is a configurable parameter.
 

Alessandro71

Well-Known Member
Licensed User
Longtime User
It looks like the GNSS is providing a Location object that is different from the Location object provided by the standard GPS library.
In my project I was using both FusedLocationProvider and GPS libraries: as soon as I replaced the GPS library with GNSS, I get this error from
B4X:
java.lang.Exception: Sub flp_locationchanged signature does not match expected signature.
Putting back the original GPS library fixes the problem.
 

agraham

Expert
Licensed User
Longtime User
GNSS is providing a Location object that is different from the Location object provided by the standard GPS library.
No it's not.The GNSS is a strict superset of the GPS library with additions not changes. I've just checked that in the GNSS demo and GPS and GNSS are interchangeable.

From the name that error looks like its from the FusedLocationProvider event. I've never used the FusedLocationProvider library so I don't know if there might be a conflict but try without FusedLocationProvider and if the problem persists post some example code.
 

Alessandro71

Well-Known Member
Licensed User
Longtime User
I've seen this. Check that you don't have both GPS and GNSS libraries selected in the Libraries tab.

That's precisely what I'm doing: only the GNSS library is selected, and I have that runtime exception.
Let me explain the context a little more.
My project have two different location options:
1) FusedLocationProvider for fast, but not really accurate positioning
2) GPS for high precision tracking
User has choice between the 2, since I've already tested that FusedLocationProvider is not accurate enough for tracking fast motion like a car moving on a road.
Both location providers use the Location object: when you select FusedLocationProvider library, you should also select GPS for importing the Location object.
The project is running correctly with FusedLocationProvider + GPS
As soon as I replaced the GPS library with the GNSS one, I started getting the signature exception.
This happens with the GNSS library only selected and also with both GPS and GNSS selected.
Reverting back to using only GPS objects and pulling out GNSS, restores correct behavior.
Thus my inference about the Location object being somewhat redefined in GNSS, since the sub signature references only that object
B4X:
Sub flp_LocationChanged(Location1 As Location)
 

agraham

Expert
Licensed User
Longtime User
when you select FusedLocationProvider library, you should also select GPS for importing the Location object.
That's probably the problem. As I said I don't know anything about FusedLocationProvider as I have never used it, but the full class name of the Location object will depend on the library Java class name (not visible in B4A) so if it is expecting an anywheresoftware.b4a.gps.LocationWrapper instance and getting an anywheresoftware.b4a.gnss.LocationWrapper instance it will cause this error.
 

agraham

Expert
Licensed User
Longtime User
I have located FusedLocationProvider and poked around inside it and sure enough it imports the GPS library LocationWrapper when compiled.
Java:
import anywheresoftware.b4a.gps.LocationWrapper;

What is the use case for this app? What GNSS enhancements do you need? I can compile you a version of GNSS that should work with FusedLocationProvider but I am not willing to post a modified library for general use with the same package name as another library.
 

Alessandro71

Well-Known Member
Licensed User
Longtime User
What is the use case for this app? What GNSS enhancements do you need? I can compile you a version of GNSS that should work with FusedLocationProvider but I am not willing to post a modified library for general use with the same package name as another library.

I understand that this is not the proper way to go.
I just used the GNSS library out of the "drop-in replacement" for the GPS one, hoping to have a better precision for a tracking app for cars.
I think I will drop FusedLocationProvider instead, it's a tricky error, since there's no sign of it coming at compile time, it just shows up at runtime.
Thank you for your effort.
 

Alessandro71

Well-Known Member
Licensed User
Longtime User
But still, one thing it's not yet clear to me: by using GNSS instead of GPS, will I get a faster fix/more accurate positioning information?
Location-wise, are there any benefits, or is it just for accessing extended information like constellation data?
 

agraham

Expert
Licensed User
Longtime User
is it just for accessing extended information like constellation data?
Yes. If you read the first post you can get some constellation data from the GPS library. GNSS gives you a lot of extra individual satellite data in the additional GNSSStatus event otherwise it is identical to the GPS library.
 
Top