Location Strategies
注:本指南中描述的策略适用于平台定位API中android.location。该谷歌位置服务API,谷歌Play的一部分服务,提供了更强大的,高层次的框架,自动处理位置提供者,用户的移动和定位精度。它还可以处理基于功耗参数你提供位置更新的调度。在大多数情况下,你会得到更好的电池性能,以及更合适的准确性,使用位置服务API。
要了解更多有关位置服务API,请参阅谷歌Android位置服务。
了解用户所在允许应用程序更聪明,给用户提供更好的信息。在开发Android的位置感知应用程序,你可以利用GPS和Android的网络位置提供商获取用户位置。虽然GPS是最精确的,它只能在户外,它会迅速消耗电池电力,并且不尽快用户希望返回的位置。 Android的网络位置提供商决定使用手机信号塔和Wi-Fi信号,提供了在工作室内和室外的方式位置信息的用户定位,响应速度更快,节省电池电量。要在应用程序获取用户的位置,可以使用GPS和网络位置提供商,或者只是一个。
在确定用户位置的挑战
从移动设备获取用户位置可以是复杂的。有几个原因的位置读数(不论其来源)可以包含错误和不准确的。在用户定位误差的一些来源包括:
位置众多来源
GPS,小区ID,和Wi-Fi可分别提供线索给用户的位置。确定哪些使用和信任是在准确度,速度和电池效率的权衡的问题。
移动用户
由于用户位置的变化,必须重新估计用户位置,每隔一段时间占移动。
不同精度
位置估计每个位置源未来不在其准确性是一致的。从一个来源获得10秒前一个位置可能比从其他或同一源中的最新位置更加准确。
这些问题可以使它难以获得可靠的用户的位置的读数。本文提供的信息,以帮助您应对这些挑战,以获得可靠的位置读数。它还提供了可以在应用程序中使用,以提供一个准确,反应地理位置体验用户的想法。
请求位置更新
解决一些上述的定位误差之前,这里是介绍如何可以在Android上获取用户的位置。
在入门的Android用户位置以回调的方式工作。您表明您想通过调用requestLocationUpdates()接收来自的LocationManager(“位置经理”)位置更新,传递一个LocationListener的。您LocationListener的必须实现几个回调方法,该位置管理器调用时,用户位置的变化或当服务的状态发生变化。
例如,下面的代码演示了如何定义一个LocationListener的要求和位置更新:
// Acquire a reference to the system Location Manager LocationManager locationManager = (LocationManager) this.getSystemService(Context.LOCATION_SERVICE); // Define a listener that responds to location updates LocationListener locationListener = new LocationListener() { public void onLocationChanged(Location location) { // Called when a new location is found by the network location provider. makeUseOfNewLocation(location); } public void onStatusChanged(String provider, int status, Bundle extras) {} public void onProviderEnabled(String provider) {} public void onProviderDisabled(String provider) {} }; // Register the listener with the Location Manager to receive location updates locationManager.requestLocationUpdates(LocationManager.NETWORK_PROVIDER, 0, 0, locationListener);在requestLocationUpdates第一个参数()的位置提供者的类型使用(在这种情况下,手机信号塔和Wi-Fi的定位网络位置提供商)。您可以控制在该监听器接收的第二和第三个参数,第二个更新的频率是通知,三是介于两者之间的距离最小的更改通知,同时设置为零请求位置通知之间的最短时间间隔尽可能频繁地。最后一个参数是你的LocationListener的,它接收的位置更新回调。
<manifest ... > <uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" /> ... </manifest>如果没有这些权限,您的申请将请求位置更新时,在运行时失败。
图1表示在其中应用程序监听位置更新窗口的时间表。
这种模式的一个窗口,在此期间,位置更新接收帧很多,你需要你的应用程序添加基于位置的服务时作出的决定的。
决定什么时候开始监听更新
作为应用程序启动时,或仅用户激活某项功能后,您可能要立即开始监听位置更新。要知道,监听定位坐标长窗可以消耗大量的电池电量,但短期内可能不会允许足够的精度。
如上所示,你可以开始通过调用requestLocationUpdates()监听的更新:
String locationProvider = LocationManager.NETWORK_PROVIDER; // Or, use GPS location data: // String locationProvider = LocationManager.GPS_PROVIDER; locationManager.requestLocationUpdates(locationProvider, 0, 0, locationListener);掌握最后的已知位置的快速修复
String locationProvider = LocationManager.NETWORK_PROVIDER; // Or use LocationManager.GPS_PROVIDER Location lastKnownLocation = locationManager.getLastKnownLocation(locationProvider);决定何时停止监听更新
// Remove the listener you previously added locationManager.removeUpdates(locationListener);维护当前最佳估计数
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); }调整模式以节省电池和数据交换
图2表示在其中获得的用户位置,并且当用户消耗的当前位置收听停止窗口的时间表。
此线与如何用户位置的以前的模式中的代码获得(图1)。为了获得最佳的定位精度,您可以选择开始监听位置更新,当用户开始创建内容或应用程序启动,即使,然后停止监听更新时的内容已准备好发布或记录。您可能需要考虑创建内容的典型任务需要多长时间,并判断此持续时间允许的位置估计的有效收集。
帮助用户就去哪决定
你可能会创建一个试图为用户提供了一组有关到哪里选择一个应用程序。例如,你希望提供附近的餐馆,商店和娱乐场所以及根据用户位置的变化建议的顺序列表。
为了适应这样的流程,你可以选择:
当获得新的最佳估计重新排列推荐
停止监听更新,如果建议的顺序有所企稳
这种模型在图3中被可视化。
图2表示在其中获得的用户位置,并且当用户消耗的当前位置收听停止窗口的时间表。
此线与如何用户位置的以前的模式中的代码获得(图1)。为了获得最佳的定位精度,您可以选择开始监听位置更新,当用户开始创建内容或应用程序启动,即使,然后停止监听更新时的内容已准备好发布或记录。您可能需要考虑创建内容的典型任务需要多长时间,并判断此持续时间允许的位置估计的有效收集。
帮助用户就去哪决定
你可能会创建一个试图为用户提供了一组有关到哪里选择一个应用程序。例如,你希望提供附近的餐馆,商店和娱乐场所以及根据用户位置的变化建议的顺序列表。
为了适应这样的流程,你可以选择:
当获得新的最佳估计重新排列推荐
停止监听更新,如果建议的顺序有所企稳
这种模型在图3中被可视化。
telnet localhost <console-port>发送位置数据:
geo fix -121.45356 46.51119 4392地理NMEA发送NMEA 0183句。
geo nmea $GPRMC,081836,A,3751.65,S,14507.36,E,000.0,360.0,130998,011.3,E*62有关如何连接到模拟器控制台的信息,请参阅使用模拟器控制台。