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: 1,072
Last edited:

Alessandro71

Well-Known Member
Licensed User
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.

So the GPS library, even if it's named "GPS" (probably for historic reason) can actually receive data from GLONASS, for example?
If I'm only interested plain Location information (i.e. Latitude, Longitude, Speed) there is no added benefit in using GNSS?
 

Alessandro71

Well-Known Member
Licensed User
In the first post I have posted a warning about the deprecation of GpsStatus whan targeting SDK 31 or later. The original GPS library will no longer work in this situation as GpsStatus is no longer available for use.
It's not clear to me if this warning applies only to GNSS library or also to the built-in standard GPS library.
 

agraham

Expert
Licensed User
Longtime User
The standard GPS library is now hobbled in apps targeting SDK 31 running on Android 11, 12 and later (maybe 10 but I can't test it) as noted in this thread here - which prompted me to add the comment in the first post
 

Alessandro71

Well-Known Member
Licensed User
The Location object of the GNSS library is detected as different by the runtime system, from the Location object of the GPS library.
I discovered this while replacing GPS with GNSS in a project that is using FusedLocationProvider for SDK 31 compliancy:

java.lang.Exception: Sub flp_locationchanged signature does not match expected signature.

My app has 2 different build configuration:
a "Lite" version which uses FusedLocationProvider for fast but coarse location tracking
a "Pro" version which uses GNSS for precise location tracking

for "Lite" version I need to select FusedLocationProvider+GPS libraries while for "Pro" version I must deselect GPS and select GNSS
failure to do select the correct lib (GPS or GNSS) will not produce any error at compile time, but just at run time.
Is there an easy way to make sure I'm selecting the right lib in the right build mode?
I'm thinking about a stub code that causes a compile error when the wrong lib is selected for the current build configuration, maybe using an object that exists only in the correct lib.
Rephrasing my though: is there any code that compiles fine with GPS lib but not with GNSS and viceversa?
I will do some tests in this direction...
 

agraham

Expert
Licensed User
Longtime User
You can tell if you have GNSS selected at compile time by Dimming an instance of GNSStatus which should tell you even before compiling that the GNSS library is not selected. Also if you can Dim a GPSSatellite instance you have either GPS or GNSS selected. Perhaps you can put some conditional code in relying on a Lite or Pro symbol to enable it.
 

Alessandro71

Well-Known Member
Licensed User
You can tell if you have GNSS selected at compile time by Dimming an instance of GNSStatus which should tell you even before compiling that the GNSS library is not selected. Also if you can Dim a GPSSatellite instance you have either GPS or GNSS selected. Perhaps you can put some conditional code in relying on a Lite or Pro symbol to enable it.

Thank you for your feedback: meanwhile I devised the same approach:
B4X:
    #if Lite
    'fast location
    'unselect GNSS libray when using FLP
    Public flp As FusedLocationProvider
    Public GPSScanner as GPS    'unused: just to make sure we have selected the correct library (GPS and not GNSS)
    #else if Pro
    'precise location
    Public GPSScanner As GNSS
    #end if
 
Top