在你构建程序和LocationManager共同工作之后,你开始能获取位置更新。
设置位置监听器
LocationManager类向应用程序暴露了许多方法去获取位置更新。最简单的形式是,你注册一个事件监听器,确认位置管理者从哪里获取位置更新,并且指定获取位置更新的最小时间和距离间隔。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);
处理多个位置更新信息源
一般来说,一个拥有高精度(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);
}
灵活地使用getLastKnowLocation()方法
为了获取一个合理的位置修正而设置的时间间隔可能不会被某些应用程序所接受。你应该考虑调用getLastKnowLocation()方法,它仅仅查询从任何位置提供者获取的最后的位置更新。记住,返回的位置信息会变得陈旧,你应该检查时间间隔和返回位置的精度,并且决定它是否对你的应用程序有用。如果你选择丢弃从getLastKnownLocation()方法返回的位置更新,去等待从位置提供者返回的更新的更新,你应该考虑在地址数据被接受前显示一个合适的消息。终止数据更新
当你使用完了地址数据,你应该停止位置更新从而减少不必要的电源和网络带宽的消耗。例如,如果用户导航离开一个显示位置更新的Activity,在该Activity不在可见的时候,应该在onStop()方法中通过调用removeUpdates()方法停止位置更新(onStop()方法在当Activity不在可见的时候调用,如果你想要学习更多关于Activity生命周期的知识,阅读Stopping and Restarting an Activity章节)。
protected void onStop() {
super.onStop();
mLocationManager.removeUpdates(listener);
}
注意:对于如同一个实时绘图程序一样,需要持续获取和处理位置更新的应用程序,最好是将位置更新逻辑在后台服务中运行,并使用系统通知栏来让用户知道位置数据正在被使用。
文档目录:Developers/Training/Advanced Training/Making Your App Location Aware/Obtaining the Current Location