Android Studio调用百度地图(二):实现地图显示后台定位和步行导航

先看一下运行效果:

Android Studio调用百度地图(二):实现地图显示后台定位和步行导航_第1张图片 Android Studio调用百度地图(二):实现地图显示后台定位和步行导航_第2张图片 Android Studio调用百度地图(二):实现地图显示后台定位和步行导航_第3张图片

实现功能:后台定位+步行导航(可通过长按屏幕自定义终点,起点为定位点)
后台定位即当程序在后台时依旧执行定位功能,步行导航支持30米-50千米范围内的导航

一 导入SDK并配置相关信息

SDK下载和AK创建详见 Android Studio调用百度地图(一):注册成为百度地图开发者并下载SDK
SDK的导入具体可见百度地图官网

这里我要说的是实现定位和导航时需要注意的地方。
在proguard-rules.pro中添加

-dontoptimize
-ignorewarnings
-keeppackagenames com.baidu.**
-keepattributes Exceptions,InnerClasses,Signature,Deprecated,SourceFile,LineNumberTable,LocalVariable*Table,*Annotation*,Synthetic,EnclosingMethod

-dontwarn com.baidu.**
-dontwarn com.baidu.navisdk.**
-dontwarn com.baidu.navi.**

-keep class com.baidu.** { *; }
-keep interface com.baidu.** { *; }

-keep class vi.com.gdi.** { *; }

-dontwarn com.google.protobuf.**
-keep class com.google.protobuf.** { *;}
-keep interface com.google.protobuf.** { *;}

在AndroidManifest.xml中添加
Android Studio调用百度地图(二):实现地图显示后台定位和步行导航_第4张图片

二 调用百度地图API实现后台定位和步行导航

1 实现后台定位核心代码

   // 定位初始化
 private void initLocationSDK() {
        mClient = new LocationClient(this);
        LocationClientOption mOption = new LocationClientOption();
        mOption.setScanSpan(5000);
        mOption.setCoorType("bd09ll");//设置坐标类型
        mOption.setIsNeedAddress(true);//设置是否需要地址信息,默认为无地址。
        mOption.setOpenGps(true);
        mClient.setLocOption(mOption);
        mClient.registerLocationListener(myLocationListener);
    }
    
   //开始后台定位
    private void settingLocInForeground() {
        //android8.0及以上使用NotificationUtils
        if (Build.VERSION.SDK_INT >= 26) {
            mNotificationUtils = new NotificationUtils(this);
            Notification.Builder builder2 = mNotificationUtils.getAndroidChannelNotification
                    ("适配android 8限制后台定位功能", "正在后台定位");
            notification = builder2.build();
        } else {
            //获取一个Notification构造器
            Notification.Builder builder = new Notification.Builder(DeleveryInfo.this);
            Intent nfIntent = new Intent(DeleveryInfo.this, DeleveryInfo.class);

            builder.setContentIntent(PendingIntent.
                    getActivity(DeleveryInfo.this, 0, nfIntent, 0)) // 设置PendingIntent
                    .setContentTitle("适配android 8限制后台定位功能") // 设置下拉列表里的标题
                    // .setSmallIcon(R.drawable.ic_launcher) // 设置状态栏内的小图标
                    .setContentText("正在后台定位") // 设置上下文内容
                    .setWhen(System.currentTimeMillis()); // 设置该通知发生的时间

            if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN) {
                notification = builder.build(); // 获取构建好的Notification
            }
        }
        notification.defaults = Notification.DEFAULT_SOUND; //设置为默认的声音
        //开发者应用如果有后台定位需求,在退到后台的时候,为了保证定位可以在后台一直运行, 可以调用该函数,
        //会将定位SDK的SERVICE设置成为前台服务,适配ANDROID 8后台无法定位问题,其他版本下也会提高定位进程存活率
        //id - 为通知栏notifation设置唯一id,必须大于0
        //notification - 开发者自定义通知
        mClient.enableLocInForeground(1001, notification);// 调起前台定位
        mClient.disableLocInForeground(true);// 关闭前台定位,同时移除通知栏
    }

