478 views

Android不同精度的定位

我们在开发LBS类应用时必然会用到Android的定位,本文来看看Android下的不同精度的定位,以及如何判断定位是否更精确。

首先,我们需要1个LocationManager类:

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

有了locationManager之后,我们便可以开始监听位置的变化了,使用LocationManager中的方法:

requestLocationUpdates(String provider,long minTime,float minDistance,LocationListener listener)

来设置监听器。

第一个参数2选1,分别是:LocationManager.NETWORK_PROVIDER和LocationManager.GPS_PROVIDER,前者使用移动网络依靠基站获取位置,精度低速度快,后者使用GPS进行定位,精度高但一般需要10-60秒时间才能开始第1次定位,如果是在室内则基本上无法定位。
这2种Provider肯定是互补的,本文中,我们要同时开启2个监听,但基于移动网络的监听只会执行一次就会被停止,而基于GPS的监听则会一直持续下去。

首先,我们会声明1个监听器的内部类,这个类会同时用于2种模式的监听,还要声明1个currentLocation,用于记录当前的位置。

private class MyLocationListner implements LocationListener{
    @Override
    public void onLocationChanged(Location location) {
        Log.i("LocationTest", "Got The New Location of provider:"+location.getProvider());
        if(currentLocation!=null){
            if(isBetterLocation(location, currentLocation)){
                Log.i("LocationTest", "It’s a better location");
                currentLocation=location;
                showLocation(location);
            }
        }
        else{
            Log.i("LocationTest", "First location");
            currentLocation=location;
            showLocation(location);
        }
        //移除LocationManager.NETWORK_PROVIDER的监听器
        if(LocationManager.NETWORK_PROVIDER.equals(location.getProvider())){
            locationManager.removeUpdates(this);
        }
    }
    public void onStatusChanged(String provider, int status, Bundle extras) {
    }
    public void onProviderEnabled(String provider) {
    }
    public void onProviderDisabled(String provider) {
    }
};
Location currentLocation;
//测试
private void showLocation(Location location){
    //纬度
    Log.i("LocationTest", "Latitude:"+location.getLatitude());
    //经度
    Log.i("LocationTest", "Longitude:"+location.getLongitude());
    //精确度
    Log.i("LocationTest", "Accuracy:"+location.getAccuracy());
}

在showLocation方法中,打印了location的Accuracy属性,一般来说NETWORK得到的位置精度一般在500-1000米,GPS得到的精度一般在5-50米,基于这个属性我们可以对精度进行判断,以决定是否采用这个精度。

上面的代码中有1个isBetterLocation方法,这是用来判断获取的位置是否更好,这个方法来自于Dev Guide:

private static final int CHECK_INTERVAL = 1000 * 30;
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 > CHECK_INTERVAL;
    boolean isSignificantlyOlder = timeDelta < -CHECK_INTERVAL;
    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 boolean isSameProvider(String provider1, String provider2) {
    if (provider1 == null) {
        return provider2 == null;
    }
    return provider1.equals(provider2);
}

我们可以看出上面方法不仅使用了Accuracy,还使用了时间进行判断,只要App需要定位,我们均可以直接使用上面的这个方法来对位置更新信息进行比较,提高精度。 
一般来说,开发时我们先使用NETWORK来得到1个精度较差的位置,可以保存在数据库,一旦有精度更高的位置则覆盖原先的位置信息。

无觅相关文章插件,快速提升流量

发表评论

电子邮件地址不会被公开。 必填项已用 * 标注

*

您可以使用这些 HTML 标签和属性: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>