This commit is contained in:
wangcongtao
2021-01-18 16:45:02 +08:00
parent 53c0a936cf
commit be3654f6c4
12 changed files with 640 additions and 18 deletions

View File

@@ -0,0 +1,21 @@
package com.mogo.och.taxi;
public
/**
* @author congtaowang
* @since 2021/1/18
*
* 网约车-出租车到站回调
*/
interface IMogoOCHTaxiArriveCallback {
/**
* 到达起始站
*/
void onArriveAtStartStation();
/**
* 到达终点站
*/
void onArriveAtEndStation();
}

View File

@@ -7,6 +7,7 @@ import androidx.fragment.app.FragmentActivity;
import com.alibaba.android.arouter.facade.annotation.Route;
import com.mogo.och.IMogoOCH;
import com.mogo.och.OCHConstants;
import com.mogo.och.taxi.ui.OCHTaxiUiController;
import com.mogo.utils.logger.Logger;
public
@@ -23,12 +24,12 @@ class MogoOCHTaxi implements IMogoOCH {
@Override
public void init( FragmentActivity activity, int containerId ) {
MogoOCHTaxiModel.getInstance().init( activity.getApplicationContext() );
OCHTaxiUiController.getInstance().init( activity, containerId );
}
@Override
public void init( Context context ) {
Logger.d( TAG, "init" );
MogoOCHTaxiModel.getInstance().init( context );
}
}

View File

