Retrieving # of satellites used in gps fix from Android
android, gps, locationmanager, satellite
Solution
locationManager.requestLocationUpdates(LocationManager.NETWORK_PROVIDER, 0, 0, locationListener);
Should be
locationManager.requestLocationUpdates(LocationManager.GPS_PROVIDER, 0, 0, locationListener);
Problem
I am trying to retrieve the # of satellites used in the GPS fix. I have implemented two different methods, as shown below: ``` package ti.utils; import android.app.Activity; import android.content.Context; import android.location.GpsSatellite; import android.location.GpsStatus; import android.location.Location; import android.location.LocationListener; import android.location.LocationManager; import android.os.Bundle; public class Gps { private static final int TWO_MINUTES = 1000 * 60 * 2; private static Location Location; public static int Satellites = -1; public static void StartTracking(Activity activity) { final LocationManager locationManager = (LocationManager) activity.getSystemService(Context.LOCATION_SERVICE); //listen for gps status changes. GpsStatus.Listener gpsStatusListener = new GpsStatus.Listener() { public void onGpsStatusChanged(int event) { Log("In onGpsStatusChanged event: " + event); if (event == GpsStatus.GPS_EVENT_SATELLITE_STATUS || event == GpsStatus.GPS_EVENT_FIRST_FIX) { GpsStatus status = locationManager.getGpsStatus(null); Iterable<GpsSatellite> sats = status.getSatellites(); // Check number of satellites in list to determine fix state Satellites = 0; for (GpsSatellite sat : sats) { //if(sat.usedInFix()) Satellites++; } Log("Setting Satellites from GpsStatusListener: " + Satellites); } } }; locationManager.addGpsStatusListener(gpsStatusListener); //listen for location changes. LocationListener locationListener = new LocationListener() { public void onLocationChanged(Location location) { // Called when a new location is found by the network location provider. try { Log("Location changed! Speed = " + location.getSpeed() + " & Satellites = " + location.getExtras().getInt("satellites")); boolean isBetter = isBetterLocation(location, Location); if(isBetter) { Log("Set to new location"); Location = location; Satellites = location.getExtras().getInt("satellites"); Log("Setting Satellites from LocationListener: " + Satellites); } } catch(Exception exc) { Log(exc.getMessage()); } } public void onStatusChanged(String provider, int status, Bundle extras) {} public void onProviderEnabled(String provider) {} public void onProviderDisabled(String provider) {} }; locationManager.requestLocationUpdates(LocationManager.NETWORK_PROVIDER, 0, 0, locationListener); } /** Determines whether one Location reading is better than the current Location fix * @param location The new Location that you want to evaluate * @param currentBestLocation The current Location fix, to which you want to compare the new one */ protected static boolean isBetterLocation(Location location, Location currentBestLocation) { if (currentBestLocation == null) { // A new location is always better than no location return true; } // Check whether the new location fix is newer or older long timeDelta = location.getTime() - currentBestLocation.getTime(); boolean isSignificantlyNewer = timeDelta > TWO_MINUTES; boolean isSignificantlyOlder = timeDelta < -TWO_MINUTES; boolean isNewer = timeDelta > 0; // If it's been more than two minutes since the current location, use the new location // because the user has likely moved if (isSignificantlyNewer) { return true; // If the new location is more than two minutes older, it must be worse } else if (isSignificantlyOlder) { return false; } // Check whether the new location fix is more or less accurate int accuracyDelta = (int) (location.getAccuracy() - currentBestLocation.getAccuracy()); boolean isLessAccurate = accuracyDelta > 0; boolean isMoreAccurate = accuracyDelta < 0; boolean isSignificantlyLessAccurate = accuracyDelta > 200; // Check if the old and new location are from the same provider boolean isFromSameProvider = isSameProvider(location.getProvider(), currentBestLocation.getProvider()); // Determine location quality using a combination of timeliness and accuracy if (isMoreAccurate) { return true; } else if (isNewer && !isLessAccurate) { return true; } else if (isNewer && !isSignificantlyLessAccurate && isFromSameProvider) { return true; } return false; } /** Checks whether two providers are the same */ private static boolean isSameProvider(String provider1, String provider2) { if (provider1 == null) { return provider2 == null; } return provider1.equals(provider2); } private static void Log(String message) { if(message != null && message.length() > 0) { //android.util.Log.i(LCAT, message); org.appcelerator.kroll.common.Log.i("SygicModule", message); } } } ``` Neither of the listener events (onGpsStatusChanged & onLocationChanged) ever fire, even though I have standalone GPS enabled on my phone. I have the ACCESS_FINE_LOCATION permission set: ``` <uses-permission android:name="android.permission.ACCESS_FINE_LOCATION"/> ``` I downloaded a 3rd party app called GPS Status and it was able to correctly display the # of satellites, so I know it isn't an issue with my Droid X2. Any ideas?