天天看點

Android Studio調用百度地圖(二):實作地圖顯示背景定位和步行導航

先看一下運作效果:

Android Studio調用百度地圖(二):實作地圖顯示背景定位和步行導航
Android Studio調用百度地圖(二):實作地圖顯示背景定位和步行導航
Android Studio調用百度地圖(二):實作地圖顯示背景定位和步行導航

實作功能:背景定位+步行導航(可通過長按螢幕自定義終點,起點為定位點)

背景定位即當程式在背景時依舊執行定位功能,步行導航支援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調用百度地圖(二):實作地圖顯示背景定位和步行導航

二 調用百度地圖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