显示位置信息
在前面的课程中,位置的更新以纬度和经度的形式获取。这种方式对计算距离或者在地图上显示图钉是很有用的,这种小数对终端用户又是毫无意义的。如果对用户显示位置,有很多更好的方式来代替。
Perform Reverse Geocoding
Reverse-geocoding是将经纬度坐标转化为可读地址的过程。Geocoder
API可以做到这一点。最后注意,这个API是基于一个web服务 。如果这个服务在设备上不允许,这个API将抛出"Service not Available exception" 的异常或者返回空的地址队列。在Android2.3(API level 9)之后一个很有用的方法isPresent()被加入,用来检查是否存在。下面的代码片断用来展示 Geocoder
API的 reverse-geocoding功能。因为getFromLocation()
是异步的,所以你不应该在UI线程中调用,因此AsyncTask
被使用在片断中。
private final LocationListener listener = new LocationListener() {
public void onLocationChanged(Location location) {
// Bypass reverse-geocoding if the Geocoder service is not available on the
// device. The isPresent() convenient method is only available on Gingerbread or above.
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.GINGERBREAD && Geocoder.isPresent()) {
// Since the geocoding API is synchronous and may take a while. You don't want to lock
// up the UI thread. Invoking reverse geocoding in an AsyncTask.
(new ReverseGeocodingTask(this)).execute(new Location[] {location});
}
}
...
};
// AsyncTask encapsulating the reverse-geocoding API. Since the geocoder API is blocked,
// we do not want to invoke it from the UI thread.
private class ReverseGeocodingTask extends AsyncTask<Location, Void, Void> {
Context mContext;
public ReverseGeocodingTask(Context context) {
super();
mContext = context;
}
@Override
protected Void doInBackground(Location... params) {
Geocoder geocoder = new Geocoder(mContext, Locale.getDefault());
Location loc = params[0];
List<Address> addresses = null;
try {
// Call the synchronous getFromLocation() method by passing in the lat/long values.
addresses = geocoder.getFromLocation(loc.getLatitude(), loc.getLongitude(), 1);
} catch (IOException e) {
e.printStackTrace();
// Update UI field with the exception.
Message.obtain(mHandler, UPDATE_ADDRESS, e.toString()).sendToTarget();
}
if (addresses != null &s;&s; addresses.size() > 0) {
Address address = addresses.get(0);
// Format the first line of address (if available), city, and country name.
String addressText = String.format("%s, %s, %s",
address.getMaxAddressLineIndex() > 0 ? address.getAddressLine(0) : "",
address.getLocality(),
address.getCountryName());
// Update the UI via a message handler.
Message.obtain(mHandler, UPDATE_ADDRESS, addressText).sendToTarget();
}
return null;
}
}