@@ -1,18 +1,25 @@
package com.mogo.och.taxi;
import android.content.Context;
import android.location.Location;
import android.text.TextUtils;
import com.mogo.commons.data.BaseData;
import com.mogo.commons.network.SubscribeImpl;
import com.mogo.map.MogoLatLng;
import com.mogo.map.navi.IMogoCarLocationChangedListener2;
import com.mogo.module.common.MogoApisHandler;
import com.mogo.module.common.constants.HostConst;
import com.mogo.och.taxi.ui.OCHTaxiUiController;
import com.mogo.service.adas.IMogoAdasOCHCallback;
import com.mogo.service.adas.RemoteControlAutoPilotParameters;
import com.mogo.service.adas.entity.AdasOCHData;
import com.mogo.service.connection.IMogoOnMessageListener;
import com.mogo.utils.CoordinateUtils;
import com.mogo.utils.logger.Logger;
import com.mogo.utils.network.RequestOptions;
import com.mogo.utils.network.utils.GsonUtil;
import com.mogo.utils.storage.SharedPrefsMgr;
import io.reactivex.android.schedulers.AndroidSchedulers;
import io.reactivex.schedulers.Schedulers;
@@ -29,9 +36,6 @@ class MogoOCHTaxiModel {
private static final String TAG = "MogoOCHTaxiModel";
private static volatile MogoOCHTaxiModel sInstance;
private Context mContext;
private OCHTaxiResponse mCurrentOCHOrder;
private OCHArriveNotifyCallback mNotifyCallback;
private MogoOCHTaxiModel() {
}
@@ -47,9 +51,33 @@ class MogoOCHTaxiModel {
return sInstance;
}
/**
* 订单信息
*/
public static final String SP_KEY_OCH_TAXI_ORDER = "SP_KEY_OCH_TAXI_ORDER";
/**
* 是否已开启自动驾驶
*/
public static final String SP_KEY_START_AUTO_PILOT = "SP_KEY_START_AUTO_PILOT";
private OrderMsgListener mOrderMsgListener;
private OrderStatusMsgListener mOrderStatusMsgListener;
private OCHTaxiServiceApi mOCHTaxiServiceApi;
private Context mContext;
private OCHTaxiResponse mCurrentOCHOrder;
private OCHArriveNotifyCallback mNotifyCallback;
private IMogoCarLocationChangedListener2 mCarLocationChangedListener2;
/**
* 是否达到起始站点
*/
private boolean mIsArriveAtStartStation = false;
/**
* 是否达到终点
*/
private boolean mIsArriveAtEndStation = false;
private Object readResolve() {
// 阻止反序列化,必须实现 Serializable 接口
@@ -72,8 +100,71 @@ class MogoOCHTaxiModel {
.getAdasControllerApi()
.addAdasOCHCallback( mNotifyCallback = new OCHArriveNotifyCallback() );
// 订单恢复
// String orderInfo = SharedPrefsMgr.getInstance( mContext ).getString( SP_KEY_OCH_TAXI_ORDER );
// if ( !TextUtils.isEmpty( orderInfo ) ) {
// mCurrentOCHOrder = GsonUtil.objectFromJson( orderInfo, OCHTaxiResponse.class );
// if ( mCurrentOCHOrder == null ) {
// return;
// }
// if ( !isAutoPilotStarted() ) {
// mOrderMsgListener.onMsgReceived( mCurrentOCHOrder );
// }
// }
}
/**
* 自车定位
*/
private class LocationListener implements IMogoCarLocationChangedListener2 {
@Override
public void onCarLocationChanged2( Location location ) {
onLocationChanged( location );
}
@Override
public void onCarLocationChanged( MogoLatLng latLng ) {
}
}
/**
* 位置变化时通过围栏5M判断是否到达起点
*
* @param location
*/
private void onLocationChanged( Location location ) {
if ( location == null ) {
return;
}
if ( !checkCurrentOCHOrder() ) {
return;
}
if ( mIsArriveAtStartStation ) {
unregisterCarLocationListener();
return;
}
OCHTaxiResponse.OCHTaxiStation station = mCurrentOCHOrder.drivingRoutes.get( 0 );//起点
double distance = CoordinateUtils.calculateLineDistance( station.lon, station.lat, location.getLongitude(), location.getLatitude() );
if ( distance <= 5 ) {
mIsArriveAtStartStation = true;
unregisterCarLocationListener();
OCHTaxiUiController.getInstance().onArriveAtStartStation();
return;
}
}
/**
* 是否已到达起始站
*/
public boolean isArriveAtStartStation() {
return mIsArriveAtStartStation;
}
/**
* 后端长链推送通知新订单
*/
private class OrderMsgListener implements IMogoOnMessageListener< OCHTaxiResponse > {
@Override
public Class< OCHTaxiResponse > target() {
@@ -82,10 +173,65 @@ class MogoOCHTaxiModel {
@Override
public void onMsgReceived( OCHTaxiResponse obj ) {
if ( mCurrentOCHOrder != null ) {
Logger.e( TAG, "有订单尚未结束" );
return;
}
mCurrentOCHOrder = obj;
cacheOrderInfo2Native( mCurrentOCHOrder );
Location location = MogoApisHandler.getInstance()
.getApis()
.getMapServiceApi()
.getNavi( mContext )
.getCarLocation2();
onLocationChanged( location );
if ( !isArriveAtStartStation() ) {
registerCarLocationListener();
}
OCHTaxiUiController.getInstance().addFragment();
}
}
/**
* 保存订单到本地,避免车机重启丢失数据
*
* @param obj
*/
private void cacheOrderInfo2Native( OCHTaxiResponse obj ) {
if ( obj == null ) {
return;
}
SharedPrefsMgr.getInstance( mContext )
.putString( SP_KEY_OCH_TAXI_ORDER, GsonUtil.jsonFromObject( obj ) );
}
/**
* 达到起始站围栏监听
*/
private void registerCarLocationListener() {
MogoApisHandler.getInstance()
.getApis()
.getRegisterCenterApi()
.registerCarLocationChangedListener( TAG,
mCarLocationChangedListener2 == null ? mCarLocationChangedListener2 = new LocationListener() : mCarLocationChangedListener2 );
}
/**
* 注销到达起始站围栏监听
*/
private void unregisterCarLocationListener() {
if ( mCarLocationChangedListener2 == null ) {
return;
}
MogoApisHandler.getInstance()
.getApis()
.getRegisterCenterApi()
.unregisterCarLocationChangedListener( TAG, mCarLocationChangedListener2 );
}
/**
* 后端长链推送通知订单状态被改变
*/
private class OrderStatusMsgListener implements IMogoOnMessageListener< OCHTaxiOrderStatusResponse > {
@Override
@@ -110,14 +256,29 @@ class MogoOCHTaxiModel {
}
}
/**
* 自动驾驶本地通知订单到站
*/
private class OCHArriveNotifyCallback implements IMogoAdasOCHCallback {
@Override
public void onArriveAt( AdasOCHData data ) {
if ( data == null ) {
return;
}
if ( mIsArriveAtEndStation ) {
return;
}
if ( !checkCurrentOCHOrder() ) {
return;
}
mIsArriveAtEndStation = true;
OCHTaxiUiController.getInstance().onArriveAtEndStation();
}
}
/**
* 更新订单状态
*
* @param orderStatus 订单状态
*/
public void updateOCHOrderStatus( OCHOrderStatus orderStatus, OCHOrderStatusCallback callback ) {
@@ -160,19 +321,34 @@ class MogoOCHTaxiModel {
} );
}
/**
* 清除订单信息
*/
public void clearCurrentOCHOrder() {
mCurrentOCHOrder = null;
mIsArriveAtStartStation = false;
mIsArriveAtEndStation = false;
SharedPrefsMgr.getInstance( mContext ).remove( SP_KEY_OCH_TAXI_ORDER );
markAutoPilotStartedStatus( false );
}
private boolean checkCurrentOCHOrder() {
/**
* 检测当前订单
*
* @return
*/
public boolean checkCurrentOCHOrder() {
if ( mCurrentOCHOrder != null
&& mCurrentOCHOrder.drivingRoute != null
&& mCurrentOCHOrder.drivingRoute.size() >= 2 ) {
&& mCurrentOCHOrder.drivingRoutes != null
&& mCurrentOCHOrder.drivingRoutes.size() >= 2 ) {
return true;
}
return false;
}
/**
* 以当前订单为基础,开启自动驾驶
*/
public void startAutoPilot() {
if ( !checkCurrentOCHOrder() ) {
Logger.e( TAG, "no order or order is empty." );
@@ -180,12 +356,40 @@ class MogoOCHTaxiModel {
}
RemoteControlAutoPilotParameters parameters = new RemoteControlAutoPilotParameters();
parameters.vehicleType = mCurrentOCHOrder.orderType;
parameters.startLatLon = new RemoteControlAutoPilotParameters.AutoPilotLonLat( mCurrentOCHOrder.drivingRoute.get( 0 ).lat, mCurrentOCHOrder.drivingRoute.get( 0 ).lon );
parameters.endLatLon = new RemoteControlAutoPilotParameters.AutoPilotLonLat( mCurrentOCHOrder.drivingRoute.get( 1 ).lat, mCurrentOCHOrder.drivingRoute.get( 1 ).lon );
parameters.startLatLon = new RemoteControlAutoPilotParameters.AutoPilotLonLat( mCurrentOCHOrder.drivingRoutes.get( 0 ).lat, mCurrentOCHOrder.drivingRoutes.get( 0 ).lon );
parameters.endLatLon = new RemoteControlAutoPilotParameters.AutoPilotLonLat( mCurrentOCHOrder.drivingRoutes.get( 1 ).lat, mCurrentOCHOrder.drivingRoutes.get( 1 ).lon );
MogoApisHandler.getInstance()
.getApis()
.getAdasControllerApi()
.aiCloudToAdasData( parameters );
markAutoPilotStartedStatus( true );
Logger.d( TAG, "start autopilot with parameter: %s", GsonUtil.jsonFromObject( parameters ) );
}
/**
* 标记开启自动驾驶
*
* @param started
*/
private void markAutoPilotStartedStatus( boolean started ) {
SharedPrefsMgr.getInstance( mContext ).putBoolean( SP_KEY_START_AUTO_PILOT, started );
}
/**
* 判断已开启自动驾驶
*
* @return
*/
private boolean isAutoPilotStarted() {
return SharedPrefsMgr.getInstance( mContext ).getBoolean( SP_KEY_START_AUTO_PILOT, false );
}
/**
* 获取当前订单
*
* @return
*/
public OCHTaxiResponse getCurrentOCHOrder() {
return mCurrentOCHOrder;
}
}

View File

@@ -1,5 +1,8 @@
package com.mogo.och.taxi;
import android.os.Parcel;
import android.os.Parcelable;
import java.util.List;
public
@@ -9,7 +12,7 @@ public
*
* 描述
*/
class OCHTaxiResponse {
class OCHTaxiResponse implements Parcelable {
// 订单号
public String orderNo;
@@ -24,12 +27,101 @@ class OCHTaxiResponse {
// 起始站目的站距离km
public double travelDistance;
// 站点
public List< OCHTaxiStation > drivingRoute;
public List< OCHTaxiStation > drivingRoutes;
public static class OCHTaxiStation {
public static class OCHTaxiStation implements Parcelable {
public int siteId;
public String siteName;
public double lon;
public double lat;
@Override
public int describeContents() {
return 0;
}
@Override
public void writeToParcel( Parcel dest, int flags ) {
dest.writeInt( this.siteId );
dest.writeString( this.siteName );
dest.writeDouble( this.lon );
dest.writeDouble( this.lat );
}
public OCHTaxiStation() {
}
protected OCHTaxiStation( Parcel in ) {
this.siteId = in.readInt();
this.siteName = in.readString();
this.lon = in.readDouble();
this.lat = in.readDouble();
}
public static final Creator< OCHTaxiStation > CREATOR = new Creator< OCHTaxiStation >() {
@Override
public OCHTaxiStation createFromParcel( Parcel source ) {
return new OCHTaxiStation( source );
}
@Override
public OCHTaxiStation[] newArray( int size ) {
return new OCHTaxiStation[size];
}
};
}
public OCHTaxiResponse() {
}
@Override
public int describeContents() {
return 0;
}
@Override
public void writeToParcel( Parcel dest, int flags ) {
dest.writeString( this.orderNo );
dest.writeInt( this.orderType );
dest.writeString( this.startStation );
dest.writeString( this.endStation );
dest.writeInt( this.orderDispatchType );
dest.writeDouble( this.travelDistance );
dest.writeTypedList( this.drivingRoutes );
}
protected OCHTaxiResponse( Parcel in ) {
this.orderNo = in.readString();
this.orderType = in.readInt();
this.startStation = in.readString();
this.endStation = in.readString();
this.orderDispatchType = in.readInt();
this.travelDistance = in.readDouble();
this.drivingRoutes = in.createTypedArrayList( OCHTaxiStation.CREATOR );
}
public static final Creator< OCHTaxiResponse > CREATOR = new Creator< OCHTaxiResponse >() {
@Override
public OCHTaxiResponse createFromParcel( Parcel source ) {
return new OCHTaxiResponse( source );
}
@Override
public OCHTaxiResponse[] newArray( int size ) {
return new OCHTaxiResponse[size];
}
};
@Override
public String toString() {
return "OCHTaxiResponse{" +
"orderNo='" + orderNo + '\'' +
", orderType=" + orderType +
", startStation='" + startStation + '\'' +
", endStation='" + endStation + '\'' +
", orderDispatchType=" + orderDispatchType +
", travelDistance=" + travelDistance +
", drivingRoutes=" + drivingRoutes +
'}';
}
}

View File

@@ -0,0 +1,118 @@
package com.mogo.och.taxi.ui;
import android.os.Bundle;
import android.widget.Button;
import android.widget.TextView;
import androidx.annotation.NonNull;
import com.mogo.commons.mvp.MvpFragment;
import com.mogo.module.common.MogoApisHandler;
import com.mogo.och.taxi.IMogoOCHTaxiArriveCallback;
import com.mogo.och.taxi.MogoOCHTaxiModel;
import com.mogo.och.taxi.R;
import com.mogo.service.statusmanager.IMogoStatusChangedListener;
import com.mogo.service.statusmanager.StatusDescriptor;
import com.mogo.utils.logger.Logger;
public
/**
* @author congtaowang
* @since 2021/1/18
*
* 网约车-出租车UI
*/
class OCHTaxiFragment extends MvpFragment< OCHTaxiView, OCHTaxiPresenter > implements OCHTaxiView,
IMogoStatusChangedListener, IMogoOCHTaxiArriveCallback {
public static final String TAG = "OCHTaxiFragment";
public static OCHTaxiFragment newInstance() {
Bundle args = new Bundle();
OCHTaxiFragment fragment = new OCHTaxiFragment();
fragment.setArguments( args );
return fragment;
}
private TextView orderInfo;
private Button autoPilot;
@Override
protected int getLayoutId() {
return R.layout.module_och_taxi_fragment;
}
@Override
protected void initViews() {
orderInfo = findViewById( R.id.orderInfo );
autoPilot = findViewById( R.id.autoPilot );
orderInfo.setText( MogoOCHTaxiModel.getInstance().getCurrentOCHOrder().toString() );
autoPilot.setOnClickListener( view -> {
MogoOCHTaxiModel.getInstance().startAutoPilot();
} );
if ( MogoApisHandler.getInstance()
.getApis()
.getStatusManagerApi()
.isVrMode() ) {
vrMode();
} else {
flatMode();
}
initListeners();
}
private void initListeners() {
MogoApisHandler.getInstance()
.getApis()
.getStatusManagerApi()
.registerStatusChangedListener( TAG, StatusDescriptor.VR_MODE, this );
OCHTaxiUiController.getInstance().setOCHTaxiArriveCallback( this );
}
@NonNull
@Override
protected OCHTaxiPresenter createPresenter() {
return new OCHTaxiPresenter( this );
}
@Override
public void onStatusChanged( StatusDescriptor descriptor, boolean isTrue ) {
if ( isTrue ) {
vrMode();
} else {
flatMode();
}
}
private void vrMode() {
}
private void flatMode() {
}
@Override
public void onArriveAtStartStation() {
Logger.d( TAG, "达到起点" );
}
@Override
public void onArriveAtEndStation() {
Logger.d( TAG, "达到终点" );
}
@Override
public void onDestroyView() {
super.onDestroyView();
MogoApisHandler.getInstance()
.getApis()
.getStatusManagerApi()
.unregisterStatusChangedListener( TAG, StatusDescriptor.VR_MODE, this );
OCHTaxiUiController.getInstance().setOCHTaxiArriveCallback( null );
}
}

View File

@@ -0,0 +1,34 @@
package com.mogo.och.taxi.ui;
import androidx.annotation.NonNull;
import androidx.lifecycle.LifecycleOwner;
import com.mogo.commons.mvp.Presenter;
import com.mogo.utils.logger.Logger;
public
/**
* @author congtaowang
* @since 2021/1/18
*
* 描述
*/
class OCHTaxiPresenter extends Presenter< OCHTaxiView > {
private static final String TAG = "OCHTaxiPresenter";
public OCHTaxiPresenter( OCHTaxiView view ) {
super( view );
}
@Override
public void onCreate( @NonNull LifecycleOwner owner ) {
super.onCreate( owner );
Logger.d( TAG, "网约车-出租车拿到订单" );
}
@Override
public void onDestroy( @NonNull LifecycleOwner owner ) {
super.onDestroy( owner );
}
}

View File

@@ -0,0 +1,119 @@
package com.mogo.och.taxi.ui;
import android.os.Looper;
import androidx.fragment.app.Fragment;
import androidx.fragment.app.FragmentActivity;
import androidx.fragment.app.FragmentManager;
import com.mogo.och.taxi.IMogoOCHTaxiArriveCallback;
import com.mogo.och.taxi.MogoOCHTaxiModel;
import com.mogo.utils.UiThreadHandler;
import com.mogo.utils.logger.Logger;
public
/**
* @author congtaowang
* @since 2021/1/18
*
* 控制UI显示
*/
class OCHTaxiUiController implements IMogoOCHTaxiArriveCallback {
private static final String TAG = "OCHTaxiUiController";
private static volatile OCHTaxiUiController sInstance;
private FragmentActivity mActivity;
private int mContainerId;
private IMogoOCHTaxiArriveCallback mOCHTaxiArriveCallback;
private OCHTaxiUiController() {
}
public static OCHTaxiUiController getInstance() {
if ( sInstance == null ) {
synchronized ( OCHTaxiUiController.class ) {
if ( sInstance == null ) {
sInstance = new OCHTaxiUiController();
}
}
}
return sInstance;
}
private Object readResolve() {
// 阻止反序列化,必须实现 Serializable 接口
return sInstance;
}
public void init( FragmentActivity activity, int containerId ) {
mActivity = activity;
mContainerId = containerId;
addFragment();
}
public void addFragment() {
if ( Looper.myLooper() != Looper.getMainLooper() ) {
UiThreadHandler.post( () -> {
addFragmentImpl();
} );
} else {
addFragmentImpl();
}
}
private void addFragmentImpl() {
if ( !MogoOCHTaxiModel.getInstance().checkCurrentOCHOrder() ) {
return;
}
Fragment fragment = null;
FragmentManager fragmentManager = mActivity.getSupportFragmentManager();
fragment = fragmentManager.findFragmentByTag( OCHTaxiFragment.TAG );
if ( fragment == null ) {
fragment = OCHTaxiFragment.newInstance();
}
mActivity.getSupportFragmentManager()
.beginTransaction()
.replace( mContainerId, fragment, OCHTaxiFragment.TAG )
.commitNowAllowingStateLoss();
Logger.d( TAG, "add fragment" );
}
public void removeFragment() {
Fragment fragment = null;
FragmentManager fragmentManager = mActivity.getSupportFragmentManager();
fragment = fragmentManager.findFragmentByTag( OCHTaxiFragment.TAG );
if ( fragment == null ) {
return;
}
fragmentManager.beginTransaction()
.remove( fragment )
.commitNowAllowingStateLoss();
}
public void setOCHTaxiArriveCallback( IMogoOCHTaxiArriveCallback OCHTaxiArriveCallback ) {
this.mOCHTaxiArriveCallback = OCHTaxiArriveCallback;
}
public IMogoOCHTaxiArriveCallback getOCHTaxiArriveCallback() {
return mOCHTaxiArriveCallback;
}
@Override
public void onArriveAtStartStation() {
if ( mOCHTaxiArriveCallback != null ) {
mOCHTaxiArriveCallback.onArriveAtEndStation();
}
}
@Override
public void onArriveAtEndStation() {
if ( mOCHTaxiArriveCallback != null ) {
mOCHTaxiArriveCallback.onArriveAtEndStation();
}
}
}

View File

@@ -0,0 +1,13 @@
package com.mogo.och.taxi.ui;
import com.mogo.commons.mvp.IView;
public
/**
* @author congtaowang
* @since 2021/1/18
*
* 描述
*/
interface OCHTaxiView extends IView {
}

View File

@@ -0,0 +1,21 @@
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:gravity="center"
android:orientation="vertical">
<TextView
android:id="@+id/orderInfo"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="kong"
android:textColor="#FFFFFF"
android:textSize="20px" />
<Button
android:id="@+id/autoPilot"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="开启自动驾驶" />
</LinearLayout>

View File

@@ -21,7 +21,7 @@ public class CarSeries {
if ( invokeFlag ) {
return isF8xxSeries;
}
isF8xxSeries = DebugConfig.getProductFlavor().startsWith( "f8" );
isF8xxSeries = DebugConfig.getProductFlavor().startsWith( "f" );
invokeFlag = true;
return isF8xxSeries;
}

View File

@@ -33,7 +33,7 @@ public class MogoRegisterCenterHandler implements IMogoRegisterCenter {
private Map< String, IMogoLocationListener > mLocation = new HashMap<>();
private Map< String, IMogoMarkerClickListener > mMarker = new HashMap<>();
private Map< String, IMogoAimlessModeListener > mAimless = new HashMap<>();
private Map< String, IMogoCarLocationChangedListener > mCarLocations = new HashMap<>();
private Map< String, IMogoCarLocationChangedListener > mCarLocations = new ConcurrentHashMap<>();
private Map< String, IMogoADASControlStatusChangedListener > mADAS = new HashMap<>();
private MogoRegisterCenterHandler() {
@@ -190,7 +190,7 @@ public class MogoRegisterCenterHandler implements IMogoRegisterCenter {
}
@Override
public Iterator<IMogoADASControlStatusChangedListener > getAdasControlStatusChangedListeners(){
public Iterator< IMogoADASControlStatusChangedListener > getAdasControlStatusChangedListeners() {
return mADAS.values().iterator();
}
}

View File

@@ -92,5 +92,4 @@
android:layout_width="match_parent"
android:layout_height="match_parent" />
</FrameLayout>