百度地图
显示地图
- 申请API Key, 并放入清单文件
<meta-data android:name="com.baidu.lbsapi.API_KEY" android:value="3zajzkwwhq4leyIWkleneoyN" />
- 添加权限
<!-- 这个权限用于进行网络定位--> <uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION"></uses-permission> <!-- 这个权限用于访问GPS定位--> <uses-permission android:name="android.permission.ACCESS_FINE_LOCATION"></uses-permission> <!-- 用于访问wifi网络信息,wifi信息会用于进行网络定位--> <uses-permission android:name="android.permission.ACCESS_WIFI_STATE"></uses-permission> <!-- 获取运营商信息,用于支持提供运营商信息相关的接口--> <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE"></uses-permission> <!-- 这个权限用于获取wifi的获取权限,wifi信息会用来进行网络定位--> <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" /> <!-- SD卡读取权限,用户写入离线定位数据--> <uses-permission android:name="android.permission.MOUNT_UNMOUNT_FILESYSTEMS"></uses-permission> <!-- 允许应用读取低级别的系统日志文件 --> <uses-permission android:name="android.permission.READ_LOGS"></uses-permission>
-
初始化SDK, 并接收结果通知
private void initSDK() { SDKInitializer.initialize(getApplicationContext()); IntentFilter filter = new IntentFilter(); // 网络错误 filter.addAction(SDKInitializer.SDK_BROADCAST_ACTION_STRING_NETWORK_ERROR); // 权限异常 filter.addAction(SDKInitializer.SDK_BROADTCAST_ACTION_STRING_PERMISSION_CHECK_ERROR); receiver = new MyBroadcastReceiver(); registerReceiver(receiver, filter); } class MyBroadcastReceiver extends BroadcastReceiver { @Override public void onReceive(Context context, Intent intent) { if (SDKInitializer.SDK_BROADCAST_ACTION_STRING_NETWORK_ERROR .equals(intent.getAction())) { Toast.makeText(BaseActivity.this, "网络异常", Toast.LENGTH_SHORT).show(); } if (SDKInitializer.SDK_BROADTCAST_ACTION_STRING_PERMISSION_CHECK_ERROR .equals(intent.getAction())) { Toast.makeText(BaseActivity.this, "Key验证异常", Toast.LENGTH_SHORT).show(); } } }
-
实现生命周期方法
@Override protected void onResume() { mapView.onResume(); super.onResume(); } @Override protected void onPause() { mapView.onPause(); super.onPause(); } @Override protected void onDestroy() { mapView.onDestroy(); // 反注册广播接收者 unregisterReceiver(receiver); super.onDestroy(); }
-
初始化地图
private void initMap() { // 得到地图控件 mapView = (MapView) findViewById(R.id.mapView); // 得到地图控制器 mapControl = mapView.getMap(); // 更改中心点 MapStatusUpdate update1 = MapStatusUpdateFactory.newLatLng(new LatLng(34.196421, 108.868445)); mapControl.animateMapStatus(update1); // 更改缩放级别, 缩放级别取值范围: 3 - 19 MapStatusUpdate update2 = MapStatusUpdateFactory.zoomTo(16); mapControl.animateMapStatus(update2); }
图层控制
- 添加选项菜单
@Override public boolean onCreateOptionsMenu(Menu menu) { menu.add(1, 1, 1, "显示普通图层"); menu.add(1, 2, 2, "显示卫星图"); menu.add(1, 3, 3, "显示/关闭交通图"); return super.onCreateOptionsMenu(menu); }
-
更改底图
图层类似于一叠扑克牌
最下层是一个底图, 底图有两种类型- 普通地图
- 卫星图
在这之上可以有其它图层, 类似交通图, 热力图
super.mapControl.setMapType(BaiduMap.MAP_TYPE_NORMAL); super.mapControl.setMapType(BaiduMap.MAP_TYPE_SATELLITE);
- 添加交通图
@Override public boolean onOptionsItemSelected(MenuItem item) { switch (item.getItemId()) { case 1: super.mapControl.setMapType(BaiduMap.MAP_TYPE_NORMAL); break; case 2: super.mapControl.setMapType(BaiduMap.MAP_TYPE_SATELLITE); break; case 3: super.mapControl.setTrafficEnabled(!isShowTraffic); isShowTraffic = !isShowTraffic; break; } return super.onOptionsItemSelected(item); }
圆形覆盖物
- 创建覆盖物
CircleOptions options = new CircleOptions();
- 设置覆盖物内容
// 设置位置 options.center(new LatLng(34.196421, 108.868445)); // 设置半径, 单位: 米 options.radius(100); // 填充颜色 options.fillColor(Color.TRANSPARENT); // 设置圆边样式, 参数一: 边的宽度, 参数二: 边的颜色 options.stroke(new Stroke(2, Color.BLUE));
- 添加到界面上
mapControl.addOverlay(options);
文字覆盖物
- 创建覆盖物
TextOptions textOptions = new TextOptions();
- 设置覆盖物内容
// 设置文字 textOptions.text("西安传智"); // 设置字体大小, 单位 px textOptions.fontSize(100); // 设置字体颜色 textOptions.fontColor(Color.BLUE); // 设置覆盖物位置 textOptions.position(new LatLng(34.196421, 108.868445));
- 添加到界面上
mapControl.addOverlay(textOptions);
图形覆盖物
- 创建覆盖物
MarkerOptions options = new MarkerOptions();
-
设置覆盖物内容
// 设置Overlay的标题 options.title("产品狗"); // 设置位置 options.position(new LatLng(34.196421, 108.868445)); // 创建对应的BitmapDescripter数组 ArrayList<BitmapDescriptor> bitmaps = new ArrayList<BitmapDescriptor>(); bitmaps.add(BitmapDescriptorFactory.fromResource(R.drawable.eat_icon)); bitmaps.add(BitmapDescriptorFactory.fromResource(R.drawable.icon_geo)); // 给Overlay设置图片数组, 如果有一组图片的话, 可以通过period来控制刷新速度 options.icons(bitmaps); options.period(30); // 设置Options可以拖动 options.draggable(true);
- 添加到界面上
mapControl.addOverlay(options);
点击Marker的时候显示弹框
-
初始化弹框, 加入控件中, 并设置隐藏, 这样的做法是为了加快速度, 节省资源
private void initPopView() { // 创建出来PopView popView = getLayoutInflater().inflate(R.layout.pop, null); popView.setVisibility(View.INVISIBLE); // 得到文字对应的TextView tv_title = (TextView) popView.findViewById(R.id.title); // 创建MapView中的子View的描述类 MapViewLayoutParams params = new MapViewLayoutParams.Builder() .width(MapViewLayoutParams.WRAP_CONTENT) .height(MapViewLayoutParams.WRAP_CONTENT) .layoutMode(ELayoutMode.absoluteMode) .point(new Point(100, 100)) .build(); // 加入到界面 mapView.addView(popView, params); }
- 给MarkerOverlay设置点击事件
// 设置marker的点击事件 mapControl.setOnMarkerClickListener(new OnMarkerClickListener() { /** * marker: markeroverlay的属性 */ @Override public boolean onMarkerClick(Marker marker) { showPopView(marker.getTitle(), marker.getPosition()); return false; } });
-
在点击事件的时候显示出来弹框, 并更新弹框位置
private void showPopView(String title, LatLng position) { popView.setVisibility(View.VISIBLE); tv_title.setText(title); // 创建MapView中的子View的描述类 MapViewLayoutParams params = new MapViewLayoutParams.Builder() .width(MapViewLayoutParams.WRAP_CONTENT) .height(MapViewLayoutParams.WRAP_CONTENT) .layoutMode(ELayoutMode.mapMode) .position(position) .build(); // 加入到界面 mapView.updateViewLayout(popView, params); }
POI搜索
- 通过
PoiSearch
开始搜索- 通过
PoiBoundSearchOption
传递矩形范围搜索的参数- 通过
PoiNearbySearchOption
传递圆形搜索的参数- 通过
PoiCitySearchOption
传递城市搜索的参数
矩形搜索
-
创建用于矩形搜索的参数
// 新建搜索选项 PoiBoundSearchOption searchOption = new PoiBoundSearchOption(); searchOption.keyword("酒店"); // 拼装范围 LatLngBounds bounds = new LatLngBounds.Builder() .include(new LatLng(34.196421 - 0.011, 108.868445 - 0.011)) .include(new LatLng(34.196421 + 0.011, 108.868445 + 0.011)) .build(); searchOption.bound(bounds);
-
创建Poi搜索入口, 并将参数传入开始检索
// 新建搜索类 PoiSearch search = PoiSearch.newInstance(); // 开始搜索 search.searchInBound(searchOption);
-
创建搜索结果监听, 并设置给Poi搜索入口
// 由于是一个异步的过程, 所以需要通过回调接口来接受相关参数 search.setOnGetPoiSearchResultListener(this); /** * 当Poi详情搜索完成的时候调用此方法, 传入详情搜索的结果集 * @param result 详情结果集 */ @Override public void onGetPoiDetailResult(PoiDetailResult result) { } /** * 当Poi搜索完成的时候调用此方法, 传入Poi搜索的结果集 * @param result poi搜索的结果集 */ @Override public void onGetPoiResult(PoiResult result) { // 创建用于展示Poi搜索结果集的覆盖物 PoiOverlay overlay = new PoiOverlay(mapController); overlay.setData(result); overlay.addToMap(); overlay.zoomToSpan(); }
路线搜索
类似于Poi搜索, 路线搜索页是几乎相同的构造方式
主要有:
RoutePlanSearch
是搜索的入口DrivingRoutePlanOption
保存驾车搜索的参数WalkingRoutePlanOption
保存步行搜索的参数TransitRoutePlanOption
保存公交换乘的参数
驾车搜索
- 创建搜索参数类, 创建相应的参数
//发起请求 DrivingRoutePlanOption drivingPlanOptoin = new DrivingRoutePlanOption(); // 起点 drivingPlanOptoin.from(PlanNode.withLocation(new LatLng(34.798413, 113.551107))); // 终点 drivingPlanOptoin.to(PlanNode.withLocation(new LatLng(34.813292 ,113.552154))); // 策略 drivingPlanOptoin.policy(DrivingRoutePlanOption.DrivingPolicy.ECAR_TIME_FIRST);
-
创建搜索入口, 并传入参数, 开启搜索
//搜索核心类 RoutePlanSearch routePlanSearch = RoutePlanSearch.newInstance(); routePlanSearch.drivingSearch(drivingPlanOptoin);
-
创建监听并注册, 获取搜索结果
//设置监听 routePlanSearch.setOnGetRoutePlanResultListener(new MyOnGetRoutePlanResultListener()); class MyOnGetRoutePlanResultListener implements OnGetRoutePlanResultListener{ @Override public void onGetDrivingRouteResult(DrivingRouteResult drivingRouteResult) { //展示驾车路线 DrivingRouteOverlay drivingRouteOverlay = new DrivingRouteOverlay(mapController); drivingRouteOverlay.setData(drivingRouteResult.getRouteLines().get(0));//结果中有多种路线选择,直接选择第一种即可 drivingRouteOverlay.addToMap(); drivingRouteOverlay.zoomToSpan(); } @Override public void onGetTransitRouteResult(TransitRouteResult transitRouteResult) { } @Override public void onGetWalkingRouteResult(WalkingRouteResult walkingRouteResult) { } }
定位
- 注册百度定位所需要的服务器
<service android:name="com.baidu.location.f" android:enabled="true" android:process=":remote"/>
-
创建定位所需要的一些主类
mLocationClient = new LocationClient(getApplicationContext()); initLocaion();
-
创建监听并注册, 获取定位成功的结果
mLocationClient.registerLocationListener( myListener ); //注册监听函数 public class MyLocationListener implements BDLocationListener { @Override public void onReceiveLocation(BDLocation location) { mapController.setMyLocationData(new MyLocationData.Builder() .latitude(location.getLatitude()) .longitude(location.getLongitude()) .build()); } }
-
对定位进行设置, 模板代码
LocationClientOption option = new LocationClientOption(); option.setLocationMode(LocationMode.Hight_Accuracy);//可选,默认高精度,设置定位模式,高精度,低功耗,仅设备 option.setCoorType("bd09ll");//可选,默认gcj02,设置返回的定位结果坐标系 int span=1000; option.setScanSpan(span);//可选,默认0,即仅定位一次,设置发起定位请求的间隔需要大于等于1000ms才是有效的 option.setIsNeedAddress(true);//可选,设置是否需要地址信息,默认不需要 option.setOpenGps(true);//可选,默认false,设置是否使用gps option.setLocationNotify(true);//可选,默认false,设置是否当gps有效时按照1S1次频率输出GPS结果 option.setIgnoreKillProcess(false);//可选,默认false,定位SDK内部是一个SERVICE,并放到了独立进程,设置是否在stop的时候杀死这个进程,默认杀死 option.SetIgnoreCacheException(false);//可选,默认false,设置是否收集CRASH信息,默认收集 mLocationClient.setLocOption(option); mapController.setMyLocationEnabled(true);
-
在Activity开启的时候开启定位, 在Activity结束的时候结束定位
@Override protected void onStart() { mLocationClient.start(); super.onStart(); } @Override protected void onStop() { mLocationClient.stop(); super.onStop(); }