11.3 Android的地图服务
与略显枯燥的地址信息相比,地图无疑是更好地展示位置信息的工具。它不仅能够直观地展示当前位置的周边信息,还可以进行查询路线等更深入的交互操作。
Google以扩展库的形式为Android提供了地图库的支持,开发者可以使用该地图库更好地展示地理信息。
11.3.1 使用地图
Google的地图库是以可选的形式提供给开发者的,因此,在使用之前,需要将开发的SDK切换至Google Add-On版本的SDK下,[1]在该SDK中包含了Google地图库的jar包。
在使用时,开发者需要在应用的配置文件中声明对Google地图库的引用。Android会在运行时检查系统中是否包含对应的地图库,避免应用在执行时出错:
…
<application…>
<!—通过users-library参数声明对Google地图库的引用—>
<uses-library android:name="com.google.android.maps"/>
…
</application>
除此之外,开发者还需要申请Google Map API的使用密钥(Key),用来声明对Google地图服务的使用授权,以此来防止恶意抓取。该密钥与应用的签名文件是一一对应的,具体申请办法可以参考网站的介绍[2]。
地图库的核心是com.google.android.maps.MapView控件,它会通过网络来获取地图数据并将其展示出来。构造含有MapView控件的界面组件,可以派生com.google.android.maps.MapActivity类,使用该组件对象可以更好地管理MapView控件的生命周期,并控制MapView对网络服务的请求。
构造包含MapView控件的组件界面与构造普通组件的界面完全一致,也是通过资源文件来进行描述的:
<!—其中android:apiKey用于放置申请到的Google API密钥—>
<com.google.android.maps.MapView
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:apiKey="MY_GOOGLE_MAP_API_KEY"
…
/>
在地图展示中,除了底图,地标(Overlay)也是重要的信息载体,用来展示与某个具体位置(通过经纬度表示)相关的一些信息,包括地名、地址、图片、介绍等。
在Google地图库中,地标是通过com.google.android.maps.Overlay类来表示的。开发者可以重载Overlay.draw函数来修改地标的展示效果,并利用重载Overlay.onTap函数来响应用户的点击事件。
在实践中,通常会派生com.google.android.maps.ItemizedOverlay类来自定义地标信息。ItemizedOverlay是Overlay的一个子类,用来展示一组相关联的地标信息,并控制地标间的焦点切换、绘制和交互。com.google.android.maps.OverlayItem对象,用来表示ItemizedOverlay中的一个具体的地标信息,其使用示例如下:
//自定义的ItemizedOverlay类
public class VenueItemizedOverlay extends
ItemizedOverlay<OverlayItem>{
//用来存放一系列的地标对象
private ArrayList<OverlayItem>overlays=new ArrayList<OverlayItem>();
private Context context;
public VenueItemizedOverlay(Drawable defaultMarker, Context context){
super(boundCenterBottom(defaultMarker));
this.context=context;
}
protected OverlayItem createItem(int index){
return this.overlays.get(index);
}
public int size(){
return this.overlays.size();
}
public void addOverlayItem(OverlayItem item){
overlays.add(overlay);
populate();
}
protected boolean onTap(int index){
//处理地标点击事件,弹出对话框来展示地标信息
OverlayItem item=this.overlays.get(index);
AlertDialog.Builder builder=
new AlertDialog.Builder(context);
builder.setTitle(item.getTitle());
builder.setMessage(item.getSnippet());
builder.show();
return true;
}
}
…
//构造并添加地标信息Overlay对象
VenueItemizedOverlay overlay=new VenueItemizedOverlay(
getResources().getDrawable(R.drawable.map_marker));
for(int i=0;i<getOverlayItemNumber();++i){
overlay.addOverlayItem(createOverlayItem(i));
}
//把地标信息插入到地图中
MapView mapView=(MapView)findViewById(R.id.my_map);
mapView.getOverlays().add(overlay);
通过地图控件和地标对象,可以将位置信息生动地表现出来。此外,在地图库中,还有一个非常重要的类com.google.android.maps.MapController。MapController的作用是为地标的缩放和切换增加动画效果,让基于地图的信息呈现变得更加活泼生动。比如,将地图的信息区域切换到某个位置,可以通过MapController对象进行控制:
//获取需要切换到的位置
GeoPoint point=getNewLocation();
//使用MapController进行切换
MapView mapView=(MapView)findViewById(R.id.my_map);
mapView.getController().animateTo(point);
[1]关于Google Add-On版本的SDK介绍,可以参见:http://code.google.com/android/add-ons/google-apis/index.html。
[2]申请Map API Key的介绍,参见:http://code.google.com/android/add-ons/google-apis/mapkey.html。