五、android百度地圖之導航(程式碼的拆分和工具類的封裝)

sas???發表於2017-11-20
2802344-bba87c326e4ad246.png
導航

四、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() {

    }
}

到此為止,整個導航功能已經走完三分之二的路程了,為了方便大家我歷來都是直接貼出程式碼,因為看見一個教程卻不能完成功能的感覺簡直不能太糟糕。本來這一篇可以繼續寫完的,但是為了防止篇幅過長和大家只複製貼上不搞明白思路我就留著下一篇再講。喜歡就點個讚唄~

相關文章