1.写在前面

项目中需要加上路线规划,导航,添加覆盖物,因为我最开始项目中定位我使用的是百度定位,所以为了省事,接着使用百度地图sdk实现这些。这两天踩了很多百度地图的坑,记下来。因为一些原因,后面会说,需求还没做完,所以效果图很简单,如下。

2.坑1,环境配置

对于百度地图sdk的配置我是无语。因为一开始项目中并没打算使用百度地图其他功能,只是准备定位。所以我下载sdk时只是下载了定位的sdk,如图

现在需要加上地图和导航的sdk(后面才知道导航并不需要下载专门的导航sdk,因为地图sdk可以直接调用百度地图客户端或者网页), 所以我一键自定义时,把他们全下载了(包括定位),如图,因为不管什么功能的sdk中jar包的命名是一样的,都是BaiduLBS_Android.jar,所以我如果只下载地图和导航,里面的jar也是这个名字,这是不行的。

全部下载后,得到的lib是这样的,如图。


发现没,这libs里面的只有一个架构armeabi,这里我就有种不好的预感,因为这里面并没有想定位下载下来的一样,分为很多架构,如图

然后将权限,依赖什么的都配置好,因为前面用了定位,所以key已经好了。一运行,发现刚进app定位一直失败,看了下定位失败的错误码报162,一查发现162:请求串密文解析失败,一般是由于客户端SO文件加载失败造成,请严格参照开发指南或demo开发,放入对应SO文件。

果然 ,然后我为了验证把libs全部删了把前面只有定位的lib试了下,发现定位可以。试了很多办法和搜了很多资料,最后没办法我用了很直白的方法解决了。
解决坑1 我发现单独下载地图或者定位里面的libs都很正常,如图

只有单独下载导航的libs不正常,如图

所以我有准备使用三个功能地图,定位,导航的的jar包,和分别下载三个功能的so文件,手动把他们分到一起去,

最后确实成功了,运行后可以定位,而且三个功能的api都可以使用,但是后面发现调用外部地图其实并不需要导航的sdk,所以这上面操作然并卵,但是如果有人需要使用导航的sdk,那这种思路是可以的。

3.百度地图地理编码

因为后面路线规划时需要终点的位置,我觉得使用经纬度比文字描述好点,所以准备将终点位置转成经纬度,这个比较容易,只要知道得出来的百度坐标系。代码如下

实现OnGetGeoCoderResultListener接口,
GeoCoder mSearch = null;
// 初始化搜索模块,注册事件监听
mSearch = GeoCoder.newInstance();
mSearch.setOnGetGeoCodeResultListener(this);
mSearch.geocode(new GeoCodeOption().city(address).address(address));

这里我发现一个有意思的事,api中GeoCodeOption的参数是设置城市和设置地址,但是其实可以写一个参数,如上面.

前面实现了接口,需要重写的两个方法就是返回的结果,代码如下

  //获取正向编码规则@Overridepublic void onGetGeoCodeResult(GeoCodeResult geoCodeResult) {if (geoCodeResult == null || geoCodeResult.error != SearchResult.ERRORNO.NO_ERROR) {//没有检索到结果Toast.makeText(HomeMenuDetailActivity.this, "没有检索到结果", Toast.LENGTH_SHORT).show();}//获取地理编码结果String strInfo = String.format("纬度:%f 经度:%f",geoCodeResult.getLocation().latitude, geoCodeResult.getLocation().longitude);     }

4.对终点位置的设置

对终点做了几个设置,1进地图希望以终点为中心。2添加覆盖物。3添加泡泡弹框。

地图页面的布局很简单,就是一个mapview,就不贴了。
1.希望进入地图以终点为中心,使用baidumap的这个方法

setMapStatus(MapStatusUpdate update)
改变地图状态

代码很简单,我直接贴代码了

mapView = (MapView) this.findViewById(R.id.bmapView);
baiduMap =  mapView.getMap();
//终点位置对象
LatLng llEnd = new LatLng(latidudeB,longtidudeB);
MapStatus.Builder builder = new MapStatus.Builder();
builder.target(llEnd).zoom(18.0f);      baiduMap.setMapStatus(MapStatusUpdateFactory.newMapStatus(builder.build()));

2.对终点添加覆盖物,就是那个icon,代码比较简单,注释也写了,直接上代码

 //终点覆盖物图标
BitmapDescriptor endMakerIcon = BitmapDescriptorFactory.fromResource(R.mipmap.icon_en);
//终点位置
LatLng llEnd = new LatLng(latidudeB,longtidudeB);
OverlayOptions optionEnd = new MarkerOptions().position(llEnd).icon(endMakerIcon);
//在地图上添加Marker,并显示
baiduMap.addOverlay(optionEnd);              

