高德地图之实时导航

您所在的位置:网站首页 高德导航使用方法 高德地图之实时导航

高德地图之实时导航

2024-07-15 15:07| 来源: 网络整理| 查看: 265

之前的文章总结了高德地图之拾取地点,接着在这个基础上继续总结了高德地图之路线规划,今天我们将在这个基础上来总结高德地图之实时导航。之前的文章如果没有看过的话,建议大家先了解一下,不然可能会看得不大懂。 其实实时导航相对来说应该是最简单的,但是API讲的不是很清楚,于是我将自己的弯路一一道来,让大家看看有没有什么收获。首先,我们按照官网API的说法来走一遍,简单来说就四步:

定义AMapNaviView实现 简单来说就是声明一个控件,这个控件和前文的地图不是一个包了,代码如下:AMapNaviView 的生命周期 无非就是维护生命周期,并且同路线规划一样实现导航视图事件监听接口——AMapNaviViewListener,代码如下:进行路线规划 这里就一句话“具体参考:驾车路径规划或步行路径规划。”也就是说我们直接使用上文的路线规划就好了。这里有一个大坑,后文会提到。开启导航 这个最简单,就是在第二步实现接口的时候,重写 onCalculateRouteSuccess()函数即可。 定义AMapNaviView实现 AMapNaviView 的生命周期 protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); //获取 AMapNaviView 实例 mAMapNaviView = (AMapNaviView) findViewById(R.id.navi_view); mAMapNaviView.setAMapNaviViewListener(this); } @Override protected void onResume() { super.onResume(); mAMapNaviView.onResume(); } @Override protected void onPause() { super.onPause(); mAMapNaviView.onPause(); } @Override protected void onDestroy() { super.onDestroy(); mAMapNaviView.onDestroy(); } 开启导航 @Override public void onCalculateRouteSuccess() { super.onCalculateRouteSuccess(); mAMapNavi.startNavi(NaviType.GPS); }

上面提到这里有一个bug,就是说当我们有多条线路的时候,我们怎么指定线路呢?而且就算只有一条线路,这里也不能实现导航。这个时候实时导航如下:

这里写图片描述

当时我很奇怪,因为demo里并没有发现路线规划的Activity是如何将路线,以及起点、终点传到实时导航的Activity,后来我发现在路线规划Activity的时候有一个亮点:

mAMapNavi = AMapNavi.getInstance(getApplicationContext());

导航对外控制类对象mAMapNavi其实是一个单例,我们看看实时导航里面是怎样获取这个对象的?

//实时导航获取AMapNavi实例 mAMapNavi = AMapNavi.getInstance(this); //demo中获取AMapNavi实例 //com.amap.navi.demo.activity.RouteNaviActivity mAMapNavi = AMapNavi.getInstance(getApplicationContext());

虽然我们传入了不同的Context对象,但是其实效果都一样,我们看看AMapNavi源码中getInstance(Context var0)是怎么实现单例的?

public static synchronized AMapNavi getInstance(Context var0) { try { if(singletonAMapNavi == null) { singletonAMapNavi = new AMapNavi(var0); } } catch (Throwable var2) { du.a(var2); ey.b(var2, "AMapNavi", "getInstance(Context context)"); } return singletonAMapNavi; }

解决了起点、终点的传递,但是线路好像还没有解决指定线路的值!这个值其实也是在路线规划Activity中我们已实现了,看看当多条线路的时候我们点击其中一条线路的事件监听,代码如下:

