首先是要司机端和乘客端能够通信,我原本是想自己用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