3.那个泡泡弹窗做的有点失败,因为不是很好看,做的好,应该外面包含一张泡泡图片,百度提供一张,但是不适合,而且也应该把矩形的四个角用shape倒角的,这样好看点。

先看下这个xml布局吧,我写的很奇怪,没用weight,而是用数值定死了,因为我开始使用weight运行出来后很难看,见图。我以为是LayoutInflater加载布局时应该还需要个父ViewGroup,但是不管我是用mapview还是最外层的父布局很不行,所以直接写数值了。

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"android:orientation="horizontal"android:layout_width="wrap_content"android:layout_height="45dp"><LinearLayout
        android:background="@color/white"android:gravity="center_vertical"android:orientation="vertical"android:layout_width="220dp"android:layout_height="match_parent"><TextView
            android:layout_marginTop="5dp"android:id="@+id/tv_mapview_pop_name"android:layout_marginLeft="10dp"android:textSize="15sp"android:textColor="@color/liteblack"android:layout_width="wrap_content"android:layout_height="wrap_content" /><TextView
            android:layout_marginBottom="5dp"android:id="@+id/tv_mapview_pop_address"android:layout_marginLeft="10dp"android:textSize="13sp"android:lines="1"android:ellipsize="end"android:textColor="@color/grey"android:layout_width="wrap_content"android:layout_height="wrap_content" /></LinearLayout><RelativeLayout
        android:id="@+id/rl_mapview_pop_navi"android:gravity="center"android:background="@color/colorPrimary"android:layout_width="80dp"android:layout_height="match_parent"><TextView
            android:textColor="@color/white"android:textSize="14sp"android:text="导航"android:layout_width="wrap_content"android:layout_height="wrap_content" /></RelativeLayout></LinearLayout>


这个信息窗口,百度api提供了方法,见图

