Android知识Android开发经验谈Android开发

Android - 百度导航Demo,我们一起来踩坑!

2017-07-17  本文已影响2640人  Cosecant

Kotlin - 百度导航Demo,我们一起来踩坑!

背景

项目开发中,我们总是离不开定位、地图这些功能,当然有时候有了地图,那么导航就显得很有必要了。现在让我们开启百度导航吧!

第一步:磨刀不误砍柴工,获得你需要的SDK包

下载地址:百度LBS导航SDK

首先我们得从官网采集我们需要的百度LBS开发包,此处就暂时省略啦!

*注意:要使用百度TTS语音,我们需要注册百度导航TTS白名单,否则我们的导航器可是不会吭声的哦!(当然,你自己集成了其他TTS库除外)

第二步:不积洼步,不足以至千里。学习他人经验,事半功倍

配置说明:百度LBS配置

SDK均已按照官方配置好了,现在我们需要做得就是看别人怎么写的 -- 查看官方导航DEMO源代码。

从官方Demo中可以看出,导航流程大致如下:

初始化SDK ---> 初始化导航配置参数 ---> 规划导航路线 -->开始导航

因此我们可以把官方导航Demo修改一下,直接拿来用!

下面是我总结的一个工具类,仅供参考:

class BaiduMapNavigator private constructor(val activity: Activity) {

    companion object {

        @JvmField
        val ROUTE_PLAN_NODE = "routePlanNode"

        @JvmField
        var isBaiduNaviInitSuccess: Boolean = false

        @SuppressLint("StaticFieldLeak")
        @JvmField
        var baiduNavi: BaiduMapNavigator? = null

        @JvmStatic
        fun getInstance(context: Activity): BaiduMapNavigator? {
            if (baiduNavi == null) {
                synchronized(BaiduMapNavigator::class.java) {
                    baiduNavi = BaiduMapNavigator(context)
                }
            }
            return baiduNavi
        }

    }

    private val eventListerner: BaiduNaviManager.NavEventListener
            = BaiduNaviManager.NavEventListener { what, arg1, arg2, bundle -> BNEventHandler.getInstance().handleNaviEvent(what, arg1, arg2, bundle) }

    /** 初始化导航 **/
    fun initNavigator(context: Context, startNaviName: String, endNaviName: String, naviLatLng: Array<LatLng>) {
        val loadingDialog: MaterialProgressDialog? = DialogUtil.initAndShow(context, MaterialProgressDialog::class.java)
        loadingDialog?.setLoadingText("正在初始化...")
        if (!isBaiduNaviInitSuccess) {
            var authinfo: String?
            val mSDCardPath = SysData.MAIN_APP_DIRECTORY
            File(mSDCardPath, "EdumapNavi").mkdirs()
            BaiduNaviManager.getInstance().init(activity, mSDCardPath, "EdumapNavi", object : BaiduNaviManager.NaviInitListener {
                override fun onAuthResult(status: Int, msg: String) {
                    if (0 == status) {
                        authinfo = "key校验成功!"
                    } else {
                        authinfo = "key校验失败, " + msg
                    }
                    activity.runOnUiThread({ Toast.makeText(activity, authinfo, Toast.LENGTH_LONG).show() })
                }

                override fun initSuccess() {
                    Toast.makeText(activity, "百度导航引擎初始化成功", Toast.LENGTH_SHORT).show()
                    isBaiduNaviInitSuccess = true

                    //设置语音导航
                    val bundle = Bundle()
                    // 必须设置APPID,否则会静音
                    bundle.putString(BNCommonSettingParam.TTS_APP_ID, BuildConfig.BaiduMapApiKey)
                    BNaviSettingManager.setNaviSdkParam(bundle)

                    BNaviSettingManager.setShowTotalRoadConditionBar(BNaviSettingManager.PreViewRoadCondition.ROAD_CONDITION_BAR_SHOW_ON)
                    BNaviSettingManager.setVoiceMode(BNaviSettingManager.VoiceMode.Veteran)
                    // BNaviSettingManager.setPowerSaveMode(BNaviSettingManager.PowerSaveMode.DISABLE_MODE);
                    BNaviSettingManager.setRealRoadCondition(BNaviSettingManager.RealRoadCondition.NAVI_ITS_ON)
                    BNaviSettingManager.setIsAutoQuitWhenArrived(true)

                    //开始百度导航
                    routePlanToNavi(startNaviName, endNaviName, naviLatLng)

                    DialogUtil.hide(loadingDialog)
                }

                override fun initStart() {
                    Toast.makeText(activity, "百度导航引擎初始化开始", Toast.LENGTH_SHORT).show()
                }

                override fun initFailed() {
                    isBaiduNaviInitSuccess = false
                    DialogUtil.hide(loadingDialog)
                    Toast.makeText(activity, "百度导航引擎初始化失败", Toast.LENGTH_SHORT).show()
                }

            }, null, TTSCallbackHandler(activity), TTSPlayStatusCallback(activity))
        } else {
            routePlanToNavi(startNaviName, endNaviName, naviLatLng)
            DialogUtil.hide(loadingDialog)
        }
    }

