
四、android百度地图之导航(环境的配置)
五、android百度地图之导航(代码的拆分和工具类的封装)
通过前面对导航的环境配置,我们现在完成整个导航功能中最为关键的一步,那就是对导航代码进行拆分以及封装。
一、导航工具类的封装
通过我做导航这个功能,觉得最难的部分就是对导航工具类的封装,里面的逻辑和各个类、各个方法甚至于各个参数,在百度文档里都没有明确的写出来,都是我直接看API一个一个分析和拆分的,所以我直接将代码放出来,注释很详细就不用我多说了,代码如下:
/**
* @title 百度导航工具类
* @date 2017/11/20
* @author 猫儿不吃鱼鱼
*/
public class NavigationUtil implements BaiduNaviManager.NavEventListener{
private Activity activity;
/**
* 系统SD卡根目录路径
*/
private String mSDCardPath;
/**
* 应用在SD卡中的目录名
*/
private String appFolderName;
/**
* 标识初始化是否成功
*/
private boolean hasInitSuccess = false;
/**
* 校验信息
*/
private String authinfo;
/**
* 路节点的坐标类型
* BD09_MC
* 百度墨卡托坐标
* BD09LL
* 百度经纬度坐标
* GCJ02
* 国测局坐标
* WGS84
* GPS坐标
*/
private BNRoutePlanNode.CoordinateType mCoordinateType = null;
public NavigationUtil(Activity activity, String mSDCardPath, String appFolderName) {
this.activity = activity;
this.mSDCardPath = mSDCardPath;
this.appFolderName = appFolderName;
}
/**
* 百度导航服务授权和引擎初始化
*/
public void initNavi() {
BaiduNaviManager.getInstance().init(activity, mSDCardPath, appFolderName, new BaiduNaviManager.NaviInitListener() {
@Override
public void onAuthResult(int status, String msg) {
if (0 == status) {
authinfo = "key校验成功!";
} else {
authinfo = "key校验失败, " + msg;
}
activity.runOnUiThread(new Runnable() {
@Override
public void run() {
Toast.makeText(activity, authinfo, Toast.LENGTH_LONG).show();
}
});
}
@Override
public void initStart() {
Toast.makeText(activity, "百度导航引擎初始化开始", Toast.LENGTH_SHORT).show();
}
@Override
public void initSuccess() {
Toast.makeText(activity, "百度导航引擎初始化成功", Toast.LENGTH_SHORT).show();
hasInitSuccess = true;
initSetting();
}
@Override
public void initFailed() {
Toast.makeText(activity, "百度导航引擎初始化失败", Toast.LENGTH_SHORT).show();
}
}, null, ttsHandler, new TTSListener());
}
/**
* 异步获取百度内部TTS播报状态
*/
private Handler ttsHandler = new Handler() {
public void handleMessage(Message msg) {
int type = msg.what;
switch (type) {
case BaiduNaviManager.TTSPlayMsgType.PLAY_START_MSG:
//Handler : TTS play start...
break;
case BaiduNaviManager.TTSPlayMsgType.PLAY_END_MSG:
//Handler : TTS play end...
break;
}
}
};
/**
* 导航设置
*/
private void initSetting() {
//显示路况条 预览条显示
BNaviSettingManager.setShowTotalRoadConditionBar(BNaviSettingManager.PreViewRoadCondition.ROAD_CONDITION_BAR_SHOW_ON);
// 导航中语音播报模式 老手模式
BNaviSettingManager.setVoiceMode(BNaviSettingManager.VoiceMode.Veteran);
// 实际道路条件 路况条 开
BNaviSettingManager.setRealRoadCondition(BNaviSettingManager.RealRoadCondition.NAVI_ITS_ON);
//到达时自动退出
BNaviSettingManager.setIsAutoQuitWhenArrived(true);
//创建Bundle
Bundle bundle = new Bundle();
//必须设置APPID,否则会静音,这里的id传入你们自己申请的id
bundle.putString(BNCommonSettingParam.TTS_APP_ID, id);
//设置语音播报
BNaviSettingManager.setNaviSdkParam(bundle);
}
/**
* 路线规划导航
* @param coType
* @param longitudeStarting 起点经度
* @param latitudeStarting 起点维度
* @param longitudeEnd 终点经度
* @param latitudeEnd 终点维度
* @param startingName 起点名字
* @param endName 终点名字
*/
public void routePlanToNavi(BNRoutePlanNode.CoordinateType coType, double longitudeStarting, double latitudeStarting,
double longitudeEnd, double latitudeEnd, String startingName, String endName) {
mCoordinateType = coType;
if (!hasInitSuccess) {
Toast.makeText(activity, "还未初始化!", Toast.LENGTH_SHORT).show();
}
BNRoutePlanNode sNode = null;
BNRoutePlanNode eNode = null;
switch (coType) {
case GCJ02:
sNode = new BNRoutePlanNode(longitudeStarting, latitudeStarting, startingName, null, coType);
eNode = new BNRoutePlanNode(longitudeEnd, latitudeEnd, endName, null, coType);
break;
case WGS84:
sNode = new BNRoutePlanNode(longitudeStarting, latitudeStarting, startingName, null, coType);
eNode = new BNRoutePlanNode(longitudeEnd, latitudeEnd, endName, null, coType);
break;
case BD09_MC:
sNode = new BNRoutePlanNode(longitudeStarting, latitudeStarting, startingName, null, coType);
eNode = new BNRoutePlanNode(longitudeEnd, latitudeEnd, endName, null, coType);
break;
case BD09LL:
sNode = new BNRoutePlanNode(longitudeStarting, latitudeStarting, startingName, null, coType);
eNode = new BNRoutePlanNode(longitudeEnd, latitudeEnd, endName, null, coType);
break;
}
if (sNode != null && eNode != null) {
List<BNRoutePlanNode> list = new ArrayList();
list.add(sNode);
list.add(eNode);
// 开发者可以使用旧的算路接口,也可以使用新的算路接口,可以接收诱导信息等
// 第四个参数如果为false则是模拟导航
// BaiduNaviManager.getInstance().launchNavigator(this, list, 1, true, new DemoRoutePlanListener(sNode));
BaiduNaviManager.getInstance().launchNavigator(activity, list, 1, true, new NavigationRoutePlanListener(sNode,activity), this);
}
}
/**
* 导航过程信息回调接口
* @param what
* @param arg1
* @param arg2
* @param bundle
*/
@Override
public void onCommonEventCall(int what, int arg1, int arg2, Bundle bundle) {
}
}
二、路线方案的监听(算路节点)
在完成了导航的工具类后,大家的思路肯定会想到从起点到终点怎么去规划这个路线,所以我们现在还需要一个对路线的监听和计算的类,依旧详细,代码如下:
/**
* @title 路线方案的监听
* @date 2017/11/20
* @author 猫儿不吃鱼鱼
*/
public class NavigationRoutePlanListener implements BaiduNaviManager.RoutePlanListener {
private Activity activity;
/**
* 路线方案的节点
*/
public static final String ROUTE_PLAN_NODE = "routePlanNode";
/**
* 算路节点
*/
private BNRoutePlanNode mBNRoutePlanNode = null;
public static List<Activity> activityList = new LinkedList();
public NavigationRoutePlanListener(BNRoutePlanNode node,Activity activity) {
this.activity = activity;
mBNRoutePlanNode = node;
}
/**
* 导航初始化监听器
* 路线规划成功,需要跳转到导航过程页面
*/
@Override
public void onJumpToNavigator() {
/**
* 设置途径点以及resetEndNode会回调该接口
*/
for (Activity ac : activityList) {
if (ac.getClass().getName().endsWith("NavigationGuideActivity")) {
return;
}
}
Intent intent = new Intent(activity, NavigationGuideActivity.class);
Bundle bundle = new Bundle();
bundle.putSerializable(ROUTE_PLAN_NODE, (BNRoutePlanNode) mBNRoutePlanNode);
intent.putExtras(bundle);
activity.startActivity(intent);
}
/**
* 导航初始化监听器
* 路线规划失败
*/
@Override
public void onRoutePlanFailed() {
// TODO Auto-generated method stub
Toast.makeText(activity, "算路失败", Toast.LENGTH_SHORT).show();
}
}
三、导航需要的一些常量
/**
* @title 导航路径引导模块常量
* @date 2017/11/20
* @author 猫儿不吃鱼鱼
*/
public interface NavigationRouteGuideModuleConstants {
int METHOD_TYPE_ON_KEY_DOWN = 0x01;
String KEY_TYPE_KEYCODE = "keyCode";
String KEY_TYPE_EVENT = "event";
}
四、TTS播报状态
看到这里大家就要纳闷了,在NavigationUtil类里明明有一个ttsHandler的TTS播报状态,为什么这里还会提到。其实我和你们是一样一样的,他这个同步和异步不知道怎么搞的,必须两个一起写才有效果,我翻遍了API也没找到合理的解答,所以为了我们的导航能正常运行还是写一下,代码很简单,防止小白我仍然贴出来:
/**
* @title 同步获取百度内部TTS播报状态回调接口
* @date 2017/11/20
* @author 猫儿不吃鱼鱼
*/
public class TTSListener implements BaiduNaviManager.TTSPlayStateListener{
/**
* TTS开始
*/
@Override
public void playStart() {
}
/**
* TTS停止
*/
@Override
public void playEnd() {
}
}
到此为止,整个导航功能已经走完三分之二的路程了,为了方便大家我历来都是直接贴出代码,因为看见一个教程却不能完成功能的感觉简直不能太糟糕。本来这一篇可以继续写完的,但是为了防止篇幅过长和大家只复制粘贴不搞明白思路我就留着下一篇再讲。喜欢就点个赞呗~
网友评论