Google的地图服务在全世界来说也是最抢眼的,在Android中也可以使用地图服务,使用MapView可以实现。
1创建新项目,在Build Target时选择“Google APIs”,也就是要添加Google的API jar文件map.jar
2创建AVD时,target同样选择“Google APIs”
3获得“Google Map API Key”,使用jdk的keytool生成MD5 key,Keytool这个文件一般位于%JAVA_HOME/bin目录下。在开发Android程序时,一般是在debug模式下进行的,这时的SDK的build tools会自动使用debug模式下的证书对应用进行签名,为了产生debug模式下证书的MD5 key,我们必须找到keystore密钥库,在Eclipse中,选择菜单window->Preferences->Android->Build查看keystore路径
打开CMD,使用 keytool -list -keystore 'debug kestore路径'生成MD5 key,密码默认为android
获取MD5 key以后,前往https://developers.google.com/android/maps-api-signup申请API key
点击“Generate API Key”
Your key is: 0qFZTnChETSXYodY7eQ_OsScp1HHUUByWyorriA This key is good for all apps signed with your certificate whose fingerprint is: DB:02:A6:CC:77:72:5F:2F:44:F2:E9:78:98:C3:ED:01 Here is an example xml layout to get you started on your way to mapping glory: <com.google.android.maps.MapView android:layout_width="fill_parent" android:layout_height="fill_parent" android:apiKey="0qFZTnChETSXYodY7eQ_OsScp1HHUUByWyorriA" />
4 在AndroidManifiest.xml中在Application节添加配置<uses-library android:name="com.google.android.maps" />
在AndroidManifiest.xml中manifest节添加权限
<uses-permission android:name="android.permission.INTERNET"/>
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION"/>
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION"/>
完整的AndroidManifiest.xml如下:
<?xml version="1.0" encoding="utf-8"?> <manifest xmlns:android="http://schemas.android.com/apk/res/android" package="com.synvata.maps" android:versionCode="1" android:versionName="1.0" > <uses-permission android:name="android.permission.INTERNET"/> <uses-permission android:name="android.permission.ACCESS_FINE_LOCATION"/> <uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION"/> <application android:icon="@drawable/ic_launcher" android:label="@string/app_name" > <uses-library android:name="com.google.android.maps" /> <activity android:name=".MapViewsActivity" android:label="@string/app_name" android:theme="@android:style/Theme.NoTitleBar"> > <intent-filter> <action android:name="android.intent.action.MAIN" /> <category android:name="android.intent.category.LAUNCHER" /> </intent-filter> </activity> </application> </manifest>
5 在layout下Main.xml中添加MapView,如下
<?xml version="1.0" encoding="utf-8"?> <com.google.android.maps.MapView xmlns:android="http://schemas.android.com/apk/res/android" android:id="@+id/mapview" android:layout_width="fill_parent" android:layout_height="fill_parent" android:clickable="true" android:apiKey="0qFZTnChETSXYodY7eQ_OsScp1HHUUByWyorriA" />
6 Activity要继承MapActivity,代码如下
public class MapViewsActivity extends MapActivity { /** Called when the activity is first created. */ @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.main); MapView mapView = (MapView) findViewById(R.id.mapview); mapView.setBuiltInZoomControls(true); } @Override protected boolean isRouteDisplayed() { // TODO Auto-generated method stub return false; } }
此时,运行程序,可以看到Google Map。
7 通常使用地图时,要增加一些自定义功能,比如标注。Android中Overlay这个类提供了在地图上添加图层的基本功能,
新建一个类,命名为HelloItemizedOverlay
,继承于ItemizedOverlay。
声明一个OverlayItem
类型的ArrayList,用于保存所有的图层
private ArrayList<OverlayItem> mOverlays = new ArrayList<OverlayItem>();
定义默认构造函数,构造函数中必须为每一个图层定义一个默认的标注,并且使用bound方法定义标注的位置
public HelloItemizedOverlay(Drawable defaultMarker) { super(boundCenterBottom(defaultMarker)); }
定义方法将图层添加至ArrayList
public void addOverlay(OverlayItem overlay) { mOverlays.add(overlay); populate(); }
重写createItem()和size()方法
@Override protected OverlayItem createItem(int i) { return mOverlays.get(i); } @Override public int size() { return mOverlays.size(); }
为了能够处理标注的触碰事件,我们需要一个新的构造函数,为每一个图层指定应用的上下文,首先添加类成员 Context mContext,构造函数如下
public HelloItemizedOverlay(Drawable defaultMarker, Context context) { super(boundCenterBottom(defaultMarker)); mContext = context; }
然后重写onTap(int)处理图标的点击事件
@Override protected boolean onTap(int index) { OverlayItem item = mOverlays.get(index); AlertDialog.Builder dialog = new AlertDialog.Builder(mContext); dialog.setTitle(item.getTitle()); dialog.setMessage(item.getSnippet()); dialog.show(); return true; }
至此,我们的layer类编写完毕
8 返回MapViewsActivity ,在onCreate()中初始化
List<Overlay> mapOverlays = mapView.getOverlays(); Drawable drawable = this.getResources().getDrawable(R.drawable.androidmarker); HelloItemizedOverlay itemizedoverlay = new HelloItemizedOverlay(drawable, this);
创建 GeoPoint
,它定义了经纬度坐标,其值为经纬度数值*1000,000,然后根据位置创建图层。
GeoPoint point = new GeoPoint(36075402,120413824);
OverlayItem overlayitem = new OverlayItem(point, "Hello!", "I'm in Qingdao City!");
将新图层添加到Map中
itemizedoverlay.addOverlay(overlayitem);
mapOverlays.add(itemizedoverlay);
使用mapView.getController().animateTo(point);将地图移动到指定区域,setZoom()指定放大级别。
完整的MapViewsActivity如下:
public class MapViewsActivity extends MapActivity { /** Called when the activity is first created. */ @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.main); MapView mapView = (MapView) findViewById(R.id.mapview); mapView.setBuiltInZoomControls(true); List<Overlay> mapOverlays = mapView.getOverlays(); Drawable drawable = this.getResources().getDrawable(R.drawable.ic_launcher); HelloItemizedOVerlay itemizedoverlay = new HelloItemizedOVerlay(drawable, this); GeoPoint point = new GeoPoint(36075402,120413824); OverlayItem overlayitem = new OverlayItem(point, "Hello!", "I'm in Qingdao City!"); itemizedoverlay.addOverlay(overlayitem); mapOverlays.add(itemizedoverlay); mapView.getController().animateTo(point); mapView.getController().setZoom(17); } @Override protected boolean isRouteDisplayed() { // TODO Auto-generated method stub return false; } }
附HelloItemizedOverlay.java
public class HelloItemizedOVerlay extends ItemizedOverlay { private ArrayList<OverlayItem> mOverlay = new ArrayList<OverlayItem>(); private Context mContext; public HelloItemizedOVerlay(Drawable defaultMarker) { // TODO Auto-generated constructor stub super(boundCenterBottom(defaultMarker)); } public HelloItemizedOVerlay(Drawable defaultMarker,Context context){ super(boundCenterBottom(defaultMarker)); mContext=context; } @Override protected OverlayItem createItem(int i) { // TODO Auto-generated method stub return mOverlay.get(i); } @Override public int size() { // TODO Auto-generated method stub return mOverlay.size(); } public void addOverlay(OverlayItem overlay){ mOverlay.add(overlay); populate(); } @Override protected boolean onTap(int index) { OverlayItem item = mOverlay.get(index); AlertDialog.Builder dialog = new AlertDialog.Builder(mContext); dialog.setTitle(item.getTitle()); dialog.setMessage(item.getSnippet()); dialog.show(); return true; } }
运行结果如下: