仿滴滴打車司機接單,通知乘客,實時更新司機位置和與乘客之間距離的實現


首先是要司機端和乘客端能夠通信,我原本是想自己用Socket實現,但是socket的話要涉及到兩個端

的用戶的IP和端口,而端口需要尋找一個可用的端口,手機開關機的過程會端口也可能會被占用,好像

並不太容易,於是我從之前用環信即時聊天這個里面得到一點啟發,今天試了一下的確可以的,特意記

錄一下:

 

首先司機出發的時候,即點擊導航的時候,代表去接客,這時候往乘客端發送一條出發的信息

然后高德地圖會有開始導航的接口,也有位置改變的接口,所以在這個接口里面將對應的消息發給乘客就行

    /*
    * @param start開始點 end終點 wayList途經點
    * */
    public void voiceNavi(LatLng start,LatLng end,List<Poi> wayList) {
        //將百度地圖坐標轉化為高德地圖坐標
        double[] startConverted  = GPSConvert.bd09_To_Gcj02(start.latitude,start.longitude);
        double[] endConverted = GPSConvert.bd09_To_Gcj02(end.latitude,end.longitude);
        //包裝成高德地圖的點
        Poi startloc = new Poi("當前位置", new com.amap.api.maps.model.LatLng(startConverted[0],startConverted[1]), "");
        Poi endloc = new Poi("目的地", new com.amap.api.maps.model.LatLng(endConverted[0], endConverted[1]), "B000A83M61");
        //進入導航界面
        AmapNaviPage.getInstance().showRouteActivity(Driver.this, new AmapNaviParams(startloc, wayList, endloc, AmapNaviType.DRIVER), new INaviInfoCallback() {
            @Override
            public void onInitNaviFailure() {
                Toast.makeText(Driver.this,"導航失敗,請手動打開GPS權限",Toast.LENGTH_LONG).show();
            }

            @Override
            public void onGetNavigationText(String s) {

            }

            /*
            * 位置改變將位置發給乘客
            * */
            @Override
            public void onLocationChange(AMapNaviLocation aMapNaviLocation) {
                //高德地圖轉百度地圖坐標
                NaviLatLng latLng = aMapNaviLocation.getCoord();
                double[] lng = GPSConvert.gcj02_To_Bd09(latLng.getLatitude(),latLng.getLongitude());
                //標志位location字段,代表位置
                String content = "location,"+String.valueOf(lng[0])+","+String.valueOf(lng[1]);
                try{
                    //這個List代表沿路的乘客
                    if (onRoadPassengers!=null&&onRoadPassengers.size()!=0){
                        for (int j = 0;j < onRoadPassengers.size();j++){
                            String tel = onRoadPassengers.get(j).getString("userid");
                            //將此信息發給對應的乘客
                            sendMessage(content,tel);
                        }
                    }
                }catch (JSONException e){

                }catch (NullPointerException e){
                    Toast.makeText(getApplicationContext(),"請在地圖上選擇一個目的地",Toast.LENGTH_SHORT).show();
                }
            }

            @Override
            public void onArriveDestination(boolean b) {
                //到達目的地
            }

            @Override
            public void onStartNavi(int i) {
                //啟動導航
                try{
                    if (onRoadPassengers!=null&&onRoadPassengers.size()!=0){
                        for (int j = 0;j < onRoadPassengers.size();j++){
                            String tel = onRoadPassengers.get(j).getString("userid");
                            Log.d("出發發送信息給",tel);
                            //發送start 表示出發
                            sendMessage("start",tel);
                            Message message = new Message();
                            message.what = 3;
                            Bundle bundle = new Bundle();
                            bundle.putString("data",tel);
                            message.setData(bundle);
                            handler.sendMessage(message);
                        }
                    }
                }catch (JSONException e){

                }catch (NullPointerException e){
                    Toast.makeText(getApplicationContext(),"請在地圖上選擇一個目的地",Toast.LENGTH_SHORT).show();
                }
            }

            @Override
            public void onCalculateRouteSuccess(int[] ints) {
                //算路成功
            }

            @Override
            public void onCalculateRouteFailure(int i) {
                //算路失敗
            }

            @Override
            public void onStopSpeaking() {
                //停止語音
            }

            @Override
            public void onReCalculateRoute(int i) {

            }

            @Override
            public void onExitPage(int i) {

            }

            @Override
            public void onStrategyChanged(int i) {

            }

            @Override
            public View getCustomNaviBottomView() {
                return null;
            }

            @Override
            public View getCustomNaviView() {
                return null;
            }

            @Override
            public void onArrivedWayPoint(int i) {
                //到達第幾個wayPoint

            }
        });
    }

 

之后是乘客端:

乘客端的地圖界面,即主界面需要實現一個信息接收的監聽接口

    private class MessageListener implements  EMMessageListener{

        /*
        * 接收信息的接口
        * */
        @Override
        public void onMessageReceived(List<EMMessage> messages) {
            Log.d("messageListener",".....");
            for (int i = 0; i < messages.size(); i++) {
                String content = ((EMTextMessageBody) messages.get(i).getBody()).getMessage();
                if (content.equals("start")){
                    //如果標志位是start,則代表司機出發,這里非UI線程不能用Toast,所以用了Handle
                    Message message = new Message();
                    message.what = 1;
                    UIHandler.sendMessage(message);
                }
                if (content.split(",")[0].equals("location")){
                    //如果是location,代表司機的位置
                    Double lat = Double.parseDouble(content.split(",")[1]);
                    Double lng = Double.parseDouble(content.split(",")[2]);
                    MarkerOptions options = new MarkerOptions().position(new LatLng(lat,lng)).icon(BitmapDescriptorFactory.fromResource(R.drawable.look_for_car));
                    baiduMap.addOverlay(options);
                    //將司機位置和乘客之間的路線呈現在地圖上
                    //第一個參數代表自己的位置(測試點),第二個參數代表司機的位置,是傳過來的,第三個是途徑點,這里設為空
                    startGo(new LatLng(27.899096,112.923213),new LatLng(lat,lng),new ArrayList<PlanNode>());
                    new Thread(new Runnable() {
                        @Override
                        public void run() {
                            baiduMap.clear();
                            try{
                                Thread.sleep(3000);
                            }catch (InterruptedException e){

                            }
                        }
                    }).start();
                }
            }
        }

        @Override
        public void onCmdMessageReceived(List<EMMessage> messages) {

        }

        @Override
        public void onMessageRead(List<EMMessage> messages) {

        }

        @Override
        public void onMessageDelivered(List<EMMessage> messages) {

        }

        @Override
        public void onMessageChanged(EMMessage message, Object change) {

        }
    }

  

OK,到這里簡單的交互實現了,可能我的方法笨了點...

效果圖在這里

司機端

乘客端

 

項目地址:https://github.com/Yintianhao/Car-master


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM