4

Suppose the device support both gps and glonass(support at the hardware level).

Now when I get location by the android.location API, is it possible to know the hardware where the location came from?


LocationManager locationManager = (LocationManager) getSystemService(Context.LOCATION_SERVICE);
locationManager.requestLocationUpdates(LocationManager.GPS_PROVIDER, 0, 0, new LocationListener());

class LocationListener implement LocationListener(){
    @Override
    public void onLocationChanged(Location location) {
        GPSStatus status=locationManager.getGpsStatus();
        //check the PRN of the satellites from the status
        //but how can be granted that the `status` object obtained here is exactly the same when it was used to calculate the location?
    }
}

If we use the GPSStatus.Listener like this:

class LocationListener implement LocationListener,GPSStatus.Listener(){
    private GPSStatus status;
    @Override
    public void onLocationChanged(Location location) {
        if(status!=null){
            //status should be the GPSStatus before get this location
            //check the PRN of the satellites from the status
            //How it can be granted that the `onGpsStatusChanged` will be called before the `onLocationChanged` by the Android System?
        }

    }
   public void onGpsStatusChanged(int event) {
        status = locationManager.getGpsStatus(null);    
    }
}
hguser
  • 35,079
  • 54
  • 159
  • 293

3 Answers3

6

The hardware the location came from is the GPS/GLONASS chip in your phone. The chip receives signals from satellites orbiting the earth.

GPS and GLONASS satellites are used in combination on devices that support this. To determine if GLONASS satellites were used to determine the location, you can either register a GpsStatusListener or call LocationManager.getGpsStatus(). Call getSatellites() on the GpsStatus object and call getPrn() on each GpsSatellite object in the returned list. If the value is between 65 and 88 and the usedInFix() method returns true the last position was calculated using a GLONASS satellite.

See http://developer.sonymobile.com/knowledge-base/technologies/glonass/

David Wasser
  • 93,459
  • 16
  • 209
  • 274
  • So is that mean the calling of the listener order is important? The `GPSStatus.Listener` should be called before the `LocationListener`, then you can determine if the GLONASS satellites are used for the laste location? BTW, I wonder if the `GPSxxx` is proper in the API, since it seems that `GPSProvider` does not use gps satellites only, but use all available satellites like GLONASS? – hguser Dec 27 '14 at 06:16
  • You register a listener. You don't call it. It calls you when it wants to tell you something. When you get a callback that a new GPS location is available, you can then make the call sequence I described. – David Wasser Dec 28 '14 at 18:17
  • Regarding your complaint about the naming of the API, there was no available GLONASS hardware at the time this API was created. At some point they may change the name of it, but I doubt it. Once things get names, they usually stick - long after the names made any sense. Have you ever wondered why "floppy disks" are called that? Most people born after 1970 have never seen a floppy "floppy disk" in their lives. And yet, that's what they are called. – David Wasser Dec 28 '14 at 18:19
  • Maybe I do not make me clearly enough, check my update if possible. – hguser Dec 29 '14 at 00:42
  • To answer your question, you would need to examine the source code of the location API. This code is vendor-specific, so you would need to look at each and every phone manufacturer's source code. I don't see the point of this, or the benefit. This data is always changing. Sorry, I can't answer your question any more detailed than I already have. – David Wasser Dec 29 '14 at 10:03
  • is there any way to force a device to get location from glonass? – Siavash Abdoli May 18 '19 at 17:50
  • 1
    @SiavashAbdoli not as far as I know. You could post a new question and see if you get any more qualified answers. – David Wasser May 20 '19 at 09:07
1

As @DavidWasser said, it is possible to know that. I wanted to share some codes in addition to @DavidWasser 's answer.

You should have LocationManager object:

private LocationManager locationManager; 

and you initialize that with:

locationManager = (LocationManager) getSystemService(Context.LOCATION_SERVICE);

Request location updates with your implements LocationListener, GpsStatus.Listener class:

locationManager.requestLocationUpdates(LocationManager.GPS_PROVIDER, 0, 0,
        new GPSLocationListener());

GPSLocationListenerClass:

private class GPSLocationListener implements LocationListener,
        GpsStatus.Listener {
    private boolean isGPSFix;

    public void onGpsStatusChanged(int event) {
        checkGlonassFeature(); // the method which checks if locations from GLONASS or GPS
        switch (event) {
        case GpsStatus.GPS_EVENT_SATELLITE_STATUS:
            if (mLastLocation != null)
                isGPSFix = (SystemClock.elapsedRealtime() - lastGPStime) < 3000;
            if (isGPSFix) { // A fix has been acquired.
                Toast toast = Toast.makeText(GPSLocationService.this, "GPS has a fix.", Toast.LENGTH_SHORT);
                toast.setGravity(Gravity.CENTER, 0, 0);
                toast.show();
            } else { // The fix has been lost.
                Toast toast = Toast.makeText(GPSLocationService.this, "GPS DOES NOT have a fix.", Toast.LENGTH_SHORT);
                toast.setGravity(Gravity.CENTER, 0, 0);
                toast.show();
            }
            break;
        case GpsStatus.GPS_EVENT_FIRST_FIX:
            Toast toast = Toast.makeText(GPSLocationService.this, "GPS got first fix.", Toast.LENGTH_SHORT);
            toast.setGravity(Gravity.CENTER, 0, 0);
            toast.show();
            isGPSFix = true;
            break;
        }
    }

    @Override
    public void onLocationChanged(Location location) {
        //  Do works here
    }

    @Override
    public void onStatusChanged(String provider, int status, Bundle extras) {
        String statusDescription = "unknown";
        switch (status) {
        case LocationProvider.OUT_OF_SERVICE:
            statusDescription = "OUT_OF_SERVICE";
            break;
        case LocationProvider.AVAILABLE:
            statusDescription = "AVAILABLE";
            break;
        case LocationProvider.TEMPORARILY_UNAVAILABLE:
            statusDescription = "TEMPORARILY_UNAVAILABLE";
            break;
        }
    }

    @Override
    public void onProviderEnabled(String provider) {
        Toast toast = Toast.makeText(GPSLocationService.this, "GPS feature is active", Toast.LENGTH_SHORT);
        toast.setGravity(Gravity.CENTER, 0, 0);
        toast.show();
    }

    @Override
    public void onProviderDisabled(String provider) {
        Toast toast = Toast.makeText(GPSLocationService.this, "GPS feature is passive", Toast.LENGTH_SHORT);
        toast.setGravity(Gravity.CENTER, 0, 0);
        toast.show();
    }
}

and Finally your control method:

public void checkGlonassFeature() {
    boolean isGPSFromGlonass = false;
    final GpsStatus gs = this.locationManager.getGpsStatus(null);
    final Iterable<GpsSatellite> it = gs.getSatellites();
    for (GpsSatellite sat : it) {
        if(sat.usedInFix()){
            if(sat.getPrn() > 65 && sat.getPrn() < 88)
                isGPSFromGlonass = true;
            else
                isGPSFromGlonass = false;
        }
        else
            isGPSFromGlonass = false;
    }
    if(isGPSFromGlonass){
        Toast toast = Toast.makeText(getBaseContext(), "Location from GLONASS", Toast.LENGTH_SHORT);
        toast.setGravity(Gravity.CENTER, 0, 0);
        toast.show();
    }
    else{
        Toast toast = Toast.makeText(getBaseContext(), "Location from GPS", Toast.LENGTH_SHORT);
        toast.setGravity(Gravity.CENTER, 0, 0);
        toast.show();
    }
}

Note that it is only addition to above answer. Good luck.

Batuhan Coşkun
  • 2,961
  • 2
  • 31
  • 48
0

Typically, most devices that support both Glonass and GPS will combine measurements from the two constellations to make a position. You don't get one or the other, you normally get both. The mix of GPS vs Glonass constellations will depend on where you are and what satellites are visible.

As Batuhan shows above, the way to tell which satellites are used is to walk the list of satellites reported, find the satellites used in the fix, and then look at their ID numbers. ID values of 1 to 32 are for GPS satellites, 65 to 88 are Glonass. The one thing to remember is that standard android has a brain-dead header file called gps.h that doesn't understand about other constellations like Glonass, it only likes GPS. There is a simple tweak that many manufacturers do when parsing pulling data from the GPS driver to fix this, but it needs to be done on both the App processor side and inside the GPS driver code. You can't just tweak this stuff on one side without matching changes on the other. Hopefully, your device is one that has this change so you can see satellite ID numbers from all constellations.

user2246302
  • 386
  • 4
  • 11