0
    public void onLocationChanged(Location location) {
      if (!isBetterLocation(location, lastKnownLocation))
        return; 
 
      if (lastKnownLocation != null) {
        location.setSpeed(location.distanceTo(lastKnownLocation) / (location.getTime() - lastKnownLocation.getTime()) * 3600 * 1000);
        location.setBearing(lastKnownLocation.bearingTo(location));
      } 
      txtLocation.setText(String.format("%f, %f (spd: %f km/h, bearing: %f) on %s from %s",
              location.getLatitude(),
              location.getLongitude(),
              location.getSpeed() / 1000,
              location.getBearing(),
              new Date().toLocaleString(),
              location.getProvider())
      ); 
      lastKnownLocation = location;
 
      if (mUpdateEnabled)
        sendUpdateMapMessage(0); 
    } 
 
    /* I don't care! */ 
    public void onStatusChanged(String s, int i, Bundle bundle) {
    } 
 
    public void onProviderEnabled(String s) {
    } 
 
    public void onProviderDisabled(String s) {
    } 
 
    /* Straight from Google' Document */ 
 
    private static final int HALF_MINUTES = 1000 * 30;
 
    /** 
     * 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 > HALF_MINUTES;
      boolean isSignificantlyOlder = timeDelta < -HALF_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;