创建MyLocationListener监听定位

 class MyLocationListener extends BDAbstractLocationListener {
        @Override
        public void onReceiveLocation(BDLocation bdLocation) {
            if (bdLocation == null || mMapView == null) {
                return;
            }
            MyLocationData locData = new MyLocationData.Builder().accuracy(bdLocation.getRadius())
                    // 此处设置开发者获取到的方向信息,顺时针0-360
                    .direction(bdLocation.getDirection()).latitude(bdLocation.getLatitude())
                    .longitude(bdLocation.getLongitude()).build();
            // 设置定位数据
            mBaiduMap.setMyLocationData(locData);
            //地图SDK处理
            if (isFirstLoc) {
                isFirstLoc = false;
                LatLng ll = new LatLng(bdLocation.getLatitude(),
                        bdLocation.getLongitude());
                MapStatus.Builder builder = new MapStatus.Builder();
                builder.target(ll).zoom(18.0f);
                mBaiduMap.animateMapStatus(MapStatusUpdateFactory.newMapStatus(builder.build()));
            }
            LatLng point = new LatLng(bdLocation.getLatitude(), bdLocation.getLongitude());
            OverlayOptions dotOption = new DotOptions().center(point).color(0xAAA9A9A9);
            mBaiduMap.addOverlay(dotOption);
            StringBuffer sb = new StringBuffer(256);
            sb.append("Latitude:");
            sb.append(bdLocation.getLatitude());
            sb.append("Longitude");
            Dest_BD09LL_Start = new LatLng(bdLocation.getLatitude(), bdLocation.getLongitude());
            sb.append(bdLocation.getLongitude() + "\n");
            if (null != mTextView) {
                mTextView.append(sb.toString());
            }
        }
    }
  1. 步行导航可信代码

开启步行导航很简单 首先点击开始导航button初始化引擎,发起算路(如果引擎初始化成功),跳转诱导界面开始步行导航(如果算路成功)

/**
     * @Description: 引擎初始化
     * @Author: LY
     */
    private void startBikeNavi() {
        Log.d(TAG, "startBikeNavi");
        try {
            WalkNavigateHelper.getInstance().initNaviEngine(this, new IWEngineInitListener() {
                @Override
                public void engineInitSuccess() {
                    Log.d(TAG, "BikeNavi engineInitSuccess");
                    routePlanWithWalkParam();
                }

                @Override
                public void engineInitFail() {
                    Log.d(TAG, "BikeNavi engineInitFail");
                    BikeNavigateHelper.getInstance().unInitNaviEngine();
                }
            });
        } catch (Exception e) {
            Log.d(TAG, "startBikeNavi Exception");
            e.printStackTrace();
        }
    }


    /**
     * @Description: 步行导航算路
     * @Author: LY
     */
    private void routePlanWithWalkParam() {

        walkStartNode = new LatLng(Dest_BD09LL_Start.latitude, Dest_BD09LL_Start.longitude);
        walkEndNode = new LatLng(Dest_BD09LL_End.latitude, Dest_BD09LL_End.longitude);


        walkParam = new WalkNaviLaunchParam().stPt(walkStartNode).endPt(walkEndNode);

        WalkNavigateHelper.getInstance().routePlanWithParams(walkParam, new IWRoutePlanListener() {
            @Override
            public void onRoutePlanStart() {
                Log.d("Walk", "WalkNavi onRoutePlanStart");
            }

            @Override
            public void onRoutePlanSuccess() {
                Log.d("Walk", "onRoutePlanSuccess");
                Intent intent = new Intent();
                intent.setClass(DeleveryInfo.this, WNaviGuideActivity.class);
                startActivity(intent);
            }

            @Override
            public void onRoutePlanFail(WalkRoutePlanError error) {
                Log.d("Walk", "WalkNavi onRoutePlanFail");
                Toast.makeText(mNotificationUtils, "" + error, Toast.LENGTH_SHORT).show();
              
            }

        });
    }

