四湾碎、android百度地圖之導(dǎo)航(環(huán)境的配置)
五宙攻、android百度地圖之導(dǎo)航(代碼的拆分和工具類的封裝)
通過前面對(duì)導(dǎo)航的環(huán)境配置,我們現(xiàn)在完成整個(gè)導(dǎo)航功能中最為關(guān)鍵的一步介褥,那就是對(duì)導(dǎo)航代碼進(jìn)行拆分以及封裝座掘。
一、導(dǎo)航工具類的封裝
通過我做導(dǎo)航這個(gè)功能柔滔,覺得最難的部分就是對(duì)導(dǎo)航工具類的封裝溢陪,里面的邏輯和各個(gè)類、各個(gè)方法甚至于各個(gè)參數(shù)睛廊,在百度文檔里都沒有明確的寫出來形真,都是我直接看API一個(gè)一個(gè)分析和拆分的,所以我直接將代碼放出來超全,注釋很詳細(xì)就不用我多說了咆霜,代碼如下:
/**
* @title 百度導(dǎo)航工具類
* @date 2017/11/20
* @author 貓兒不吃魚魚
*/
public class NavigationUtil implements BaiduNaviManager.NavEventListener{
private Activity activity;
/**
* 系統(tǒng)SD卡根目錄路徑
*/
private String mSDCardPath;
/**
* 應(yīng)用在SD卡中的目錄名
*/
private String appFolderName;
/**
* 標(biāo)識(shí)初始化是否成功
*/
private boolean hasInitSuccess = false;
/**
* 校驗(yàn)信息
*/
private String authinfo;
/**
* 路節(jié)點(diǎn)的坐標(biāo)類型
* BD09_MC
* 百度墨卡托坐標(biāo)
* BD09LL
* 百度經(jīng)緯度坐標(biāo)
* GCJ02
* 國測局坐標(biāo)
* WGS84
* GPS坐標(biāo)
*/
private BNRoutePlanNode.CoordinateType mCoordinateType = null;
public NavigationUtil(Activity activity, String mSDCardPath, String appFolderName) {
this.activity = activity;
this.mSDCardPath = mSDCardPath;
this.appFolderName = appFolderName;
}
/**
* 百度導(dǎo)航服務(wù)授權(quán)和引擎初始化
*/
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校驗(yàn)成功!";
} else {
authinfo = "key校驗(yàn)失敗, " + msg;
}
activity.runOnUiThread(new Runnable() {
@Override
public void run() {
Toast.makeText(activity, authinfo, Toast.LENGTH_LONG).show();
}
});
}
@Override
public void initStart() {
Toast.makeText(activity, "百度導(dǎo)航引擎初始化開始", Toast.LENGTH_SHORT).show();
}
@Override
public void initSuccess() {
Toast.makeText(activity, "百度導(dǎo)航引擎初始化成功", Toast.LENGTH_SHORT).show();
hasInitSuccess = true;
initSetting();
}
@Override
public void initFailed() {
Toast.makeText(activity, "百度導(dǎo)航引擎初始化失敗", Toast.LENGTH_SHORT).show();
}
}, null, ttsHandler, new TTSListener());
}
/**
* 異步獲取百度內(nèi)部TTS播報(bào)狀態(tài)
*/
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;
}
}
};
/**
* 導(dǎo)航設(shè)置
*/
private void initSetting() {
//顯示路況條 預(yù)覽條顯示
BNaviSettingManager.setShowTotalRoadConditionBar(BNaviSettingManager.PreViewRoadCondition.ROAD_CONDITION_BAR_SHOW_ON);
// 導(dǎo)航中語音播報(bào)模式 老手模式
BNaviSettingManager.setVoiceMode(BNaviSettingManager.VoiceMode.Veteran);
// 實(shí)際道路條件 路況條 開
BNaviSettingManager.setRealRoadCondition(BNaviSettingManager.RealRoadCondition.NAVI_ITS_ON);
//到達(dá)時(shí)自動(dòng)退出
BNaviSettingManager.setIsAutoQuitWhenArrived(true);
//創(chuàng)建Bundle
Bundle bundle = new Bundle();
//必須設(shè)置APPID,否則會(huì)靜音嘶朱,這里的id傳入你們自己申請(qǐng)的id
bundle.putString(BNCommonSettingParam.TTS_APP_ID, id);
//設(shè)置語音播報(bào)
BNaviSettingManager.setNaviSdkParam(bundle);
}
/**
* 路線規(guī)劃導(dǎo)航
* @param coType
* @param longitudeStarting 起點(diǎn)經(jīng)度
* @param latitudeStarting 起點(diǎn)維度
* @param longitudeEnd 終點(diǎn)經(jīng)度
* @param latitudeEnd 終點(diǎn)維度
* @param startingName 起點(diǎn)名字
* @param endName 終點(diǎn)名字
*/
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);
// 開發(fā)者可以使用舊的算路接口蛾坯,也可以使用新的算路接口,可以接收誘導(dǎo)信息等
// 第四個(gè)參數(shù)如果為false則是模擬導(dǎo)航
// BaiduNaviManager.getInstance().launchNavigator(this, list, 1, true, new DemoRoutePlanListener(sNode));
BaiduNaviManager.getInstance().launchNavigator(activity, list, 1, true, new NavigationRoutePlanListener(sNode,activity), this);
}
}
/**
* 導(dǎo)航過程信息回調(diào)接口
* @param what
* @param arg1
* @param arg2
* @param bundle
*/
@Override
public void onCommonEventCall(int what, int arg1, int arg2, Bundle bundle) {
}
}
二、路線方案的監(jiān)聽(算路節(jié)點(diǎn))
在完成了導(dǎo)航的工具類后疏遏,大家的思路肯定會(huì)想到從起點(diǎn)到終點(diǎn)怎么去規(guī)劃這個(gè)路線脉课,所以我們現(xiàn)在還需要一個(gè)對(duì)路線的監(jiān)聽和計(jì)算的類,依舊詳細(xì)财异,代碼如下:
/**
* @title 路線方案的監(jiān)聽
* @date 2017/11/20
* @author 貓兒不吃魚魚
*/
public class NavigationRoutePlanListener implements BaiduNaviManager.RoutePlanListener {
private Activity activity;
/**
* 路線方案的節(jié)點(diǎn)
*/
public static final String ROUTE_PLAN_NODE = "routePlanNode";
/**
* 算路節(jié)點(diǎn)
*/
private BNRoutePlanNode mBNRoutePlanNode = null;
public static List<Activity> activityList = new LinkedList();
public NavigationRoutePlanListener(BNRoutePlanNode node,Activity activity) {
this.activity = activity;
mBNRoutePlanNode = node;
}
/**
* 導(dǎo)航初始化監(jiān)聽器
* 路線規(guī)劃成功倘零,需要跳轉(zhuǎn)到導(dǎo)航過程頁面
*/
@Override
public void onJumpToNavigator() {
/**
* 設(shè)置途徑點(diǎn)以及resetEndNode會(huì)回調(diào)該接口
*/
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);
}
/**
* 導(dǎo)航初始化監(jiān)聽器
* 路線規(guī)劃失敗
*/
@Override
public void onRoutePlanFailed() {
// TODO Auto-generated method stub
Toast.makeText(activity, "算路失敗", Toast.LENGTH_SHORT).show();
}
}
三、導(dǎo)航需要的一些常量
/**
* @title 導(dǎo)航路徑引導(dǎo)模塊常量
* @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播報(bào)狀態(tài)
看到這里大家就要納悶了呈驶,在NavigationUtil類里明明有一個(gè)ttsHandler的TTS播報(bào)狀態(tài),為什么這里還會(huì)提到疫鹊。其實(shí)我和你們是一樣一樣的俐东,他這個(gè)同步和異步不知道怎么搞的跌穗,必須兩個(gè)一起寫才有效果,我翻遍了API也沒找到合理的解答虏辫,所以為了我們的導(dǎo)航能正常運(yùn)行還是寫一下蚌吸,代碼很簡單,防止小白我仍然貼出來:
/**
* @title 同步獲取百度內(nèi)部TTS播報(bào)狀態(tài)回調(diào)接口
* @date 2017/11/20
* @author 貓兒不吃魚魚
*/
public class TTSListener implements BaiduNaviManager.TTSPlayStateListener{
/**
* TTS開始
*/
@Override
public void playStart() {
}
/**
* TTS停止
*/
@Override
public void playEnd() {
}
}
到此為止砌庄,整個(gè)導(dǎo)航功能已經(jīng)走完三分之二的路程了羹唠,為了方便大家我歷來都是直接貼出代碼,因?yàn)榭匆娨粋€(gè)教程卻不能完成功能的感覺簡直不能太糟糕娄昆。本來這一篇可以繼續(xù)寫完的佩微,但是為了防止篇幅過長和大家只復(fù)制粘貼不搞明白思路我就留著下一篇再講。喜歡就點(diǎn)個(gè)贊唄~