之前的几个应用都用到了百度地图Android SDK,官方SDK更新到2.0之后,提供矢量版底图,支持3D效果图展示,(更多更新日志请查看官方文档。 )决定对应用中用到的百度地图SDK也进行更新,发现有不少开发者对官方的这次更新有不少抱怨,其实官方更新也是为了提高用户体验,增加或删减一些方法在所难免。接下来我会写一个百度地图Android SDK使用系列文章,主要是面向一些新手开发者。本人水平有限,有不对之处,请指正! 1、获取API Key

用户在使用SDK之前需要获取百度地图移动版API Key,该Key与你的百度账户相关联。您必须先有百度帐户,才能获得API KEY。并且,该KEY与您引用API的程序名称有关,具体流程请参照获取密钥

2、新建并配置工程

新建一个工程,命名为BaiduMapDemo.由于我们将演示一系列例子,所以新建一个MainActivity作为”导航菜单”。

下载百度地图Android SDK,将开发包里的baidumapapi_v2_0_0.jar拷贝到项目的libs根目录下,将libBMapApiEngine_v2_0_0.so和libvi_voslib.so 拷贝到libs\armeabi目录下。然后在baidumapapi_v2_0_0.jar上右键–Build Path–Add to Build Path.

新建一个类,命名为ShowMapActivity并继承自Activity,(在百度地图Android SDK 2.0后需要显示地图的Activity并不需要再继承MapActivity)。再新建一个布局文件activity_map.xml,布局xml文件中添加百度地图控件:

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
  >

     <com.baidu.mapapi.map.MapView
        android:id="@+id/bmapsView"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:clickable="true" />

 </RelativeLayout>

然后在Manifest中注册ShowMapActivity并添加使用权限及屏幕支持;

 <supports-screens android:largeScreens="true"
        android:normalScreens="true"
        android:smallScreens="true"
        android:resizeable="true"
        android:anyDensity="true"/>

 <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE"/>
 <uses-permission android:name="android.permission.INTERNET"/>
 <uses-permission android:name="android.permission.ACCESS_WIFI_STATE"/>
 <uses-permission android:name="android.permission.CHANGE_WIFI_STATE"/>
 <!-- SDK离线地图和cache功能需要读写外部存储器 -->
 <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
 <!-- 获取设置信息和详情页直接拨打电话需要以下权限  -->
 <uses-permission android:name="android.permission.READ_PHONE_STATE"/>
 <uses-permission android:name="android.permission.CALL_PHONE"/>

在使用百度地图之前必须前初始化BMapManager对象,而且我们接下来一系列演示都会用到BMapManager对象,所以我们将BMapManager的初始化放到自定义的Application类中。新建一个类,命名为MapApplication,继承至Application。初始化代码如下:

package com.liuzhichao.baidumapdemo;

import android.app.Application;
import android.util.Log;
import android.widget.Toast;

import com.baidu.mapapi.BMapManager;
import com.baidu.mapapi.MKGeneralListener;
import com.baidu.mapapi.map.MKEvent;

public class MapApplication extends Application {

	private static MapApplication mInstance;
	public static final String TAG = MapApplication.class.getSimpleName();
	public BMapManager mapManager = null;

	public static MapApplication getInstance(){
			return mInstance;
	}

	public static final String BAIDUMAP_KEY="你的百度地图API Key";
	@Override
	public void onCreate() {
		super.onCreate();
		mInstance = this;

		mapManager = new BMapManager(getApplicationContext());
		mapManager.init(BAIDUMAP_KEY, new MyMKGeneralListener());
	}

	// 常用事件监听,用来处理通常的网络错误,授权验证错误等
   public static class MyMKGeneralListener implements MKGeneralListener{

	   @Override
		public void onGetPermissionState(int iError) {
			if (iError == MKEvent.ERROR_PERMISSION_DENIED) {
			Toast.makeText(MapApplication.getInstance().getApplicationContext(),
					"百度地图授权错误!", Toast.LENGTH_LONG).show();
			}
		}

		@Override
		public void onGetNetworkState(int iError) {
			Log.d(TAG, "onGetNetworkState error is " + iError);
			Toast.makeText(MapApplication.getInstance().getApplicationContext(),
					"网络链接错误!", Toast.LENGTH_LONG).show();
		}
		}

