react-native实现百度地图的实时导航

近期做了一个地图的项目,需要用到实时导航,在网上查找百度地图实时导航在RN中的组件没有找到,于是就自己写了一个方法可以调用原生的实时导航。

一、首先得用Android原生先实现实时导航

1、从网上下载实例Demo

http://lbsyun.baidu.com/index.php?title=android-navsdk/navsdk-android-download

下载完成后解压发现名为BaiduNavi_AndroidSDK_v3.3.1_Sample.zip的压缩包才是实时导航的Demo,将该压缩包解压问题来了,官网所给的Demo并没有Android Studio,而最后写RN和Android原生的结合必须得用Android Studio,因此第二步需要做的就是将官网例子写为Android Studio可以运行的。

2、将Demo在Android Studio中运行起来

① 用Android Studio新建一个项目名为BaiduNavDemo的应用。

② 将官网所给的例子BaiduNaviSDKSimpleDemo中的内容有选择的复制到BaiduNavDemo的项目中。

1) 将示例中的assets文件夹复制到BaiduNavDemo\app\src\main文件夹下面。

2) 将libs文件夹中的4个jar包复制到项目的libs中并且选中所有jar包右键选择Add As Library。

3) 在BaiduNavDemo的项目中app\src\main文件夹下面新建jnilibs文件夹,将armeabi文件夹中的so文件复制到jniLib文件夹下面的armeabi-v7a文件夹下面。

4) 将res文件夹中的内容复制到res文件夹中,strings.xml文件中复制完后修改app_name,styles.xml文件中完全复制,activity_main.xml文件也是全部复制。


5) 将src中的4个Java文件复制到项目的Java文件夹下,将4个Java文件逐个打开将报红错的地方改正。

③ 为了方便起见直接将MainActivity.java这个主文件作为导航的初始页,将BNDemoMainActivity.java文件中的内容复制到MainActivity.java文件中,这样会报一些红错, 解决这些错误将BNDemoMainActivity改为MainActivity即可。

除此之外,还要将BNDemoGuideActivity.java文件中的红错解决,就是用MainActivity替换BNDemoMainActivity即可。activity_main.xml文件中改为MainActivity

AndroidManifest.xml文件中加入以下内容:

 <!-- 手机震动权限 -->
    <uses-permission android:name="android.permission.BODY_SENSORS"/>
    <uses-permission android:name="android.permission.MOUNT_UNMOUNT_FILESYSTEMS" />
    <uses-permission android:name="android.permission.BAIDU_LOCATION_SERVICE" />
    <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
    <uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />
    <uses-permission android:name="android.permission.INTERNET" />
    <uses-permission android:name="android.permission.ACCES_MOCK_LOCATION" />
    <uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
    <uses-permission android:name="com.android.launcher.permission.READ_SETTINGS" />
    <uses-permission android:name="android.permission.WAKE_LOCK" />
    <uses-permission android:name="android.permission.CHANGE_WIFI_STATE" />
    <uses-permission android:name="android.permission.ACCESS_WIFI_STATE" />
    <uses-permission android:name="android.permission.ACCESS_GPS" />
    <!-- SDK1.5需要android.permission.GET_TASKS权限判断本程序是否为当前运行的应用? -->
    <uses-permission android:name="android.permission.GET_TASKS" />
    <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
    <uses-permission android:name="android.permission.BROADCAST_STICKY" />
    <uses-permission android:name="android.permission.WRITE_SETTINGS" />
    <!-- 来电消音 -->
    <uses-permission android:name="android.permission.PROCESS_OUTGOING_CALLS" />
    <uses-permission android:name="android.permission.READ_PHONE_STATE" />
    <uses-permission android:name="android.permission.MODIFY_AUDIO_SETTINGS" />
    <uses-permission android:name="android.permission.RECORD_AUDIO" />
    <!-- 摄影机 -->
    <uses-permission android:name="android.permission.CAMERA" />

<!--百度API_KEY-->
        <meta-data
            android:name="com.baidu.lbsapi.API_KEY"
            android:value="自己的key" />
        <!--百度定位服务-->
        <service
            android:name="com.baidu.location.f"
            android:enabled="true"
            android:process=":remote" >
        </service>
        <!--注册activity-->
        <activity android:name=".BNDemoGuideActivity" />

