0

我正在开发一个位置感知应用程序,当我请求位置更新时,我偶尔会得到一个非常旧的位置(好像它没有更新),或者我收到多个位置通知。我开始深入研究这个问题,发现这个博客描述了 ANDROIDS 位置监听器的工作原理。

简而言之,我的解释是,当 you 时requestLocationUpdates,您不仅会获得一个位置对象,还会收到多个。因此,我开始尝试找出如何从多个位置对象中挑选出最佳位置对象,并在 Android文档中找到了一个算法(在“维护当前最佳估计”部分下)

我对如何将该部分中的代码块实现到我自己的应用程序中感到困惑。代码块接受两个参数,locationcurrentbestlocation比较它们。

  1. 您如何声明两个位置对象以供代码块进行比较?(代码示例或伪代码将不胜感激!)
  2. locationlistener我对提供多个位置对象的理解是否正确?
  3. 如何在我的中实现 GOOGLES 代码?见下文:

我的代码如下:

public class MainActivity extends Activity {
    LocationManager lm;
    LocationListener ll;
    private Location previousLocation;

    public void onCreate(Context context, Intent intent) {    
        lm = (LocationManager)context.getSystemService(Context.LOCATION_SERVICE);
        ll = new myListener();
        lm.requestLocationUpdates(LocationManager.GPS_PROVIDER, 6000, 1000, ll);
    }

    private class myListener implements LocationListener {      
        public void onLocationChanged(Location loc) {
        if (previousLocation == null) {
               previousLocation = loc;
            } else {
                if (isBetterLocation(loc, previousLocation)) {
                //NOTIFICATION NEW LOCATION IS BETTER
                } else {
                //NOTIFICATION PREVIOUS LOCATION IS BETTER
                }
            }
        }
        public void onProviderDisabled(String provider) {
        }
        public void onProviderEnabled(String provider) {
        }
        public void onStatusChanged(String provider, int status, Bundle extras) {
        }
    }

    //GOOGLE ANDROID DOCUMENTATION CODE FOR MAINTAINING CURRENT BEST ESTIMATE
    private static final int TWO_MINUTES = 1000 * 60 * 2;

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

    private boolean isSameProvider(String provider1, String provider2) {
        if (provider1 == null) {
            return provider2 == null;
        }
            return provider1.equals(provider2);
    }
}
4

1 回答 1

1

当您使用LocationManager请求位置更新时,它将继续为您提供更新,直到您告诉它停止或您的应用程序被终止。这样,您可以每隔一段时间监控设备的当前位置,以便知道它们何时移动。如果您只需要一次位置更新,则在收到足够准确的位置修复后,请致电locationManager.removeUpdates(listener).

如果您只计划支持运行 Gingerbread 及更高版本的设备,您也可以使用该requestSingleUpdate(java.lang.String, android.location.LocationListener, android.os.Looper)方法。

首先要做的是声明您的位置侦听器并注册更新。这段代码应该让你开始:

public class MyActivity extends Activity implements LocationListener {
    /** Cache the last location fix received. */
    private Location mLastLocationReceived;

    @Override
    public void onResume() {
        super.onResume();

        // Register our location listener
        LocationManager lm = (LocationManager) getSystemService(LOCATION_SERVICE);
        lm.requestLocationUpdates(LocationManager.NETWORK_PROVIDER, 10000, 500, this);
    }

    @Override
    public void onPause() {
        super.onPause();

        // Unregister our location listener
        LocationManager lm = (LocationManager) getSystemService(LOCATION_SERVICE);
        lm.removeUpdates(this);
    }

    @Override
    public void onLocationChanged(Location location) {
        if (mLastLocationReceived == null) {
            mLastLocationReceived = location;
        } else {
            if (isBetterLocation(location, mLastLocationReceived)) {
                // New location fix is better!
            } else {
                // New location fix is not better!
            }
        }
    }

    @Override
    public void onProviderDisabled(String provider) {
        // Pass
    }

    @Override
    public void onProviderEnabled(String provider) {
        // Pass
    }

    @Override
    public void onStatusChanged(String provider, int status, Bundle extras) {
        // Pass
    }

    private boolean isBetterLocation(Location newLocation,
            Location oldLocation) {

        // TODO: Implement the logic to determine if the new location is
        // of better quality than the old location. Your application's
        // business logic determines what this method should do.

        return false;
    }

}

请注意,该isBetterLocation方法始终返回false,并由您提供实现。这里有一个很好的示例实现。另外,我没有测试这段代码,所以请原谅任何错误。

于 2012-12-31T23:30:50.940 回答