获取当前位置

在配置好LocationManger之后,就可以开始获取位置信息了。

Set Up the Location Listener


LocationManger类有很多获取信息的方法。用简单的方式,你需要注册监听事件,来获取定位信息,最小时间和每个位置的距离。回调函数 onLocationChanged() 会被调用并关联有时间和距离信息。

在下面的例子中,如果设备移动10米以上距离,位置监听接口每10秒获取通知。从位置提供者那里,其他的回调方法会得到应用的状态改变的相关内容。

private final LocationListener listener = new LocationListener() {

    @Override
    public void onLocationChanged(Location location) {
        // A new location update is received.  Do something useful with it.  In this case,
        // we're sending the update to a handler which then updates the UI with the new
        // location.
        Message.obtain(mHandler,
                UPDATE_LATLNG,
                location.getLatitude() + ", " +
                location.getLongitude()).sendToTarget();

            ...
        }
    ...
};

mLocationManager.requestLocationUpdates(LocationManager.GPS_PROVIDER,
        10000,          // 10-second interval.
        10,             // 10 meters.
        listener);

Handle Multiple Sources of Location Updates


通常来说,GPS会比变通的网络定位更 耗时。如果你想更快、更精准的显示位置数据,通用的方法是注册GPS和网络的位置监听接口。在 onLocationChanged() 回调中,你将从不同位置提供者那里得到不同时间戳和动态精确度的位置信息。你需要把逻辑来消除歧义的位置提供者和丢弃更新陈旧和不准确。下面的代码片断示范了简单的逻辑实现。

private static final int TWO_MINUTES = 1000 * 60 * 2;

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

/** Checks whether two providers are the same */
private boolean isSameProvider(String provider1, String provider2) {
    if (provider1 == null) {
      return provider2 == null;
    }
    return provider1.equals(provider2);
}

Use getLastKnownLocation() Wisely




获取准确的定位的准备时间在某些应用程序也许是无法接受的。你应该考虑调用getLastKnownLocation()来获取之前某个定位提供者的定位信息。记住获得的位置也许是过时的。你应该检查时间戳和位置的精确度来决定是否是有用的。如果你选择抛弃getLastKnownLocation()获得的位置信息,等待定位提供者刷新信息,你应该考虑展示合理的消息在获得位置数据之前来告知用户。

Terminate Location Updates


当你需要用到位置数据时,你应该终止位置更新来减少不必的电量和带宽的消耗。例如,用户退出了有定位更新和显示的导航页(Activity),你应该在onStop中通过调用removeUpdates()停止定位更新。(onStop会在activity不可见的时候调用。如果你想了解更多的activity的生命周期,请阅读 Stopping and Restarting an Activity

protected void onStop() {
    super.onStop();
    mLocationManager.removeUpdates(listener);
}


标记:像实时地图这样的应用程序需要方便的获得位置信息,最好的方式是通过service来更新,通过系统通知栏来告知用户定位功能正在被使用。

未完待续。。。