	@Override
	//在您app的退出之前调用mapadpi的destroy()函数,避免重复初始化带来的时间消耗
	public void onTerminate() {
		// TODO Auto-generated method stub
	    if (mapManager != null) {
	    	mapManager.destroy();
	    	mapManager = null;
        }
		super.onTerminate();
	}

}

然后不要忘了在Manifest文件中注册:

<application
        android:name=".MapApplication"
        android:allowBackup="true"
        android:icon="@drawable/ic_launcher"
        android:label="@string/app_name"
        android:theme="@style/AppTheme" >

再来编写ShowMapActivity的代码:

package com.liuzhichao.baidumapdemo;

import android.app.Activity;
import android.os.Bundle;

import com.baidu.mapapi.BMapManager;
import com.baidu.mapapi.map.MapController;
import com.baidu.mapapi.map.MapView;
import com.baidu.platform.comapi.basestruct.GeoPoint;

public class ShowMapActivity extends Activity {

	private MapView mMapView;
	private MapController mapController;
	private MapApplication mapApp;
	@Override
	protected void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);

		//请在调用setContentView前一定要先初始化BMapManager对象

		mapApp = MapApplication.getInstance();
		if (mapApp.mapManager==null) {
			mapApp.mapManager = new BMapManager(this);
			mapApp.mapManager.init(MapApplication.BAIDUMAP_KEY, new MapApplication.MyMKGeneralListener());
		}

		setContentView(R.layout.activity_map);

		mMapView = (MapView) findViewById(R.id.bmapsView);

		mMapView.setBuiltInZoomControls(true);// 设置启用内置的缩放控件

		//设置是否打开卫星图
		//mMapView.setSatellite(true);

		//设置是否打开路况图
		//mMapView.setTraffic(true);

		// 设置mapview是否支持双击放大效果
		mMapView.setDoubleClickZooming(true);

		//返回地图的MapController,这个对象可用于控制和驱动平移和缩放。
		mapController = mMapView.getController();
		//设置缩放级别
		mapController.setZoom(12);

		// 在给定的中心点GeoPoint上设置地图视图。
		GeoPoint center = new GeoPoint((int)(39.915* 1E6),(int)(116.404* 1E6));
		mapController.setCenter(center);
	}

	@Override
	protected void onPause() {
		mMapView.onPause();// 当所属的Activity隐藏时调用
		super.onPause();
	}

	@Override
	protected void onResume() {
		mMapView.onResume();
		super.onResume();// 当所属Activity显示时调用
	}

	@Override
	protected void onSaveInstanceState(Bundle outState) {
		super.onSaveInstanceState(outState);
		// 把MapView的状态存储到一个Bundle中。
		mMapView.onSaveInstanceState(outState);

	}

	@Override
	protected void onRestoreInstanceState(Bundle savedInstanceState) {
		super.onRestoreInstanceState(savedInstanceState);
		// 把MapView的状态恢复到一个Bundle。
		mMapView.onRestoreInstanceState(savedInstanceState);
	}

	@Override
	protected void onDestroy() {
		super.onDestroy();
		mMapView.destroy();
	}

}

最后我们在MainActivity中添加菜单导航代码:

package com.liuzhichao.baidumapdemo;

import android.app.ListActivity;
import android.content.Context;
import android.content.Intent;
import android.os.Bundle;
import android.view.View;
import android.widget.AdapterView;
import android.widget.AdapterView.OnItemClickListener;
import android.widget.ArrayAdapter;

public class MainActivity extends ListActivity {

	private Context context;
	 private String[] demos={"1、显示百度地图"};
	@Override
	protected void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		context = this;
		setListAdapter(new ArrayAdapter <String> (this, android.R.layout.simple_list_item_1,demos));

		getListView().setOnItemClickListener(new OnItemClickListener() {

			@Override
			public void onItemClick(AdapterView <?>  parent, View view,
					int position, long id) {
				Intent intent = null;

				switch (position) {
				case 0:
					intent = new Intent(context, ShowMapActivity.class);
					break;

				default:
					break;
				}

				if (intent!=null) {
					startActivity(intent);
				}
			}

		});
	}

}

保存并运行,点击”显示百度地图”则看到显示如下地图,地图中心点是我们给定的天安门。

BaiduMapDemo-basedemo
BaiduMapDemo-basedemo

BaiduMapDemo-basedemo2
BaiduMapDemo-basedemo2

这样就正常的在我们的Activity显示出了百度地图,与之前的SDK最大的不同就是不再需要继承MapActivity。下一讲,我们将在百度地图上显示当前位置。