诱导界面 WNaviGuideActivity.java

public class WNaviGuideActivity extends Activity {
        private final static String TAG = WNaviGuideActivity.class.getSimpleName();

        private WalkNavigateHelper mNaviHelper;

        private boolean isPreSPEAKtotal = true;
        private String orient = "";

        @Override
        protected void onDestroy() {
            super.onDestroy();
            mNaviHelper.quit();
        }

        @Override
        protected void onResume() {
            super.onResume();
            mNaviHelper.resume();
        }

        @Override
        protected void onPause() {
            super.onPause();
            mNaviHelper.pause();
        }


        Handler handler = new Handler() {
            @Override
            public void handleMessage(Message msg) {
                super.handleMessage(msg);
                if (msg.what == 0x001) {
                    ChangeState();
                    handler.sendEmptyMessageDelayed(0x001, 45000);
                }
                if (msg.what == 0x002) {
                     handler.sendEmptyMessageDelayed(0x002, 30000);
                }
                if (msg.what == 0x003) {
                  
                    startActivity(new Intent(WNaviGuideActivity.this, DeleveryInfo.class));
                }
            }
        };

        private void ChangeState() {
            isPreSPEAKtotal = true;
        }

        @Override
        protected void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            mNaviHelper = WalkNavigateHelper.getInstance();
            try {
                View view = mNaviHelper.onCreate(WNaviGuideActivity.this);
                if (view != null) {
                    setContentView(view);
                }
            } catch (Exception e) {
                e.printStackTrace();
            }
            //设置步行导航状态监听
            mNaviHelper.setWalkNaviStatusListener(new IWNaviStatusListener() {
                @Override
                public void onWalkNaviModeChange(int mode, WalkNaviModeSwitchListener listener) {
                    Log.d(TAG, "onWalkNaviModeChange : " + mode);
                    mNaviHelper.switchWalkNaviMode(WNaviGuideActivity.this, mode, listener);
                }

                /* @Description: 这个是在退出导航时自动调用的方法,在这里要把对象进行释放,避免空对象的产生
                 * @Author: LiY                                                                                                                                                                         ue
                 */
                @Override
                public void onNaviExit() {
                    Log.d(TAG, "onNaviExit");
                    handler.removeMessages(0x001);
                    handler.removeMessages(0x002);
                    handler.removeMessages(0x003);
                }
            });

            /**
             * 诱导文本回调
             * @param s 诱导文本
             * @param b 是否抢先播报
             * @return
             */
            mNaviHelper.setTTsPlayer(new  IWTTSPlayer() {
                                                 @Override
                                                 public int playTTSText(final String s, boolean b) {
                                                     Log.d(TAG, "tts: " + s);                                                                                                                                    
                                                     return 0;
                                                 }
                                             });


