Obtaining the Current Location

设置Location监听器

  LocationManager中有很多方法,使得应用可以获取位置更新。

  典型的观察者模式:注册一个事件监听器,说明location manager想从哪里接收位置更新,并且设定接收位置更新的最小时间间隔和距离间隔,onLocationChanged()回调方法就会在时间和位置间隔相应的频率下被激发。

  LocationListener是一个接口,用于接收LocationManager关于位置变化的通知。

  需要通过requestLocationUpdates(String, long, float, LocationListener)进行监听器的注册。

  LocationListener其中的onLocationChanged(Locationlocation)方法每当位置变化就会被调用。

  比如下面的代码例子,每隔至少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);

处理多源位置更新

  一般来说,更高精确度的定位方法(如GPS定位)比低精确度的定位方法(如基于网络的定位)花费更多的定位时间。

  如果你想要尽快展示位置数据并且在有更好精度的信息可用的时候更新它,一个通常的做法是注册一个位置监听器,同时监听GPS和网络位置提供者。

  在onLocationChanged()回调函数中,你可以接收多个location provider的位置更新,它们可能有不同时间间隔和不同的精度,这时候需要结合逻辑判断,舍弃过时的还有不准确的更新。

  一个实现的例子:

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

  可以看到在这个实现中,判断位置信息是否是一个更好的结果,首先判断获取的位置的时间信息,是不是更新;然后检查精度、是否是同一个provider提供等信息。

明智地使用getLastKnownLocation()

  一些特定应用下,获取位置的首次建立时间如果过长可能难以使用户接受。可以考虑调用getLastKnownLocation()方法,这个方法返回上一次的定位结果。

  当然这个结果很有可能是过期的,因为中间设备可能被关闭然后移动到了一个其他的地方。可以检查返回位置的时间戳和精度,然后决定这个位置是否有用。

  如果丢弃了getLastKnownLocation()方法返回的位置,等待新的位置更新时,最好考虑显示一个合适的信息给用户。

关闭位置更新

  当你不再需要位置数据时,可以关闭位置更新,以减少多余的能量消耗和网络带宽。

  比如,当用户已经离开了位置更新显示的界面,就可以通过在onStop()中调用removeUpdates()方法来停止位置更新。如下:

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

  当然也有一些应用需要持续地更新和处理位置数据,这时候最好将位置更新逻辑放在后台service中,用系统的notification bar让用户看到位置数据。

参考资料

  Training: Obtaining the Current Location

  http://developer.android.com/training/basics/location/currentlocation.html

  LocationManager类:

  http://developer.android.com/reference/android/location/LocationManager.html

  LocationListener接口:

  http://developer.android.com/reference/android/location/LocationListener.html

  Location类:

  http://developer.android.com/reference/android/location/Location.html

更多相关文章

  1. Android(安卓)获取内存卡路径及外存储路径方法
  2. Android(安卓)Activty使用示例【慢慢更新】
  3. Android进阶(二)https请求No peer certificate的解决方法.
  4. Android动画之三:Property Animation(上)
  5. android button 效果设计
  6. [笔记]如何解决Your project contains C++ files but it is not
  7. android.app.Activity 的介绍(转)
  8. Android(安卓)Adapter
  9. WebView的Java和javascript相互调用

随机推荐

  1. android webrtc构建过程
  2. 谁说Android的动画不廉价(三)之共享元素动
  3. 浅谈Android中的线程的通信及Handle机制
  4. Android String Placeholders
  5. Android退出程序(三)——Android事件总线
  6. usb 配置
  7. Android 系統存在設計漏洞,釣魚網站隨時出
  8. ListView 取消点击效果
  9. 【Android的从零单排开发日记】之入门篇(
  10. android 基础知识整理 1