    /**
     * 路线规划函数
     * @param startNaviName 导航起始地
     * @param endNaviName 导航目的地
     */
    private fun routePlanToNavi(startNaviName: String, endNaviName: String, naviLatLng: Array<LatLng>) {
        val sNode: BNRoutePlanNode = BNRoutePlanNode(naviLatLng[0].longitude, naviLatLng[0].latitude, startNaviName, null, BNRoutePlanNode.CoordinateType.BD09LL)
        val eNode: BNRoutePlanNode = BNRoutePlanNode(naviLatLng[1].longitude, naviLatLng[1].latitude, endNaviName, null, BNRoutePlanNode.CoordinateType.BD09LL)
        BaiduNaviManager.getInstance().launchNavigator(activity, arrayListOf(sNode, eNode), 1, true, BaiduRoutePlanListener(sNode), eventListerner)
    }

    /**
     * 路线导航监听
     * @param node 规划路线节点
     */
    inner class BaiduRoutePlanListener(node: BNRoutePlanNode) : BaiduNaviManager.RoutePlanListener {

        private var mBNRoutePlanNode: BNRoutePlanNode? = null

        init {
            mBNRoutePlanNode = node
        }

        override fun onJumpToNavigator() {
            val intent = Intent(activity, BNGuideActivity::class.java)
            val bundle = Bundle()
            bundle.putSerializable(ROUTE_PLAN_NODE, mBNRoutePlanNode)
            intent.putExtras(bundle)
            activity.startActivity(intent)
        }

        override fun onRoutePlanFailed() {
            Toast.makeText(activity, "路线规划失败", Toast.LENGTH_SHORT).show()
        }
    }

    /**
     * 语音播报播放状态回调
     * @param activity 上下文对象
     */
    class TTSPlayStatusCallback(val activity: Activity) : BaiduNaviManager.TTSPlayStateListener {

        override fun playStart() {
            Log.i(BaiduMapNavigator::class.java.simpleName, "status: 开始播报导航...")
        }

        override fun playEnd() {
            Log.i(BaiduMapNavigator::class.java.simpleName, "status: 播报导航结束...")
        }
    }

    /**
     * 语音播报回调
     * @param context 上下文对象
     */
    class TTSCallbackHandler(val context: Context) : Handler() {

        override fun handleMessage(msg: Message) {
            val type = msg.what
            when (type) {
                BaiduNaviManager.TTSPlayMsgType.PLAY_START_MSG -> {
                    Log.i(BaiduMapNavigator::class.java.simpleName, "开始播报导航...")
                }// showToastMsg("Handler : TTS play start");
                BaiduNaviManager.TTSPlayMsgType.PLAY_END_MSG -> {
                    Log.i(BaiduMapNavigator::class.java.simpleName, "播报导航结束...")
                }// showToastMsg("Handler : TTS play end");
                else -> {
                }
            }
        }

    }

}

万事俱备只欠东风,那么该怎么调用呢?

java:

BaiduMapNavigator.getInstance(Activity activity).initNavigator(Context context, String startNaviName, String endNaviName, LatLng[] naviLatLng);

kotlin:

BaiduMapNavigator.getInstance(activity: Activity).initNavigator(context: Context, startNaviName: String, endNaviName: String,  naviLatLng: Array<LatLng>);

功成身退,成败得失

集成第三方SDK其实并不麻烦,麻烦的是第三方提供的文档有时候是有误的或者表述并不明了,亦或者已经过时。这就很需要我们去查看Demo,归纳出我们自己需要的代码精华。集成这次百度导航中,最让我困惑的是arm64-v8a架构的设备找不到libgnustl_shared.so的位置,armeabi-v7a表现正常!

上一篇下一篇

猜你喜欢

热点阅读