Fetching the best Location in android

As easy it may look but finding the accurate location of an android device is not straight forward.

Three imporatnt things to consider are :-

1. Lag time in getting the location first time (very important)
2. Available LocationProviders
3. Checking if the new location is accurate or not



Solving point 1:



// let Android select the right location provider for you

bestProvider = locationManager.getBestProvider(myCriteria, true);



//If no provider set as network provider

if (bestProvider == null) {

  bestProvider = locationManager.getProvider(

     LocationManager.NETWORK_PROVIDER).getName();

}




The first painful part is getting your location from your locationProvider the very first time. At times some providers like GPS can take more than few minutes to show results. Therefore always check if your provider is null, if yes, then go for the network provider, since it is the fastest locationProvider. 

This is for fetching the location the first time. Later on you can change the provider as per your functionality.

Solving point 2.

List<String> matchingProviders = locationManager.getAllProviders();
ArrayList<Location> lastLocations = new ArrayList<Location>();

for (String provider: matchingProviders) 
{
  Location location = locationManager.getLastKnownLocation(provider);
  if (location != null) 
  {
    lastLocations.add(location);
  }
}
findBestLocation(lastLocations);


Now once you got your first location, you can check for your best locationProvider as given above.
From every locationProvider fetch last location and compare if it is accurate and best(last line)


Solving point 3.

/** 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 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;
}


As given in android dev site, it is always a good idea to compare your new location retrieved in your locationListener with the old location. New location fetched doesn't mean it is accurate. It has to be compared and hence checked if it is better.
The above function does the comparison. You can change it according to your needs

No comments:

Post a Comment