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。