这第二个构造方法三个参数,分别是窗口布局,位置,Y轴偏移量。
代码里写了注释如下,

  /*** 终点弹出框泡泡设置*/public void initMapPopView(){//创建InfoWindow展示的viewView popView = LayoutInflater.from(this).inflate(R.layout.mapview_pop,null);TextView tv_mapview_pop_name = (TextView) popView.findViewById(R.id.tv_mapview_pop_name);TextView tv_mapview_pop_address = (TextView) popView.findViewById(R.id.tv_mapview_pop_address);tv_mapview_pop_name.setText(homeMenuSupplierName);  //变量店铺名字tv_mapview_pop_address.setText(homeMenuSupplierAddress);   //变量店铺位置RelativeLayout rl_mapview_pop_navi = (RelativeLayout) popView.findViewById(R.id.rl_mapview_pop_navi);rl_mapview_pop_navi.setOnClickListener(new View.OnClickListener() {@Overridepublic void onClick(View v) {startNavi();Toast.makeText(BDMenuMapActivity.this,"开始导航",Toast.LENGTH_SHORT).show();}});//终点位置LatLng llEnd = new LatLng(latidudeB,longtidudeB);InfoWindow mInfoWindow = new InfoWindow(popView, llEnd, -70);baiduMap.showInfoWindow(mInfoWindow);}

5.发起路线规划搜索(重要)

先把开始步骤写好,实现接口,获取搜索实例,代码如下

implements OnGetRoutePlanResultListener// 搜索相关
RoutePlanSearch mSearch = null;    // 搜索模块,也可去掉地图模块独立使用
// 初始化搜索模块,注册事件监听
mSearch = RoutePlanSearch.newInstance();
//设置路线检索监听者
mSearch.setOnGetRoutePlanResultListener(this);

实现接口后,有几个方法要重写,其实就是发起路线搜索后的结果,

我这代码里只写了驾车路线规划。首先在这个页面,一定是知道起点和终点的位置了,不管是什么样的形式,经纬度,还是一个string字符串描述。
发起驾车路线规划方法,用它反推,需要什么东西。

mSearch.drivingSearch(drivingOption);

需要这个参数,DrivingRoutePlanOption,而这个对象又有如下方法

  DrivingRoutePlanOption    currentCity(java.lang.String cityName)设置当前城市,检索打车信息时必需DrivingRoutePlanOption   from(PlanNode from)设置起点DrivingRoutePlanOptionpassBy(java.util.List<PlanNode> wayPoints)设置途经点DrivingRoutePlanOption policy(DrivingRoutePlanOption.DrivingPolicy policy)设置驾车路线规划策略DrivingRoutePlanOption to(PlanNode to)设置终点DrivingRoutePlanOption trafficPolicy(DrivingRoutePlanOption.DrivingTrafficPolicy trafficPolicy)设置是否支持路况数据

设置起点和终点都涉及到PlanNode对象,它的构造方法有两个

static PlanNode withCityCodeAndPlaceName(int cityCode, java.lang.String placeName)
通过地名和城市名确定出行节点信息
static PlanNode withCityNameAndPlaceName(java.lang.String city, java.lang.String placeName)
通过地名和城市名确定出行节点信息
static PlanNode withLocation(LatLng location)
通过指定经纬度确定出行节点信息

一般两点驾车路线规划可以有几种选择,这里也可以设置

policy(DrivingRoutePlanOption.DrivingPolicy policy)设置驾车路线规划策略ECAR_AVOID_JAM驾车策略: 躲避拥堵ECAR_DIS_FIRST驾乘检索策略常量:最短距离ECAR_FEE_FIRST驾乘检索策略常量:较少费用ECAR_TIME_FIRST驾乘检索策略常量:时间优先

因为我还想获取,驾车需要的时间,千米,设置如下

currentCity(java.lang.String cityName)
设置当前城市,检索打车信息时必需

代码如下

        PlanNode stNode = PlanNode.withLocation(new LatLng(latitudeA,longtidueA));  //起点位置PlanNode enNode = PlanNode.withLocation(new LatLng(latidudeB,longtidudeB));   //终点位置DrivingRoutePlanOption drivingOption = new DrivingRoutePlanOption();drivingOption.from(stNode);//设置起点drivingOption.to(enNode);  //设置终点
drivingOption.currentCity("长沙市");//发起驾车路线规划mSearch.drivingSearch(drivingOption);

在返回的搜索结果中操作,希望路线规划出来后能用覆盖物显示地图上面,这里就有坑2.
坑2
demo中提供了方法设置,如下

 // 定制RouteOverlyprivate class MyDrivingRouteOverlay extends DrivingRouteOverlay {public MyDrivingRouteOverlay(BaiduMap baiduMap) {super(baiduMap);}@Overridepublic BitmapDescriptor getStartMarker() {if (useDefaultIcon) {return BitmapDescriptorFactory.fromResource(R.mipmap.icon_st);}return null;}@Overridepublic BitmapDescriptor getTerminalMarker() {if (useDefaultIcon) {return BitmapDescriptorFactory.fromResource(R.mipmap.icon_en);}return null;}}

但是把方法copy来后DrivingRouteOverlay这个类怎么也找不到,我又不能把demo中的copy过来,万一这里面用了其他的类或者接口呢。所以我用百度搜了下,发现“DrivingRouteOverlay不存在/找不到“都已经成一个词条了。然后发现可以去论坛或者把demo中的一个overlay util包copy到项目中。为什么这个包没放在sdk里面呢,应该百度地图有其他考量吧

所以随便选条路出来,把它显示出来。

route = drivingRouteResult.getRouteLines().get(0);//创建公交路线规划线路覆盖物DrivingRouteOverlay overlay = new MyDrivingRouteOverlay(baiduMap);
//            routeOverlay = overlay;//设置公交路线规划数据overlay.setData((DrivingRouteLine) route);//将公交路线规划覆盖物添加到地图中overlay.addToMap();overlay.zoomToSpan();

坑3,打车信息为null

根据api,这DrivingRouteResult可以获取打车信息的。如图

但其实不管是用

TaxiInfo taxiInfo = drivingRouteResult.getTaxiInfo();
List<TaxiInfo> taxiInfoList =  drivingRouteResult.getTaxiInfos();

都不行,获取对象,对象是null,获取集合也是null。我在论坛搜了下
发现也有人问这种情况,据说是路线搜索时设置参数问题,不用经纬度表示位置,我用这样的参数也试了下还是不行,但是我去百度地图客户端试了下这两个地点,驾车路线有时间个千米显示。前面那个位置是我用百度地图定位获取到的addressstr。我还问了下以前使用百度地图的大佬,也没得到好的结果大佬博客位置

//          PlanNode stNode = PlanNode.withCityNameAndPlaceName("长沙市","中国湖南省长沙市芙蓉区万家丽中路1段-95号");
//          PlanNode enNode = PlanNode.withCityNameAndPlaceName("长沙市", "湖南长沙芙蓉区东郡华城广场A2-1207");

6.启动百度地图导航

这demo中提供很多方法,直接copy就好了,感觉百度地图这demo做的挺好的,很多东西都找得到.。我这里选调百度地图客户端。所以并不需要导航sdk。

 /*** 启动百度地图导航(Native)*/public void startNavi() {LatLng pt1 = new LatLng(latitudeA, longtidueA);LatLng pt2 = new LatLng(latidudeB, longtidudeB);// 构建 导航参数NaviParaOption para = new NaviParaOption().startPoint(pt1).endPoint(pt2).startName("长沙市芙蓉区万家丽中路1段-95号").endName("长沙芙蓉区东郡华城广场A2-1207");try {BaiduMapNavigation.openBaiduMapNavi(para, this);} catch (BaiduMapAppNotSupportNaviException e) {e.printStackTrace();// showDialog();}}

百度地图sdk踩坑之旅相关推荐

  1. vue3 使用百度地图,踩坑日历

    vue中使用百度地图,之前使用的是vue-baidu-map组件,在vue2中引入完全能正常使用,但是引入到vue3项目中,BMap is not defined频繁报错.. 官方地址:Vue Bai ...

  2. android百度地图sdk定位权限,Android:使用百度地图SDK实现定位:下载SDK、申请密钥、动态获得Android权限...

    最近想实现一个打卡的功能,想到可以利用百度地图的SDK.网上有很多关于百度地图SDK定位.地图功能应用的demo,这部分倒不是很困难.但网上很多博客写的内容一般都着重于代码部分,很多下载配置和编译器设 ...

  3. 高德定位SDK踩坑-高精度模式下获取不到GPS定位(无网络环境)

    高德定位SDK踩坑-高精度模式下获取不到GPS定位(无网络环境) 关键字:定位模式 高精度模式 GPS定位 无网络 一句话描述问题:高精度模式在断网环境下不可靠.有几率重复报错或使用缓存定位,不使用G ...

  4. 微信开发踩坑之旅 之 开发准备及服务器配置

    在工作和兴趣的机缘巧合之下,我开始接触微信开发.在这里简单记述自己的微信开发踩坑之旅. 首先,由于本人标准的理工科生,记述的语言有所不足,我尽量说明准确和详细点. 本文记述主线 ·申请公众号 ·公众号 ...

  5. Android google翻译踩坑之旅

    # Android google翻译踩坑之旅   最近由于工作需求,需要为游戏Android平台接入Google翻译的SDK,由于关于翻译的文章非常少,访问官方文档又需要翻墙,更可气的是找到的博客写了 ...

  6. Android百度地图——SDK版本v2.0.0初探

    大过年的,没回家.听着外面烟花爆竹声阵阵,大冷天的一个人也不想出去转.城市不管多么繁华,一个人都是感觉"无味".最近在研究百度地图的API使用,在使用过程中遇到些问题,有些心得吧, ...

  7. 百度地图sdk sha1秘钥获取有种想吐的赶脚

    撸代码坐的腰算背疼还只是弄一个不是项目里边需要的升级版本的so 日 需要sha1 指纹秘钥,还有项目包, 才能用百度地图sdk 这个找sha1  获取废了20分钟, 显示全盘找keytool.exe ...

  8. H5使用百度地图SDK获取用户当前位置并且标记显示在地图

    代码实现功能: H5使用百度地图SDK获取用户当前位置并且标记显示在地图,点击该标记弹出一层自定义的HTML. 效果图: 代码: <!DOCTYPE html> <html>& ...

  9. 公司考勤模块集成百度地图SDK

    百度地图SDK开发者网站: lbsyun.baidu.com/index.php?t- 一 申请密钥(安全码):需要 项目名称和bundle ID 网址:lbsyun.baidu.com/apicon ...

最新文章

  1. 漫画:Object 类很大,你忍一下(完结篇)
  2. C 入门 第八节 指针
  3. 如何用PHP写商品折扣_秒杀抢购时的超发,你用php如何优化的
  4. Property ‘configuration‘ and ‘configLocation‘ can not specified with together
  5. window10最全win键组合技巧(win10快捷键)
  6. java 弹出下载_java如何实现下载弹出的对话框
  7. Linux lvs 多端口组成
  8. 堆(概念,数据结构中堆与内存堆区的区别 ,堆的基本操作)
  9. mysql数据库开发环境_MacOS下搭载开发环境之数据库篇(Mysql + Navicat)
  10. Java中的IO流(六)
  11. 设计自己的高并发架构
  12. 推荐系统和搜索引擎的关系
  13. Python 字典(Dictionary) values()
  14. 容器技术Docker K8s 35 容器服务ACK基础与进阶-应用与发布管理
  15. 自己在inode客户端的大量问题(不断更新中)(2012-02-23 21:24 )
  16. ABB机器人伺服电机维修故障
  17. ImportError: DLL load failed while importing ie_api
  18. sentinel实现限流、降级、熔断配置和测试使用
  19. 理解Celery的worker
  20. linux运维排查常用命令(开发专享)

热门文章

  1. Python中的文件处理
  2. 实验五——手工编写PE文件
  3. 【开源系列】三国演义LBS (三)源码:基础库
  4. python-双色球
  5. Power Designer:如何在输入name的时候,让code不跟着变
  6. 语义智能的方法体系及其在金融领域的应用实践
  7. C语言之前的A、B语言又是什么?(计算机语言发展史)
  8. 安装matlab2021b之后电脑启动变慢matlab启动很慢以及初始化时间过长
  9. EBS业务学习之库存管理
  10. android jni gbk,Android之NDK编码转(UTF8-GBK)