holder.getView(ll_itemview).setOnClickListener(new View.OnClickListener() { @Override public void onClick(View view) { currentPosition = position; //已经选中,再次选中直接返回 if(lastPosition==currentPosition){ return; }else{ //当前的下标值赋值给当前选择的线路下标值 routeIndex = position; //更换线路 changeRoute(); //选择Item设置背景 selectedBackground(holder); //清空上次设置的背景 cleanSelector(); } lastPosition = position; } }); /** * 选择路线 */ public void changeRoute() { //计算出来的路径只有一条 if (routeOverlays.size() == 1) { //必须告诉AMapNavi 你最后选择的哪条路 mAMapNavi.selectRouteId(routeOverlays.keyAt(0)); return; } if (routeIndex >= routeOverlays.size()) routeIndex = 0; //根据选中的路线下标值得到路线ID int routeID = routeOverlays.keyAt(routeIndex); //突出选择的那条路 for (int i = 0; i < routeOverlays.size(); i++) { int key = routeOverlays.keyAt(i); routeOverlays.get(key).setTransparency(0.4f); } routeOverlays.get(routeID).setTransparency(1); /**把用户选择的那条路的权值弄高,使路线高亮显示的同时,重合路段不会变的透明**/ routeOverlays.get(routeID).setZindex(zindex++); //必须告诉AMapNavi 你最后选择的哪条路 mAMapNavi.selectRouteId(routeID); routeIndex++; }

我们看到上面代码中的mAMapNavi.selectRouteId(int id)方法就设置过了,所以我们在实时导航里面,已经不用再次规划路线,可以直接启动导航,这里我们直接看onCreate(Bundle savedInstanceState) 方法的源码就好:

@Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); requestWindowFeature(Window.FEATURE_NO_TITLE); ActionBar actionbar = getSupportActionBar(); if(actionbar!=null){ actionbar.hide(); } setContentView(R.layout.activity_gpsnavi); //定义AMapNaviView实现 mAMapNaviView = (AMapNaviView) findViewById(R.id.navi_view); mAMapNaviView.onCreate(savedInstanceState); mAMapNaviView.setAMapNaviViewListener(this); //获取AMapNavi实例 mAMapNavi = AMapNavi.getInstance(this); //添加监听回调,用于处理导航视图事件监听。 mAMapNavi.addAMapNaviListener(this); //初始化语音引擎 mTtsManager = TTSController.getInstance(getApplicationContext()); //实例化语音引擎 mTtsManager.init(); //添加导航事件监听。(关键是语音的播放) mAMapNavi.addAMapNaviListener(mTtsManager); //启动实时导航 mAMapNavi.startNavi(NaviType.GPS); //启动模拟导航 //mAMapNavi.startNavi(NaviType.EMULATOR); }

这里写图片描述 上面已经解决了实时导航、语音播放(建议自己申请一个ID),但是最后还有一个坑——就是我们的Activity退回到路线规划Activity的时候,再次规划路线就会失败,就算再次初始化也会失败,不信邪的话可以尝试,那么我们需要怎么解决呢?先看看效果图:

这里写图片描述

大家应该看到左下角的“X”图标,当我们点击这个图标的时候,会有两种情况,要么就是弹起来一个SDK包含的Dialog,要么就是自定义一个事件,但是不管是哪一种,总应该重写事件监听方法,对吧?

@Override public boolean onNaviBackClick() { //导航页面左下角返回按钮的回调接口 // false-由SDK主动弹出『退出导航』对话框, // true-SDK不主动弹出『退出导航对话框』,由用户自定义 return false; } @Override public void onNaviCancel() { //导航页面左下角返回按钮点击后弹出的『退出导航对话框』中选择『确定』后的回调接口。 finish(); }

这里写图片描述

上面代码对该Activity调用了finish()方法,这个时候Activity执行onDestroy()方法的时候,根据上面生命周期的维护,会将AMapNavi对象给销毁掉,导致退回到路线规划Activity的时候AMapNavi对象不能用。 因此我们修改onDestroy()方法即可:

@Override protected void onDestroy() { super.onDestroy(); mAMapNavi.stopNavi(); mTtsManager.destroy(); }

效果图:

这里写图片描述

详见源码



【本文地址】


今日新闻


推荐新闻


CopyRight 2018-2019 办公设备维修网 版权所有 豫ICP备15022753号-3