1.准备工作:
1.1在
http://developer.baidu.com/map/android-
mobile-apply-key.htm申请key,前提是要有百度开发者账号,这里已经申请了一个秘钥:
6563200A658F689A0E72C67AD26E1E8F51FBC488
1.2将地图开发的jar包导入到工程目录下的libs目录下
2.增加权限:
<!-- gps权限 -->
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION"/>
<!-- wifi权限 -->
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE"/>
<uses-permission android:name="android.permission.ACCESS_WIFI_STATE"/>
<uses-permission android:name="android.permission.CHANGE_WIFI_STATE"/>
<!-- 网络权限 -->
<uses-permission android:name="android.permission.INTERNET"/>
<!-- 写SD权限 -->
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
<!-- 获取手机信息的权限 -->
<uses-permission android:name="android.permission.READ_PHONE_STATE"/>
<!-- gps定位需要的权限 -->
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION"></uses-permission>
<uses-permission android:name="android.permission.ACCESS_WIFI_STATE"></uses-permission>
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE"></uses-permission>
<uses-permission android:name="android.permission.CHANGE_WIFI_STATE"></uses-permission>
<uses-permission android:name="android.permission.READ_PHONE_STATE"></uses-permission>
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"></uses-permission>
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.MOUNT_UNMOUNT_FILESYSTEMS"></uses-permission>
<uses-permission android:name="android.permission.READ_LOGS"></uses-permission>
3.地图入门三大类:
3.1 MapView:
该类是继承自VIewGroup的自定义控件,它可以显示地图的详细信息并且可以出发点击事件和触摸手 势去实现地图的动画和拖放动作。
3.2 BMapManager:
该类是地图引擎管理类,它可以控制MapView的生命周期,init(),start(),stop(),destory();对应着Activity 中相应的生命周期方法,在使用MapView显示地图之前需要调用init(key,listener)去验证key是
否
确,
回调
结果在listener中处理,并且必须要地图MapView实例化之前调用。代码如下:
/**
* 获取权限失败的回调
*/
@Override
public void onGetPermissionState(int iError)
{
if (MKEvent.ERROR_PERMISSION_DENIED == iError)
{
Log.e(ERROR, "获取权限失败!");
}
}
/**
* 获取网络连接失败的回调
*/
@Override
public void onGetNetworkState(int iError)
{
if (MKEvent.ERROR_NETWORK_CONNECT == iError)
{
Log.e(ERROR, "获取网络连接失败!");
}
}
若是key验证失败的话是不能显示地图的。
3.3 MapController:
该类是地图控制类,主要是控制MapView的平移,旋转,手势识别,缩放大小和俯视角度。
4.地图开发加强:
4.1 Overlay:
图层类,该类是一个抽象类,我们在使用的时候得使用它的六大子类进行图层的使用。
分别是:
TextOverlay :
文本图层,根据经纬度显示在MapView中
Graphics:
图形图层显示,
根据经纬度显示在MapView中
Popun
Overlay:
PopView 自定义的view图层显示,
根据经纬度显示在MapView中
Itemized
Overlay:
多条目图层,
根据经纬度显示在MapView中
PoiOverlay:
点图层,图标是系统默认的图标
MyLocationOverlay:基于gps定位后在MapView中显示的位置图层,图标也是系统默认的图标
用法:
所有的图层显示都是如下四个不走:
1. 创建图层想要显示的东西,如文本,图形或者OverlayItem
2. 创建图层,就是上面的六个类实例,然后将步奏1的图层数据加入其中
3. 再见图层加入到MapView中
4.最后调用MapView的refresh()方法进行地图的刷新即可
4.2 MKSearch:地图信息搜索类,可以
位置检索、周边检索、范围检索、公交检索、驾乘检索、步行检 索,功能强大。
4.3 MKSearchListener: 地图搜索回调监听器,用于在搜索之后回调的处理,主要是显示图层在MapView
5.功能代码实现:
5.1 图片图层实现:
//1.创建图形实例
//准备数据---图形(点,线,面)
Geometry geometry = new Geometry();
//图形为圆形,mPt为坐标,100表示图形的半径
geometry.setCircle(mPt, 100);
//准备数据---图形样式(点,线,面)
Symbol symbol = new Symbol();
Symbol.Color color = new Symbol().new Color();
color.alpha = 0x33;
color.blue = 0x00;
color.green = 0x00;
color.red = 0xff;
symbol.setSurface(color, 1, 1);
//图片的参数,图形与央视
Graphic graphic = new Graphic(geometry, symbol);
//2.创建OverLay
GraphicsOverlay graphicsOverlay = new GraphicsOverlay(mMapView);
graphicsOverlay.getAllGraphics().add(graphic);
//3.将overlay添加到MapView中
mMapView.getOverlays().add(graphicsOverlay);
//4.刷新
mMapView.refresh();
5.2 多图层显示:
mPopView = View.inflate(this, R.layout.item_popup, null);
mTitleText = (TextView) mPopView.findViewById(R.id.title);
LayoutParams params = new LayoutParams(LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT, new GeoPoint(0, 0), LayoutParams.BOTTOM_CENTER);
mMapView.addView(mPopView, params);
mPopView.setVisibility(View.INVISIBLE);
// 2.将图层数据加入到OverLay中
ItemizedOverlay<OverlayItem> itemizedOverlay = new ItemizedOverlay<OverlayItem>(getResources().getDrawable(R.drawable.eat_icon), mMapView) {
// 当点击图层的时候调用的方法,显示Pop窗口
@Override
protected boolean onTap(int location)
{
// 获取点击条目的数据
OverlayItem overlayItem = overlayItems.get(location);
GeoPoint geoPoint = overlayItem.getPoint();
// 设置POP窗口的位置,并设置可见
LayoutParams params = new LayoutParams(LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT, geoPoint, LayoutParams.BOTTOM_CENTER);
mMapView.updateViewLayout(mPopView, params);
mPopView.setVisibility(View.VISIBLE);
mTitleText.setText(overlayItem.getTitle());
return super.onTap(location);
}
};
itemizedOverlay.addItem(overlayItems);
// 3.将图层Overlay加入到MapView中
mMapView.getOverlays().add(itemizedOverlay);
// 4.刷新MapView
mMapView.refresh();
5.3 半径搜索:
MKSearchListener listener = new MKSearchAdapter() {/**
* 重写搜索成功后返回的方法
*/
@Override
public void onGetPoiResult(MKPoiResult result, int type, int iError)
{
// 1.1.数据
ArrayList<MKPoiInfo> allPois = null;
if (result != null && iError == 0)
{// 有数据查询结果
allPois = result.getAllPoi();
}
// 1.2.Overlay,添加数据
PoiOverlay overlay = new PoiOverlay(SearchNearByActivity.this, mMapView);
overlay.setData(allPois);
// 1.3.先清除之前的数据在添加数据
mMapView.getOverlays().clear();
mMapView.getOverlays().add(overlay);
// 1.4.刷新数据
mMapView.refresh();
super.onGetPoiResult(result, type, iError);
}
};
// 2.初始化搜索引擎
mSearch.init(mMapManager, listener);
// 3.发起检索,电影院为检索关键词,CTBU为圆心坐标,50000为半径
mSearch.poiSearchNearBy("电影院", mPt, 5000);
5.4 矩形搜索:
//1.初始化搜索监听器
MKSearchListener search = new MKSearchAdapter(){
@Override
public void onGetPoiResult(MKPoiResult result, int type, int iError)
{
//1.1 获取搜索的数据
ArrayList<MKPoiInfo> allPoi = null;
if(result != null && iError ==0){
allPoi = result.getAllPoi();
}
//1.2 创建图层
PoiOverlay overlay = new PoiOverlay(SearchInboundsActivity.this, mMapView);
overlay.setData(allPoi);
//1.3 将图层加入MapView
mMapView.getOverlays().clear();
mMapView.getOverlays().add(overlay);
//1.4 刷新
mMapView.refresh();
super.onGetPoiResult(result, type, iError);
}
};
//2.初始化搜索引擎
mSearch.init(mMapManager, search);
//3.开始检索
mSearch.poiSearchInbounds("加油站", new GeoPoint((int)mLatitutde - 10000, (int)mLongtitutde - 10000),
new GeoPoint((int)mLatitutde + 10000, (int)mLongtitutde +10000));
5.5 驾驶检索:
// 1,设置初始监听,处理回调结果
mSearch.init(mMapManager, new MKSearchAdapter() {
@Override
public void onGetDrivingRouteResult(MKDrivingRouteResult result,int iError)
{
// 处理返回结果
// 判断
if (result == null || iError != 0) {
return;
}
// 1 数据
MKRoutePlan data = result.getPlan(0);
// 2 Overlay 加数据
RouteOverlay overlay = new RouteOverlay(DrivingSearchActivity.this, mMapView);
overlay.setData(data.getRoute(0));
// 3 mv加overlay
mMapView.getOverlays().add(overlay);
// 4 刷新
mMapView.refresh();
}
});
//起点
MKPlanNode start = new MKPlanNode();
start.pt = mPt;
//重点
MKPlanNode end = new MKPlanNode();
end.name = "xxx";
//中途经过的地方
ArrayList<MKWpNode> wpNodes = new ArrayList<MKWpNode>();
{
MKWpNode node = new MKWpNode();
node.name = "xxx";
wpNodes.add(node);
}
{
MKWpNode node = new MKWpNode();
node.name = "xxx";
wpNodes.add(node);
}
mSearch.setDrivingPolicy(MKSearch.ECAR_FEE_FIRST);
mSearch.drivingSearch("xxx", start, "xxx", end, wpNodes);
5.6 步行检索
// 1,设置监听
mSearch.init(mMapManager, new MKSearchAdapter() {
@Override
public void onGetWalkingRouteResult(MKWalkingRouteResult result, int iError)
{
// 1,数据
MKRoutePlan plan = result.getPlan(0);
// 2,overlay
RouteOverlay overlay = new RouteOverlay(WalkingSearchActivity.this, mMapView);
overlay.setData(plan.getRoute(0));
// 3,添加
mMapView.getOverlays().add(overlay);
// 4,刷新
mMapView.refresh();
super.onGetWalkingRouteResult(result, iError);
}
});
// 2,发起请求
/*
* public int walkingSearch(String startCity, MKPlanNode start, String
* endCity, MKPlanNode end) 步行路线搜索.
* 异步函数,返回结果在MKSearchListener里的onGetWalkingRouteResult方法通知
*
*
* 参数:startCity - 起点所在城市,起点为坐标时可不填start - 搜索的起点,可以为坐标,名称任一种endCity -
* 终点所在城市,终点为坐标时可不填end - 搜索的终点,可以为坐标,名称任一种
*/
MKPlanNode start = new MKPlanNode();
start.pt = mPt;
MKPlanNode end = new MKPlanNode();
end.name = "重庆工商大学";
mSearch.walkingSearch("重庆", start, "重庆", end);
5.7 交通检索:
// 1.设置监听回调
mSearch.init(mMapManager, new MKSearchAdapter() {
@Override
public void onGetTransitRouteResult(MKTransitRouteResult result,
int iError) {
//1.数据
MKTransitRoutePlan plan = result.getPlan(0);
//2.Overlay
TransitOverlay overlay = new TransitOverlay(TransitSearchActivity.this, mMapView);
overlay.setData(plan);
//3.加 overlay
mMapView.getOverlays().add(overlay);
//4.刷新
mMapView.refresh();
super.onGetTransitRouteResult(result, iError);
}
});
// 2,发起检索请求
/**
* public int transitSearch(String city, MKPlanNode start, MKPlanNode
* end) 公交路线搜索. 异步函数,返回结果在MKSearchListener里的onGetTransitRouteResult方法通知
*
*
* 参数:city - 城市名,用于在哪个城市内进行检索(必须填写)start - 检索的起点,可通过关键字,坐标,两种方式指定end -
* 检索的终点,可通过关键字,坐标,两种方式指定
*/
//起点与终点
MKPlanNode start = new MKPlanNode();
start.pt = mPt;
MKPlanNode end = new MKPlanNode();
end.name = "xxx";
//设置不需要地铁
mSearch.setTransitPolicy(MKSearch.EBUS_NO_SUBWAY);
mSearch.transitSearch("xxx", start, end);
5.8 GPS定位,这是一个新的功能,需要在清单文件这次一个服务
<
service android:name="com.baidu.location.f" android:enabled="true" android:process=":remote"
></
service
>
然后在代码中主要
LocationClient和
BDLocationListener两个类,并且开GPS最好是和Activity生命周期一直,在Activity销毁的时候也要停止GPS服务,因为GPS定位是非常耗电的
//客户端的地理位置
public LocationClient mLocationClient = null;
/**
* 初始化地理位置的监听器
*/
public BDLocationListener myListener = new BDLocationListener() {
/**
* 获取定位信息成功后回调的方法
*/
@Override
public void onReceiveLocation(BDLocation location) {
// 1.location 定位的信息 数据,经度和纬度
double latitude = location.getLatitude();
double longitude = location.getLongitude();
// 2.创建overlay
MyLocationOverlay overlay = new MyLocationOverlay(mMapView);
LocationData data = new LocationData();
data.latitude = latitude;
data.longitude = longitude;
overlay.setData(data);
// 3.add
mMapView.getOverlays().add(overlay);
// 4.刷新
mMapView.refresh();
GeoPoint point = new GeoPoint((int) (latitude * 1E6),(int) (longitude * 1E6));
// 5.随时移动该位置
mMapController.animateTo(point);// 移动地图的中心点
}
@Override
public void onReceivePoi(BDLocation arg0) {
}
};
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
initGps();
}
/**
* 初始化地理位置
*/
private void initGps() {
//1.声明LocationClient类
mLocationClient = new LocationClient(getApplicationContext());
//2.注册监听函数
mLocationClient.registerLocationListener(myListener);
//3.创建位置客户端选项
LocationClientOption option = new LocationClientOption();
option.setOpenGps(true);
option.setAddrType("all");// 返回的定位结果包含地址信息
option.setCoorType("bd09ll");// 返回的定位结果是百度经纬度,默认值gcj02
option.setScanSpan(5000);// 设置发起定位请求的间隔时间为5000ms
option.disableCache(true);// 禁止启用缓存定位
option.setPoiNumber(5); // 最多返回POI个数
option.setPoiDistance(1000); // poi查询距离
option.setPoiExtraInfo(true); // 是否需要POI的电话和地址等详细信息
mLocationClient.setLocOption(option);
mLocationClient.requestLocation();//发起定位请求
}
@Override
protected void onDestroy() {
// TODO Auto-generated method stub
mLocationClient.stop();
super.onDestroy();
}
@Override
protected void onPause() {
// TODO Auto-generated method stub
mLocationClient.stop();
super.onPause();
}
@Override
protected void onStart() {
// TODO Auto-generated method stub
mLocationClient.start();
super.onStart();
}
6.总结:
6.1
六大类:MapView,BMapManager,MapController,Overlay,MKSearch,MKSearchListener.。
6.2
注意MapView和Activity的生命周期对应,防止多次去加载MapView,避免界面混乱。
6.3 注意GPS定位的生命周期也要和Activity对应在一起,因为GPS是非常耗电的。
6.4 每一次搜索的时候都可以设置经纬度,封装经纬度的类是GeoPoint。