            boolean startResult = mNaviHelper.startWalkNavi(WNaviGuideActivity.this);
            Log.e(TAG, "startWalkNavi result : " + startResult);
            //设置路线指引监听
            mNaviHelper.setRouteGuidanceListener(this, new

                    IWRouteGuidanceListener() {
                        /**
                         * @Description: 诱导图标更改方法回调
                         * @Author: LY
                         */
                        @Override
                        public void onRouteGuideIconUpdate(Drawable icon) {

                        }

                        @Override
                        public void onRouteGuideKind(RouteGuideKind routeGuideKind) {
                            Log.d(TAG, "onRouteGuideKind: " + routeGuideKind);
                            if (routeGuideKind == RouteGuideKind.NE_Maneuver_Kind_PassRoad_Left || routeGuideKind == RouteGuideKind.NE_Maneuver_Kind_PassRoad_Right || routeGuideKind == RouteGuideKind.NE_Maneuver_Kind_Right_PassRoad_Front || routeGuideKind == RouteGuideKind.NE_Maneuver_Kind_Right_PassRoad_UTurn)
                              
                                if (routeGuideKind == RouteGuideKind.NE_Maneuver_Kind_RightDiagonal_PassRoad_Front || routeGuideKind == RouteGuideKind.NE_Maneuver_Kind_RightDiagonal_PassRoad_Left || routeGuideKind == RouteGuideKind.NE_Maneuver_Kind_RightDiagonal_PassRoad_Left_Front || routeGuideKind == RouteGuideKind.NE_Maneuver_Kind_RightDiagonal_PassRoad_Right || routeGuideKind == RouteGuideKind.NE_Maneuver_Kind_RightDiagonal_PassRoad_Right_Back || routeGuideKind == RouteGuideKind.NE_Maneuver_Kind_RightDiagonal_PassRoad_Right_Front)
                               
                        }

                        /**
                         * @Description: 诱导信息 
                         */
                        @Override
                        public void onRoadGuideTextUpdate(CharSequence charSequence, CharSequence
                                charSequence1) {
                            Log.d(TAG, "onRoadGuideTextUpdate   charSequence=: " + charSequence + "   charSequence1 = : " +
                                    charSequence1);
                            orient = charSequence.toString() + charSequence1.toString();

                        }

                        /**
                         *
                         * @Description: 总剩余距离回调 
                         */
                        @Override
                        public void onRemainDistanceUpdate(CharSequence charSequence) {
                            Log.d(TAG, "onRemainDistanceUpdate: charSequence = :" + charSequence);
                            if (isPreSPEAKtotal) {                                
                            }
                        }

                        /**
                         *
                         * @Description: 总剩余时间回调
                         * @Author: LY
                         */
                        @Override
                        public void onRemainTimeUpdate(CharSequence charSequence) {
                            Log.d(TAG, "onRemainTimeUpdate: charSequence = :" + charSequence);
                            if (isPreSPEAKtotal) {                              
                                isPreSPEAKtotal = false;
                            }
                        }

                      
                        @Override
                        public void onGpsStatusChange(CharSequence charSequence, Drawable drawable) {
                            Log.d(TAG, "onGpsStatusChange: charSequence = :" + charSequence);

                        }

                      
                        @Override
                        public void onRouteFarAway(CharSequence charSequence, Drawable drawable) {
                            Log.d(TAG, "onRouteFarAway: charSequence = :" + charSequence);                           
                        }

                        /**                        
                         * @Description: 偏航规划中 
                         */
                        @Override
                        public void onRoutePlanYawing(CharSequence charSequence, Drawable drawable) {
                            Log.d(TAG, "onRoutePlanYawing: charSequence = :" + charSequence);
                        
                        }

                        /**
                         *
                         * @Description: 重新算路成功  
                         */
                        @Override
                        public void onReRouteComplete() {                          
                        }

                        /**
                         *
                         * @Description: 到达目的地回调   
                         */
                        @Override
                        public void onArriveDest() {                       
                            handler.sendEmptyMessageDelayed(0x003, 6000);
                        }
                       
                        @Override
                        public void onIndoorEnd(Message msg) {

                        }
                      
                        @Override
                        public void onFinalEnd(Message msg) {

                        }
                       
                        @Override
                        public void onVibrate() {

                        }
                    });
            handler.sendEmptyMessage(0x001);
            handler.sendEmptyMessage(0x002);
        }

        @Override
        public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions,
                                               int[] grantResults) {
            super.onRequestPermissionsResult(requestCode, permissions, grantResults);
            if (requestCode == ArCameraView.WALK_AR_PERMISSION) {
                if (grantResults.length > 0 && grantResults[0] == PackageManager.PERMISSION_DENIED) {
                    Toast.makeText(WNaviGuideActivity.this, "没有相机权限,请打开后重试", Toast.LENGTH_SHORT).show();
                } else if (grantResults.length > 0 && grantResults[0] == PackageManager.PERMISSION_GRANTED) {
                    mNaviHelper.startCameraAndSetMapView(WNaviGuideActivity.this);
                }
            }
        }
    }

Android Studio调用百度地图(三):定位数据实时上传到云端数据库

完整代码下载
BaiDuDemoTest

你可能感兴趣的:(Android,Studio)