④ 此时需要在百度地图api官网上申请key和语音播报的appid

将申请好的应用AK值写在

<meta-data android:name="com.baidu.lbsapi.API_KEY"
            android:value="8nqGEdwqbkTirosEClpUVmbuFbp7X79c" />

在http://yuyin.baidu.com/app网址上为自己的应用开通语音合成功能,并将appid写在

private void initSetting() {
        // BNaviSettingManager.setDayNightMode(BNaviSettingManager.DayNightMode.DAY_NIGHT_MODE_DAY);
        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);
        Bundle bundle = new Bundle();
        // 必须设置APPID,否则会静音
        bundle.putString(BNCommonSettingParam.TTS_APP_ID, "9354030");
        BNaviSettingManager.setNaviSdkParam(bundle);
    }

提示:获取发布版的SHA1和开发版的SHA1参照 http://jingyan.baidu.com/article/25648fc19932849191fd0001.html

此时就可以用Android Studio运行官网上的Demo了。

二、在react-native项目中直接实现点击导航按钮进入导航页面

1、初始化一个RN项目,并且调用原生Android的方法。

这一步在上一篇文章中react-native调用Android原生方法中已经详细说明。以下步骤是在此基础上操作的。

2、用Android studio打开rnAndroid项目下的android文件夹。

3、复制官方实时导航中的项目

1) assets文件夹含内容复制到app/src/main下

2) android目录下新建libs文件夹并复制导航项目中的libs文件夹下的jar包,并且选中所有jar包右键选择Add As Library对话框选择app

3) 在项目中app\src\main文件夹下面新建jnilibs文件夹,将armeabi文件夹中的so文件复制到jniLib文件夹下面的armeabi-v7a文件夹下面。

4) 将res文件夹中的内容复制到res文件夹中,strings.xml文件中复制完后修改app_name,styles.xml文件中只复制不同的地方,activity_main.xml文件也是全部复制。

5) 在java下的com.rnandroid包下新建nav文件夹用来放java文件,将src中的4个Java文件复制到项目的nav文件夹下,将4个Java文件逐个打开将报红错的地方改正。

4、将BNDemoMainActivity中的内容移接到MainActivity中

1) 将BNDemoMainActivity中的代码复制到MainActivity中(只复制代码,会自动提示引包的),修改报的红错。

先将MainActivity中的最后一行代码注释掉,(先测一下是否可以运行再实现RN直接调用)

//    @Override
//    protected String getMainComponentName() {
//        return "rnAndroid";
//    }

activity_main.xml文件中改为MainActivity

2) AndroidManifest.xml文件中加入内容和上面一样。

AndroidManifest.xml中注册activity时注意包名。

<!--注册activity-->
        <activity android:name="com.rnandroid.nav.BNDemoGuideActivity" />

3) 在百度地图api官网上申请key和语音播报的appid,注意填写的包名是AndroidManifest.xml中package后面的包名

package="com.rnandroid"

5、此时运行可以正常的调出来导航,下面实现在RN中直接调出来导航。

① 将MainActivity中注释掉的最后一行代码取消注释。

② 将RnTest.java文件中代码改为

public class RnTest extends ReactContextBaseJavaModule {
    private  ReactApplicationContext context = null;//添加
    public static List<Activity> activityList = new LinkedList<Activity>();//添加
    public static final String ROUTE_PLAN_NODE = "routePlanNode";//添加

    public RnTest(ReactApplicationContext reactContext) {
        super(reactContext);
        context = reactContext;//添加
    }

    //添加的导航内容开始
    private void routeplanToNavi(BNRoutePlanNode.CoordinateType coType) {
//        mCoordinateType = coType;
//        if (!hasInitSuccess) {
//            Toast.makeText(MainActivity.this, "还未初始化!", Toast.LENGTH_SHORT).show();
//        }
//        // 权限申请
//        if (android.os.Build.VERSION.SDK_INT >= 23) {
//            // 保证导航功能完备
//            if (!hasCompletePhoneAuth()) {
//                if (!hasRequestComAuth) {
//                    hasRequestComAuth = true;
//                    this.requestPermissions(authComArr, authComRequestCode);
//                    return;
//                } else {
//                    Toast.makeText(MainActivity.this, "没有完备的权限!", Toast.LENGTH_SHORT).show();
//                }
//            }
//
//        }
        BNRoutePlanNode sNode = null;
        BNRoutePlanNode eNode = null;
        switch (coType) {
            case GCJ02: {
                sNode = new BNRoutePlanNode(116.30142, 40.05087, "百度大厦", null, coType);
                eNode = new BNRoutePlanNode(116.39750, 39.90882, "北京天安门", null, coType);
                break;
            }
            case WGS84: {
                sNode = new BNRoutePlanNode(116.300821, 40.050969, "百度大厦", null, coType);
                eNode = new BNRoutePlanNode(116.397491, 39.908749, "北京天安门", null, coType);
                break;
            }
            case BD09_MC: {
                sNode = new BNRoutePlanNode(12947471, 4846474, "百度大厦", null, coType);
                eNode = new BNRoutePlanNode(12958160, 4825947, "北京天安门", null, coType);
                break;
            }
            case BD09LL: {
                sNode = new BNRoutePlanNode(116.30784537597782, 40.057009624099436, "百度大厦", null, coType);
                eNode = new BNRoutePlanNode(116.40386525193937, 39.915160800132085, "北京天安门", null, coType);
                break;
            }
            default:
                ;
        }
        if (sNode != null && eNode != null) {
            List<BNRoutePlanNode> list = new ArrayList<BNRoutePlanNode>();
            list.add(sNode);
            list.add(eNode);

            // 开发者可以使用旧的算路接口,也可以使用新的算路接口,可以接收诱导信息等
            // BaiduNaviManager.getInstance().launchNavigator(this, list, 1, true, new DemoRoutePlanListener(sNode));
            BaiduNaviManager.getInstance().launchNavigator(this.getCurrentActivity(), list, 1, true, new DemoRoutePlanListener(sNode,this.getCurrentActivity()),eventListerner);
        }
    }

    BaiduNaviManager.NavEventListener eventListerner = new BaiduNaviManager.NavEventListener() {

        @Override
        public void onCommonEventCall(int what, int arg1, int arg2, Bundle bundle) {
            BNEventHandler.getInstance().handleNaviEvent(what, arg1, arg2, bundle);
        }
    };

    public class DemoRoutePlanListener implements BaiduNaviManager.RoutePlanListener {

        private BNRoutePlanNode mBNRoutePlanNode = null;
        private  Activity  _currentActivity =null;

        public DemoRoutePlanListener(BNRoutePlanNode node , Activity currentActivity) {
            mBNRoutePlanNode = node;
            _currentActivity =currentActivity;
        }

        @Override
        public void onJumpToNavigator() {
            /*
             * 设置途径点以及resetEndNode会回调该接口
             */

            for (Activity ac : activityList) {

                if (ac.getClass().getName().endsWith("BNDemoGuideActivity")) {

                    return;
                }
            }
            Intent intent = new Intent(_currentActivity, BNDemoGuideActivity.class);
            Bundle bundle = new Bundle();
            bundle.putSerializable(ROUTE_PLAN_NODE, (BNRoutePlanNode) mBNRoutePlanNode);
            intent.putExtras(bundle);
            _currentActivity.startActivity(intent);

        }

        @Override
        public void onRoutePlanFailed() {
            // TODO Auto-generated method stub
            Toast.makeText(getReactApplicationContext(), "算路失败", Toast.LENGTH_SHORT).show();
        }
    }
    //添加的导航内容结束







    // ReactContextBaseJavaModule要求派生类实现getName方法。这个函数用于返回一个字符串
    // 这个字符串用于在JavaScript端标记这个原生模块
    @Override
    public String getName() {
        return "ToastByAndroid";
    }
    // 获取应用包名
    // 要导出一个方法给JavaScript使用,Java方法需要使用注解@ReactMethod
    @ReactMethod
    public void getPackageName() {
//        String name = getReactApplicationContext().getPackageName();
//        Toast.makeText(getReactApplicationContext(),name,Toast.LENGTH_LONG).show();

        //调用实时导航的函数
        routeplanToNavi(BNRoutePlanNode.CoordinateType.BD09LL);
    }
}

注意:this.getCurrentActivity()

实现的思路是点击RN上的按钮先调用Android原生中的getPackageName方法,执行此方法时会执行开始导航的方法。

6、此时运行发现并没有跑通,经过多方面资讯,将项目引入的libgnustl_shared.so文件删除即可。



完!








  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值