[merge2master]

This commit is contained in:
yangyakun
2023-03-28 17:32:58 +08:00
2838 changed files with 73081 additions and 69058 deletions

View File

@@ -0,0 +1,15 @@
src
- androidTest Android 测试代码
- basecommon 金旅开沃、接驳车 公用代码部分
- jinlvvan 金旅开沃 独立代码部分
- m1 金旅m1 独立代码部分
- m2 金旅m2 独立代码部分
- main 所有车型公用代码部分
- shuttle 接驳车独立代码 因为接驳车和金旅开沃代码耦合厉害暂时放入到mogo-och-bus-passenger里面
后期会创建独立module和mogo-och-bus-passenger平级
- test 普通代码测试

View File

@@ -2,6 +2,7 @@ apply plugin: 'com.android.library'
apply plugin: 'com.alibaba.arouter'
apply plugin: 'kotlin-android'
apply plugin: 'kotlin-android-extensions'
apply plugin: 'kotlin-kapt'
android {
compileSdkVersion rootProject.ext.android.compileSdkVersion
@@ -16,9 +17,10 @@ android {
testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
consumerProguardFiles "consumer-rules.pro"
javaCompileOptions {
annotationProcessorOptions {
arguments = [AROUTER_MODULE_NAME: project.getName()]
kapt {
useBuildCache = false
arguments {
arg("AROUTER_MODULE_NAME", project.getName())
}
}
}
@@ -38,6 +40,26 @@ android {
proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro'
}
}
flavorDimensions "vehicle"
productFlavors {
// 车型:金旅星辰、开沃 小巴业务
jinlvvan {
dimension "vehicle"
buildConfigField 'int', 'NEW_TEST', '0'
}
// 车型金旅m1 小巴业务
m1 {
dimension "vehicle"
buildConfigField 'int', 'NEW_TEST', '1'
}
// 车型金旅m1 小巴业务
m2 {
dimension "vehicle"
buildConfigField 'int', 'NEW_TEST', '1'
}
}
}
dependencies {
@@ -47,28 +69,15 @@ dependencies {
implementation rootProject.ext.dependencies.arouter
implementation rootProject.ext.dependencies.androidxrecyclerview
implementation rootProject.ext.dependencies.material
annotationProcessor rootProject.ext.dependencies.aroutercompiler
kapt rootProject.ext.dependencies.aroutercompiler
implementation rootProject.ext.dependencies.rxandroid
implementation rootProject.ext.dependencies.androidxconstraintlayout
implementation rootProject.ext.dependencies.amapnavi3dmap
implementation project(":OCH:mogo-och-common-module")
if (Boolean.valueOf(USE_MAVEN_PACKAGE)) {
implementation rootProject.ext.dependencies.mogoutils
implementation rootProject.ext.dependencies.mogocommons
implementation rootProject.ext.dependencies.modulecommon
implementation rootProject.ext.dependencies.mogo_core_data
implementation rootProject.ext.dependencies.mogo_core_function_call
implementation rootProject.ext.dependencies.mogo_core_function_v2x
implementation rootProject.ext.dependencies.mogo_core_function_hmi
}else {
implementation project(":core:mogo-core-utils")
implementation project(":foudations:mogo-commons")
implementation project(':modules:mogo-module-common')
implementation project(':core:mogo-core-data')
implementation project(':core:mogo-core-function-call')
implementation project(':core:function-impl:mogo-core-function-v2x')
implementation project(':core:function-impl:mogo-core-function-hmi')
}
compileOnly project(":libraries:mogo-map")
implementation project(':core:mogo-core-res')
testImplementation 'junit:junit:4.12'
}
apply from: new File(rootProject.rootDir, "gradle/upload.gradle").toString()

View File

@@ -1,32 +1,32 @@
package com.mogo.och.bus.passenger;
import static com.mogo.eagle.core.utilcode.mogo.logger.scene.SceneConstant.M_TAXI_P;
import android.content.Context;
import androidx.fragment.app.Fragment;
import androidx.fragment.app.FragmentActivity;
import com.alibaba.android.arouter.facade.annotation.Route;
import com.mogo.commons.module.status.IMogoStatusChangedListener;
import com.mogo.commons.module.status.MogoStatusManager;
import com.mogo.commons.module.status.StatusDescriptor;
import com.mogo.eagle.core.data.config.FunctionBuildConfig;
import com.mogo.eagle.core.function.call.setting.CallerMoGoUiSettingManager;
import com.mogo.eagle.core.utilcode.mogo.AppIdentityModeUtils;
import com.mogo.eagle.core.utilcode.mogo.logger.CallerLogger;
import com.mogo.map.MogoMapUIController;
import com.mogo.eagle.core.utilcode.util.MultiDisplayUtils;
import com.mogo.och.bus.passenger.constant.BusPassengerConst;
import com.mogo.och.bus.passenger.ui.BusPassengerRouteFragment;
import com.mogo.och.common.module.wigets.video.VideoPlayerActivity;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import static com.mogo.eagle.core.utilcode.mogo.logger.scene.SceneConstant.M_TAXI_P;
/**
* 网约车-Bus-乘客端
*
* Created on 2022/3/29
*/
@Route(path = BusPassengerConst.PATH)
public class MogoOCHBusPassenger implements IMogoOCH, IMogoStatusChangedListener {
public class MogoOCHBusPassenger implements IMogoOCH {
private static final String TAG = MogoOCHBusPassenger.class.getSimpleName();
private FragmentActivity mActivity;
@@ -43,8 +43,11 @@ public class MogoOCHBusPassenger implements IMogoOCH, IMogoStatusChangedListener
public Fragment createCoverage(@Nullable FragmentActivity activity, @Nullable Integer containerId) {
this.mActivity = activity;
this.mContainerId = containerId;
showFragment();
// UiThreadHandler.post(() -> stepIntoVrMode());
if (AppIdentityModeUtils.isJL(FunctionBuildConfig.appIdentityMode)) {
MultiDisplayUtils.INSTANCE.startActWithSecond(activity, VideoPlayerActivity.class);
}
return null;
}
@@ -63,18 +66,6 @@ public class MogoOCHBusPassenger implements IMogoOCH, IMogoStatusChangedListener
@Override
public void init(Context context) {
MogoStatusManager.getInstance().registerStatusChangedListener("OchBus",StatusDescriptor.VR_MODE, this);
}
@Override
public void onStatusChanged(StatusDescriptor descriptor, boolean isTrue) {
if (descriptor == StatusDescriptor.VR_MODE) {
if (isTrue){
showFragment();
}else {
hideFragment();
}
}
}
/**
@@ -82,9 +73,6 @@ public class MogoOCHBusPassenger implements IMogoOCH, IMogoStatusChangedListener
*/
private void stepIntoVrMode() {
CallerLogger.INSTANCE.d( M_TAXI_P + TAG, "进入vr模式" );
MogoMapUIController.getInstance()
.stepInVrMode( true ); // 白天模式
CallerMoGoUiSettingManager.INSTANCE.stepInDayMode();//白天模式 状态栏字体颜色变黑
}

View File

@@ -0,0 +1,16 @@
package com.mogo.och.bus.passenger.bean;
public
/**
* @author congtaowang
* @since 2021/3/22
*
* 根据车机行驶线路站点信息
*/
class BusPassengerQueryLineRequest {
private String sn;
public BusPassengerQueryLineRequest(String sn) {
this.sn = sn;
}
}

View File

@@ -1,7 +1,6 @@
package com.mogo.och.bus.passenger.callback;
import com.amap.api.maps.model.LatLng;
import com.mogo.eagle.core.data.map.MogoLatLng;
import java.util.List;

View File

@@ -10,7 +10,7 @@ import java.util.List;
*/
public interface IBusPassengerRouteLineInfoCallback {
void updateLineInfo(String lineName, String lineDurTime);
void updateStationsInfo(List<BusPassengerStation> stations,int currentStationIndex,boolean isArrived);
void updateStationsInfo(List<BusPassengerStation> stations, int currentStationIndex, boolean isArrived);
void showNoTaskView();
void hideNoTaskView();
}

View File

@@ -0,0 +1,24 @@
package com.mogo.och.bus.passenger.constant
import com.mogo.commons.debug.DebugConfig
import com.mogo.eagle.core.data.config.FunctionBuildConfig
import com.mogo.eagle.core.utilcode.mogo.AppIdentityModeUtils
import com.mogo.och.common.module.biz.constant.OchCommonConst
/**
* Created on 2021/12/6
*/
class URLConst {
companion object {
@JvmStatic
fun getBaseUrl(): String {
return if(AppIdentityModeUtils.isShuttle(FunctionBuildConfig.appIdentityMode)){
OchCommonConst.getShuttleUrl()
}else{
OchCommonConst.getBaseUrl()
}
}
}
}

View File

@@ -1,5 +1,9 @@
package com.mogo.och.bus.passenger.model;
import static com.mogo.eagle.core.utilcode.mogo.logger.scene.SceneConstant.M_BUS_P;
import static com.mogo.och.bus.passenger.constant.BusPassengerConst.QUERY_BUS_P_STATION_DELAY;
import static com.mogo.och.bus.passenger.constant.BusPassengerConst.STATION_STATUS_STOPPED;
import android.content.Context;
import android.content.Intent;
import android.net.ConnectivityManager;
@@ -11,7 +15,6 @@ import androidx.annotation.Nullable;
import com.amap.api.maps.model.LatLng;
import com.mogo.aicloud.services.socket.MogoAiCloudSocketManager;
import com.mogo.cloud.commons.utils.CoordinateUtils;
import com.mogo.commons.debug.DebugConfig;
import com.mogo.commons.module.intent.IMogoIntentListener;
import com.mogo.commons.module.intent.IntentManager;
@@ -21,16 +24,17 @@ import com.mogo.commons.module.status.StatusDescriptor;
import com.mogo.eagle.core.data.autopilot.AutopilotStatusInfo;
import com.mogo.eagle.core.data.config.FunctionBuildConfig;
import com.mogo.eagle.core.data.map.MogoLocation;
import com.mogo.eagle.core.function.api.autopilot.IMoGoAutopilotPlanningListener;
import com.mogo.eagle.core.function.api.autopilot.IMoGoAutopilotStatusListener;
import com.mogo.eagle.core.function.api.map.listener.IMoGoMapLocationListener;
import com.mogo.eagle.core.function.api.autopilot.IMoGoChassisLocationGCJ02Listener;
import com.mogo.eagle.core.function.api.autopilot.IMoGoPlanningRottingListener;
import com.mogo.eagle.core.function.call.autopilot.CallerAutoPilotStatusListenerManager;
import com.mogo.eagle.core.function.call.autopilot.CallerAutopilotPlanningListenerManager;
import com.mogo.eagle.core.function.call.map.CallerMapLocationListenerManager;
import com.mogo.eagle.core.function.call.autopilot.CallerChassisLocationGCJ02ListenerManager;
import com.mogo.eagle.core.function.call.autopilot.CallerPlanningRottingListenerManager;
import com.mogo.eagle.core.network.utils.GsonUtil;
import com.mogo.eagle.core.utilcode.mogo.AppIdentityModeUtils;
import com.mogo.eagle.core.utilcode.mogo.logger.CallerLogger;
import com.mogo.eagle.core.utilcode.mogo.storage.SharedPrefsMgr;
import com.mogo.eagle.core.utilcode.util.CoordinateUtils;
import com.mogo.eagle.core.utilcode.util.NetworkUtils;
import com.mogo.eagle.core.utilcode.util.ToastUtils;
import com.mogo.och.bus.passenger.R;
@@ -49,6 +53,7 @@ import com.mogo.och.bus.passenger.network.BusPassengerServiceManager;
import com.mogo.och.common.module.biz.network.OchCommonServiceCallback;
import com.mogo.och.common.module.manager.AbnormalFactorsLoopManager;
import com.mogo.och.common.module.utils.CoordinateCalculateRouteUtil;
import org.jetbrains.annotations.NotNull;
import java.util.ArrayList;
@@ -60,10 +65,6 @@ import mogo.telematics.pad.MessagePad;
import mogo_msg.MogoReportMsg;
import system_master.SystemStatusInfo;
import static com.mogo.eagle.core.utilcode.mogo.logger.scene.SceneConstant.M_BUS_P;
import static com.mogo.och.bus.passenger.constant.BusPassengerConst.QUERY_BUS_P_STATION_DELAY;
import static com.mogo.och.bus.passenger.constant.BusPassengerConst.STATION_STATUS_STOPPED;
/**
* Created on 2022/3/31
*/
@@ -88,7 +89,7 @@ public class BusPassengerModel {
private IBusPassegerDriverStatusCallback mDriverStatusCallback; //出车收车状态
private IBusPassengerRouteLineInfoCallback mRouteLineInfoCallback; // bus路线信息更新
private MogoLocation mLocation = null;
private MogoLocation mLocation = null;
private BusPassengerRoutesResult routesResult = null;
@@ -140,6 +141,7 @@ public class BusPassengerModel {
public void onSuccess(BusPassengerOperationStatusResponse data) {
if (data == null || data.data == null) return;
if (mDriverStatusCallback != null) {
CallerLogger.INSTANCE.d( M_BUS_P + TAG, "queryDriverOperationStatus = %s", data.data.plateNumber );
mDriverStatusCallback.changeOperationStatus(data.data.driverStatus == 1);
mDriverStatusCallback.updatePlateNumber(data.data.plateNumber);
}
@@ -168,38 +170,43 @@ public class BusPassengerModel {
, new OchCommonServiceCallback<BusPassengerRoutesResponse>() {
@Override
public void onSuccess(BusPassengerRoutesResponse data) {
if ( data == null
|| data.getResult() == null
|| data.getResult().getSites() == null) {
routesResult = null;
mNextStationIndex = 0;
startOrStopCalculateRouteInfo(false);
if (mRouteLineInfoCallback != null){
mRouteLineInfoCallback.showNoTaskView();
if ( data == null || data.getResult() == null) {
CallerLogger.INSTANCE.d( M_BUS_P + TAG, "queryDriverSiteByCoordinate = null");
if (routesResult != null) {
routesResult = null;
mNextStationIndex = 0;
startOrStopCalculateRouteInfo(false);
if (mRouteLineInfoCallback != null){
mRouteLineInfoCallback.showNoTaskView();
}
}
return;
}
if (routesResult != null && routesResult.equals(data.getResult())){
if (routesResult != null && data.getResult().equals(routesResult)){
CallerLogger.INSTANCE.d( M_BUS_P + TAG, "queryDriverSiteByCoordinate = not update");
return;
}
routesResult = data.getResult();
updatePassengerRouteInfo(data.getResult());
}
@Override
public void onError() {
}
@Override
public void onFail(int code, String msg) {
CallerLogger.INSTANCE.d( M_BUS_P + TAG, "queryDriverSiteByCoordinate = %s", msg
+ ", sn = " +BusPassengerServiceManager.INSTANCE.getDriverAppSn());
if (code == 1003){
queryDriverOperationDelay();
}
if (BusPassengerServiceManager.INSTANCE.getDriverAppSn().isEmpty()){
//此处拦截是为了防止过程中乘客屏和司机端断连拿不到司机端sn, 造成请求失败去刷新了界面
return;
}
if (code == 1003){
routesResult = null;
startOrStopCalculateRouteInfo(false);
queryDriverOperationDelay();
return;
}
CallerLogger.INSTANCE.d( M_BUS_P + TAG, "queryDriverSiteByCoordinate = %s", msg );
}
});
}
@@ -271,10 +278,10 @@ public class BusPassengerModel {
IntentManager.getInstance().registerIntentListener(ConnectivityManager.CONNECTIVITY_ACTION, mNetWorkIntentListener );
MogoStatusManager.getInstance().registerStatusChangedListener(TAG, StatusDescriptor.VR_MODE, mMogoStatusChangedListener );
// 定位监听
CallerMapLocationListenerManager.INSTANCE.addListener(TAG, mMapLocationListener,false);
CallerChassisLocationGCJ02ListenerManager.INSTANCE.addListener(TAG, mMapLocationListener);
//2021.11.1 自动驾驶路线规划接口
CallerAutopilotPlanningListenerManager.INSTANCE.addListener(TAG,moGoAutopilotPlanningListener);
CallerPlanningRottingListenerManager.INSTANCE.addListener(TAG,moGoAutopilotPlanningListener);
AbnormalFactorsLoopManager.INSTANCE.startLoopAbnormalFactors(mContext);
}
@@ -283,13 +290,13 @@ public class BusPassengerModel {
MogoStatusManager.getInstance().unregisterStatusChangedListener(TAG, StatusDescriptor.VR_MODE, mMogoStatusChangedListener);
// 注销定位监听
CallerMapLocationListenerManager.INSTANCE.removeListener(TAG,false);
CallerChassisLocationGCJ02ListenerManager.INSTANCE.removeListener(TAG);
MogoAiCloudSocketManager.getInstance(mContext)
.unregisterLifecycleListener(10010);
CallerAutoPilotStatusListenerManager.INSTANCE.removeListener(mGoAutopilotStatusListener);
CallerAutopilotPlanningListenerManager.INSTANCE.removeListener(moGoAutopilotPlanningListener);
CallerPlanningRottingListenerManager.INSTANCE.removeListener(moGoAutopilotPlanningListener);
AbnormalFactorsLoopManager.INSTANCE.stopLoopAbnormalFactors();
}
@@ -318,13 +325,13 @@ public class BusPassengerModel {
}
};
private final IMoGoMapLocationListener mMapLocationListener = new IMoGoMapLocationListener() {
private final IMoGoChassisLocationGCJ02Listener mMapLocationListener = new IMoGoChassisLocationGCJ02Listener() {
@Override
public void onLocationChanged(@Nullable MogoLocation location, int from, boolean isGps) {
if (null == location) return;
mLocation = location;
public void onChassisLocationGCJ02(@Nullable MogoLocation gnssInfo) {
if (null == gnssInfo) return;
mLocation = gnssInfo;
for (IBusPassengerControllerStatusCallback callback :mControllerStatusCallbackMap.values()){
callback.onCarLocationChanged(location);
callback.onCarLocationChanged(gnssInfo);
}
}
};
@@ -401,11 +408,7 @@ public class BusPassengerModel {
}
};
private final IMoGoAutopilotPlanningListener moGoAutopilotPlanningListener = new IMoGoAutopilotPlanningListener(){
@Override
public void onAutopilotTrajectory(@NonNull List<MessagePad.TrajectoryPoint> trajectoryInfos) {
}
private final IMoGoPlanningRottingListener moGoAutopilotPlanningListener = new IMoGoPlanningRottingListener(){
@Override
public void onAutopilotRotting(@Nullable MessagePad.GlobalPathResp routeList) {
@@ -431,7 +434,7 @@ public class BusPassengerModel {
//找出前往站对应的轨迹点拿出两站点的集合
CallerLogger.INSTANCE.d(M_BUS_P + TAG, "mRoutePoints.size() = " + mRoutePoints.size());
if (mRoutePoints.size() > 0) {
if (mStations.size() > 1){ //改为两个站点及以上计算两个站点间的估计路线
if (mStations.size() > 1){ //两个站点及以上计算两个站点间的轨迹路线
if (mNextStationIndex <= mStations.size()-1 && mNextStationIndex - 1 >=0){
mTwoStationsRouts.clear();
BusPassengerStation stationNext = mStations.get(mNextStationIndex);
@@ -451,6 +454,10 @@ public class BusPassengerModel {
}
}
}
// else { //只有两个站点的时候整个路线就是两个站点之间的轨迹
// mTwoStationsRouts.clear();
// mTwoStationsRouts.addAll(mRoutePoints);
// }
if (mTwoStationsRouts.size() > 0){
float sumLength = CoordinateCalculateRouteUtil.calculateRouteSumLength(mTwoStationsRouts);
SharedPrefsMgr.getInstance(mContext).putInt(BusPassengerConst.BUS_SP_KEY_ORDER_SUM_DIS,(int) sumLength);
@@ -493,7 +500,8 @@ public class BusPassengerModel {
}else {
lastSumLength = CoordinateCalculateRouteUtil.calculateRouteSumLength(lastPoints);
}
double lastTime = lastSumLength / BusPassengerConst.BUS_AVERAGE_SPEED * 3.6 ; //
double lastTime = lastSumLength / getAverageSpeed() * 3.6 ; //
CallerLogger.INSTANCE.d(M_BUS_P + TAG, "轨迹排查==lastSumLength = " + lastSumLength);
if (mAutopilotPlanningCallback != null){
mAutopilotPlanningCallback.routePlanningToNextStationChanged((long)lastSumLength,(long) lastTime);
@@ -502,6 +510,14 @@ public class BusPassengerModel {
}
}
public int getAverageSpeed(){
if (AppIdentityModeUtils.isShuttle(FunctionBuildConfig.appIdentityMode)){
return BusPassengerConst.SHUTTLE_AVERAGE_SPEED;
}else {
return BusPassengerConst.BUS_AVERAGE_SPEED;
}
}
public void startRemainRouteInfo() {
//开启实时计算剩余距离剩余时间预计时间
startOrStopCalculateRouteInfo(true);

View File

@@ -0,0 +1,101 @@
package com.mogo.och.bus.passenger.network
import android.content.Context
import com.mogo.eagle.core.function.call.telematic.CallerTelematicManager.getServerToken
import com.mogo.och.bus.passenger.bean.BusPassengerRoutesResponse
import com.mogo.cloud.passport.MoGoAiCloudClientConfig
import com.mogo.eagle.core.data.config.FunctionBuildConfig
import com.mogo.eagle.core.function.call.telematic.CallerTelematicManager
import com.mogo.och.bus.passenger.bean.BusPassengerQueryLineRequest
import com.mogo.och.bus.passenger.bean.BusPassengerOperationStatusResponse
import com.mogo.eagle.core.network.MoGoRetrofitFactory
import com.mogo.eagle.core.utilcode.mogo.AppIdentityModeUtils
import com.mogo.och.bus.passenger.constant.URLConst.Companion.getBaseUrl
import com.mogo.och.common.module.biz.network.OchCommonServiceCallback
import com.mogo.och.common.module.biz.network.OchCommonSubscribeImpl
import com.mogo.och.common.module.biz.network.interceptor.transformTry
/**
* Created on 2022/3/31
*/
object BusPassengerServiceManager {
private var driverSnCache = ""
private var mShuttleBusPassengerServiceApi =
MoGoRetrofitFactory.getInstance(getBaseUrl()).create(ShettlePassengerServiceApi::class.java)
private var mBusPassengerServiceApi =
MoGoRetrofitFactory.getInstance(getBaseUrl()).create(PassengerServiceApi::class.java)
/**
* 获取Bus司机端的sn
* @return
*/
val driverAppSn: String
get(){
val serverToken = getServerToken()
if (serverToken != driverSnCache && serverToken.isNotEmpty()) {
driverSnCache = serverToken
}
return driverSnCache
}
/**
* 查询绑定行驶的小巴车路线
* @param context
* @param callback
*/
@JvmStatic
fun queryDriverSiteByCoordinate(
context: Context, callback: OchCommonServiceCallback<BusPassengerRoutesResponse>?
) {
if (AppIdentityModeUtils.isShuttle(FunctionBuildConfig.appIdentityMode)) {
mShuttleBusPassengerServiceApi.queryDriverSiteByCoordinate(
MoGoAiCloudClientConfig.getInstance().serviceAppId,
MoGoAiCloudClientConfig.getInstance().token,
BusPassengerQueryLineRequest(
driverAppSn
)
).transformTry()
.subscribe(OchCommonSubscribeImpl(context, callback, "queryDriverSiteByCoordinate"))
} else {
mBusPassengerServiceApi.queryDriverSiteByCoordinate(
MoGoAiCloudClientConfig.getInstance().serviceAppId,
MoGoAiCloudClientConfig.getInstance().token,
BusPassengerQueryLineRequest(
driverAppSn
)
).transformTry()
.subscribe(OchCommonSubscribeImpl(context, callback, "queryDriverSiteByCoordinate"))
}
}
/**
* 查询司机端出车收车状态,以及车牌号
* @param context
* @param callback
*/
@JvmStatic
fun queryDriverOperationStatus(
context: Context,
callback: OchCommonServiceCallback<BusPassengerOperationStatusResponse>?
) {
if (AppIdentityModeUtils.isShuttle(FunctionBuildConfig.appIdentityMode)) {
mShuttleBusPassengerServiceApi.queryDriverOperationStatus(
MoGoAiCloudClientConfig.getInstance().serviceAppId,
MoGoAiCloudClientConfig.getInstance().token,
driverAppSn
)
.transformTry()
.subscribe(OchCommonSubscribeImpl(context, callback, "queryDriverOperationStatus"))
} else {
mBusPassengerServiceApi.queryDriverOperationStatus(
MoGoAiCloudClientConfig.getInstance().serviceAppId,
MoGoAiCloudClientConfig.getInstance().token,
driverAppSn
)
.transformTry()
.subscribe(OchCommonSubscribeImpl(context, callback, "queryDriverOperationStatus"))
}
}
}

View File

@@ -0,0 +1,40 @@
package com.mogo.och.bus.passenger.network;
import com.mogo.och.bus.passenger.bean.BusPassengerOperationStatusResponse;
import com.mogo.och.bus.passenger.bean.BusPassengerQueryLineRequest;
import com.mogo.och.bus.passenger.bean.BusPassengerRoutesResponse;
import io.reactivex.Observable;
import retrofit2.http.Body;
import retrofit2.http.GET;
import retrofit2.http.Header;
import retrofit2.http.Headers;
import retrofit2.http.POST;
import retrofit2.http.Query;
/**
* Created on 2022/3/31
*
* Bus乘客端接口定义
*/
interface PassengerServiceApi {
/**
* 查询bus司机端绑定路线
* @return 接口返回数据
*/
@Headers( {"Content-Type:application/json;charset=UTF-8"} )
@POST( "/autopilot-car-hailing/line/v2/driver/bus/passenger/lineDataWithDriver/query" )
Observable<BusPassengerRoutesResponse> queryDriverSiteByCoordinate(@Header("appId") String appId, @Header("ticket") String ticket, @Body BusPassengerQueryLineRequest request);
/**
* 查询司机端的登陆状态
* @param sn
* @return
*/
@Headers({"Content-type:application/json;charset=UTF-8"})
// @GET("/autopilot-car-hailing/car/v2/driver/bus/passenger/takeOrderStatus/query")
@GET("/autopilot-car-hailing/operation/v1/driver/bus/passenger/loginStatus")
Observable<BusPassengerOperationStatusResponse> queryDriverOperationStatus(@Header ("appId") String appId, @Header("ticket") String ticket, @Query("sn") String sn);
}

View File

@@ -0,0 +1,40 @@
package com.mogo.och.bus.passenger.network;
import com.mogo.och.bus.passenger.bean.BusPassengerOperationStatusResponse;
import com.mogo.och.bus.passenger.bean.BusPassengerQueryLineRequest;
import com.mogo.och.bus.passenger.bean.BusPassengerRoutesResponse;
import io.reactivex.Observable;
import retrofit2.http.Body;
import retrofit2.http.GET;
import retrofit2.http.Header;
import retrofit2.http.Headers;
import retrofit2.http.POST;
import retrofit2.http.Query;
/**
* Created on 2022/3/31
*
* Bus乘客端接口定义
*/
interface ShettlePassengerServiceApi {
/**
* 查询bus司机端绑定路线
* @return 接口返回数据
*/
@Headers( {"Content-Type:application/json;charset=UTF-8"} )
@POST( "/och-shuttle-cabin/api/business/v1/passenger/lineDataWithDriver/query" )
Observable<BusPassengerRoutesResponse> queryDriverSiteByCoordinate(@Header("appId") String appId, @Header("ticket") String ticket, @Body BusPassengerQueryLineRequest request);
/**
* 查询司机端的登陆状态
* @param sn
* @return
*/
@Headers({"Content-type:application/json;charset=UTF-8"})
// @GET("/autopilot-car-hailing/car/v2/driver/bus/passenger/takeOrderStatus/query")
@GET("/och-shuttle-cabin/api/business/v1/passenger/loginStatus")
Observable<BusPassengerOperationStatusResponse> queryDriverOperationStatus(@Header ("appId") String appId, @Header("ticket") String ticket, @Query("sn") String sn);
}

View File

@@ -1,6 +1,7 @@
package com.mogo.och.bus.passenger.presenter;
import android.location.Location;
import static com.mogo.eagle.core.utilcode.mogo.logger.scene.SceneConstant.M_BUS_P;
import android.os.Looper;
import androidx.annotation.NonNull;
@@ -24,8 +25,6 @@ import com.mogo.och.bus.passenger.ui.BusPassengerRouteFragment;
import java.util.List;
import static com.mogo.eagle.core.utilcode.mogo.logger.scene.SceneConstant.M_BUS_P;
/**
* Created on 2022/3/31
*/

View File

@@ -8,6 +8,7 @@ import android.widget.FrameLayout;
import android.widget.ImageView;
import android.widget.TextView;
import androidx.annotation.NonNull;
import androidx.core.widget.ContentLoadingProgressBar;
import com.mogo.commons.mvp.IView;
@@ -15,14 +16,12 @@ import com.mogo.commons.mvp.MvpFragment;
import com.mogo.commons.mvp.Presenter;
import com.mogo.eagle.core.function.api.autopilot.IMoGoAutopilotStatusListener;
import com.mogo.eagle.core.function.call.hmi.CallerHmiManager;
import com.mogo.eagle.core.function.call.map.CallerSmpManager;
import com.mogo.eagle.core.function.view.MapBizView;
import com.mogo.eagle.core.utilcode.mogo.storage.SharedPrefsMgr;
import com.mogo.eagle.core.utilcode.util.UiThreadHandler;
import com.mogo.och.bus.passenger.R;
import com.mogo.och.bus.passenger.constant.BusPassengerConst;
import com.mogo.och.common.module.utils.NumberFormatUtil;
import com.mogo.och.common.module.wigets.OCHBorderShadowLayout;
/**
* Created on 2022/3/31
@@ -32,6 +31,7 @@ import com.mogo.och.common.module.wigets.OCHBorderShadowLayout;
public abstract class BusPassengerBaseFragment<V extends IView, P extends Presenter<V>> extends MvpFragment<V, P> {
private static final String TAG = BusPassengerBaseFragment.class.getSimpleName();
private MapBizView mapBizView;
private TextView mCurrentArriveStation;
private TextView mCurrentArriveStationTitle;
private TextView mCurrentArriveTip;
@@ -56,12 +56,9 @@ public abstract class BusPassengerBaseFragment<V extends IView, P extends Presen
return TAG;
}
@Override
protected void initViews() {
//隐藏小地图
CallerSmpManager.INSTANCE.hidePanel();
mapBizView = findViewById(R.id.mapBizView);
mCurrentArriveStation = findViewById(R.id.bus_p_cur_station_name);
mCurrentArriveStationTitle = findViewById(R.id.bus_p_cur_station_title);
mCurrentArriveTip = findViewById(R.id.bus_p_cur_station_tip);
@@ -83,6 +80,37 @@ public abstract class BusPassengerBaseFragment<V extends IView, P extends Presen
@Override
protected void initViews(Bundle savedInstanceState) {
super.initViews(savedInstanceState);
mapBizView.onCreate(savedInstanceState);
}
@Override
public void onResume() {
super.onResume();
mapBizView.onResume();
}
@Override
public void onSaveInstanceState(@NonNull Bundle outState) {
super.onSaveInstanceState(outState);
mapBizView.onSaveInstanceState(outState);
}
@Override
public void onLowMemory() {
super.onLowMemory();
mapBizView.onLowMemory();
}
@Override
public void onPause() {
super.onPause();
mapBizView.onPause();
}
@Override
public void onDestroyView() {
mapBizView.onDestroy();
super.onDestroyView();
}
/**
@@ -186,11 +214,9 @@ public abstract class BusPassengerBaseFragment<V extends IView, P extends Presen
}
public void showOverviewFragment() {
CallerHmiManager.INSTANCE.showSmallFragment();
UiThreadHandler.postDelayed(new Runnable() {
@Override
public void run() {
CallerHmiManager.INSTANCE.hideSmallFragment();
}
},5000L);
}

View File

@@ -1,5 +1,7 @@
package com.mogo.och.bus.passenger.ui;
import static com.mogo.eagle.core.utilcode.mogo.logger.scene.SceneConstant.M_BUS_P;
import android.content.Context;
import android.os.Bundle;
import android.util.AttributeSet;
@@ -26,8 +28,8 @@ import com.amap.api.maps.model.MarkerOptions;
import com.amap.api.maps.model.Polyline;
import com.amap.api.maps.model.PolylineOptions;
import com.mogo.eagle.core.data.map.MogoLocation;
import com.mogo.eagle.core.function.api.map.listener.IMoGoMapLocationListener;
import com.mogo.eagle.core.function.call.map.CallerMapLocationListenerManager;
import com.mogo.eagle.core.function.api.autopilot.IMoGoChassisLocationGCJ02Listener;
import com.mogo.eagle.core.function.call.autopilot.CallerChassisLocationGCJ02ListenerManager;
import com.mogo.eagle.core.utilcode.mogo.logger.CallerLogger;
import com.mogo.och.bus.passenger.R;
import com.mogo.och.bus.passenger.callback.IBusPassengerMapViewCallback;
@@ -36,14 +38,14 @@ import com.mogo.och.bus.passenger.utils.BusPassengerMapAssetStyleUtil;
import java.util.ArrayList;
import java.util.List;
import static com.mogo.eagle.core.utilcode.mogo.logger.scene.SceneConstant.M_BUS_P;
/**
* 乘客屏小地图
*/
public class BusPassengerMapDirectionView
extends RelativeLayout
implements IMoGoMapLocationListener, IBusPassengerMapDirectionView, AMap.OnCameraChangeListener {
implements IMoGoChassisLocationGCJ02Listener,
IBusPassengerMapDirectionView,
AMap.OnCameraChangeListener {
//小地图名称
public static final String TAG = "TPMapDirectionView";
@@ -101,14 +103,14 @@ public class BusPassengerMapDirectionView
initAMapView();
// 注册定位监听
CallerMapLocationListenerManager.INSTANCE.addListener(TAG, this, false);
CallerChassisLocationGCJ02ListenerManager.INSTANCE.addListener(TAG, this);
}
@Override
protected void onDetachedFromWindow() {
super.onDetachedFromWindow();
// 注册定位监听
CallerMapLocationListenerManager.INSTANCE.removeListener(TAG, false);
CallerChassisLocationGCJ02ListenerManager.INSTANCE.removeListener(TAG);
}
private void initAMapView() {
@@ -171,19 +173,18 @@ public class BusPassengerMapDirectionView
return true;
}
@Override
public void onLocationChanged(@org.jetbrains.annotations.Nullable MogoLocation location, int from, boolean isGps) {
if (location == null) {
public void onChassisLocationGCJ02(@Nullable MogoLocation gnssInfo) {
if (gnssInfo == null) {
return;
}
// CallerLogger.INSTANCE.d(M_BUS_P + TAG, "onCarLocationChanged2 :" + location.getLatitude() + ":" + location.getLongitude());
LatLng currentLatLng = new LatLng(location.getLatitude(), location.getLongitude());
LatLng currentLatLng = new LatLng(gnssInfo.getLatitude(), gnssInfo.getLongitude());
//更新车辆位置
if (mCarMarker != null) {
// CallerLogger.INSTANCE.d(M_BUS_P + TAG, "location.getBearing() = " + location.getBearing());
mCarMarker.setRotateAngle(360 - location.getBearing());
mCarMarker.setRotateAngle((float) (360 - gnssInfo.getHeading()));
mCarMarker.setPosition(currentLatLng);
mCarMarker.setToTop();
}
@@ -208,7 +209,6 @@ public class BusPassengerMapDirectionView
}
@Override
public void drawablePolyline() {
if (mPolyline != null) {

View File

@@ -1,5 +1,7 @@
package com.mogo.och.bus.passenger.ui;
import static com.mogo.eagle.core.utilcode.mogo.logger.scene.SceneConstant.M_BUS_P;
import android.os.Bundle;
import android.view.View;
import android.view.animation.Animation;
@@ -15,7 +17,6 @@ import com.amap.api.maps.model.LatLng;
import com.elegant.utils.UiThreadHandler;
import com.mogo.commons.debug.DebugConfig;
import com.mogo.eagle.core.data.map.MogoLocation;
import com.mogo.eagle.core.function.call.hmi.CallerHmiManager;
import com.mogo.eagle.core.utilcode.mogo.logger.CallerLogger;
import com.mogo.eagle.core.utilcode.mogo.storage.SharedPrefsMgr;
import com.mogo.och.bus.passenger.R;
@@ -31,8 +32,6 @@ import com.mogo.och.common.module.wigets.MarqueeTextView;
import java.util.ArrayList;
import java.util.List;
import static com.mogo.eagle.core.utilcode.mogo.logger.scene.SceneConstant.M_BUS_P;
/**
* @author: wangmingjun
* @date: 2022/4/12
@@ -43,8 +42,7 @@ public class BusPassengerRouteFragment extends
private final String TAG = "BusPassengerRouteFragment";
private BusPassengerTrafficLightView mTrafficLightView;
private List<BusPassengerStation> mStationsList = new ArrayList<>();
private final List<BusPassengerStation> mStationsList = new ArrayList<>();
private TextView mSpeedTv;
private ConstraintLayout mNoLineInfoView;
@@ -74,8 +72,6 @@ public class BusPassengerRouteFragment extends
@Override
protected void initViews() {
super.initViews();
mTrafficLightView = findViewById(R.id.bus_p_traffic_light_view);
CallerHmiManager.INSTANCE.setProxyTrafficLightView(mTrafficLightView);
mSpeedTv = findViewById(R.id.bus_p_speed_tv);
@@ -302,7 +298,7 @@ public class BusPassengerRouteFragment extends
}
public void onCarLocationChanged(MogoLocation location) {
updateSpeedView(location.getSpeed());
updateSpeedView((float) location.getGnssSpeed());
}
public void updateSpeedView(float speed){

View File

@@ -0,0 +1,179 @@
package com.mogo.och.bus.passenger.ui
import android.content.Context
import android.util.AttributeSet
import android.view.LayoutInflater
import android.widget.LinearLayout
import com.mogo.eagle.core.data.enums.DataSourceType
import com.mogo.eagle.core.data.enums.TrafficLightEnum
import com.mogo.eagle.core.function.api.datacenter.union.IMoGoTrafficLightListener
import com.mogo.eagle.core.function.call.v2x.CallerTrafficLightListenerManager
import com.mogo.eagle.core.utilcode.util.UiThreadHandler
import com.mogo.och.bus.passenger.R
import kotlinx.android.synthetic.jinlvvan.bus_p_traffic_light_view.view.*
/**
* bus乘客端红绿灯view
*
* Created on 2022/3/14
*/
class BusPassengerTrafficLightView @JvmOverloads constructor(
context: Context?,
attrs: AttributeSet? = null,
defStyleAttr: Int = 0
) : LinearLayout(context, attrs, defStyleAttr), IMoGoTrafficLightListener {
companion object {
private const val TAG = "BusPassengerTrafficLightView"
}
private var mCurrentLightId = TrafficLightEnum.BLACK
init {
init(context)
}
private fun init(context: Context?) {
LayoutInflater.from(context).inflate(R.layout.bus_p_traffic_light_view, this, true)
}
override fun onAttachedToWindow() {
super.onAttachedToWindow()
CallerTrafficLightListenerManager.addListener(TAG, this)
}
override fun onDetachedFromWindow() {
super.onDetachedFromWindow()
CallerTrafficLightListenerManager.removeListener(TAG)
}
/**
* 展示红绿灯预警
*
* @param checkLightId 0-都是默认1-红2-黄3-绿
* @param lightSource 1:云端下发2:自车感知
*/
override fun showTrafficLight(checkLightId: TrafficLightEnum, lightSource: DataSourceType) {
super.showTrafficLight(checkLightId, lightSource)
mCurrentLightId = checkLightId
updateTrafficLightIcon(checkLightId)
}
/**
* 关闭红绿灯预警展示,并重制灯态
*/
override fun disableTrafficLight() {
super.disableTrafficLight()
UiThreadHandler.post {
mCurrentLightId = TrafficLightEnum.BLACK
this@BusPassengerTrafficLightView.visibility = GONE
}
}
/**
* @param redNum 红灯倒计时
* @param yellowNum 黄灯倒计时
* @param greenNum 绿灯倒计时
*/
override fun changeCountdownTrafficLightNum(redNum: Int, yellowNum: Int, greenNum: Int) {
super.changeCountdownTrafficLightNum(redNum, yellowNum, greenNum)
resetView()
when (mCurrentLightId) {
TrafficLightEnum.RED -> changeCountdownRed(redNum)
TrafficLightEnum.YELLOW -> changeCountdownYellow(yellowNum)
TrafficLightEnum.GREEN -> changeCountdownGreen(greenNum)
else -> UiThreadHandler.post { bus_p_traffic_light_time_tv.text = "" }
}
}
override fun changeCountdownRed(redNum: Int) {
super.changeCountdownRed(redNum)
UiThreadHandler.post {
if (redNum > 0) {
resetView()
bus_p_traffic_light_time_tv.text = redNum.toString()
} else {
disableTrafficLightCountDown()
bus_p_traffic_light_time_tv.text = ""
}
}
}
override fun changeCountdownGreen(greenNum: Int) {
super.changeCountdownGreen(greenNum)
UiThreadHandler.post {
if (greenNum > 0) {
resetView()
bus_p_traffic_light_time_tv.text = greenNum.toString()
} else {
disableTrafficLightCountDown()
bus_p_traffic_light_time_tv.text = ""
}
}
}
override fun changeCountdownYellow(yellowNum: Int) {
super.changeCountdownYellow(yellowNum)
UiThreadHandler.post {
if (yellowNum > 0) {
resetView()
bus_p_traffic_light_time_tv.text = yellowNum.toString()
} else {
disableTrafficLightCountDown()
bus_p_traffic_light_time_tv.text = ""
}
}
}
/**
* 更新红绿灯icon
*
* @param lightId 0-都是默认1-红2-黄3-绿
*/
private fun updateTrafficLightIcon(lightId: TrafficLightEnum) {
UiThreadHandler.post {
when (lightId) {
TrafficLightEnum.RED -> {
bus_p_traffic_light_iv.setBackgroundResource(R.drawable.bus_p_light_red_nor)
this@BusPassengerTrafficLightView.visibility = VISIBLE
}
TrafficLightEnum.YELLOW -> {
bus_p_traffic_light_iv.setBackgroundResource(R.drawable.bus_p_light_yellow_nor)
this@BusPassengerTrafficLightView.visibility = VISIBLE
}
TrafficLightEnum.GREEN -> {
bus_p_traffic_light_iv.setBackgroundResource(R.drawable.bus_p_light_green_nor)
this@BusPassengerTrafficLightView.visibility = VISIBLE
}
else -> this@BusPassengerTrafficLightView.visibility = GONE
}
}
}
override fun disableTrafficLightCountDown() {
super.disableTrafficLightCountDown()
UiThreadHandler.post {
val layoutParams = layoutParams
if (layoutParams is MarginLayoutParams) {
val lp = layoutParams
lp.width = resources.getDimension(R.dimen.bus_p_traffic_light_icon_size).toInt()
setLayoutParams(lp)
bus_p_traffic_light_time_tv.visibility = GONE
bus_p_traffic_light_bg.layoutParams.width =
resources.getDimension(R.dimen.dp_90).toInt()
}
}
}
private fun resetView() {
val layoutParams = layoutParams
if (layoutParams is MarginLayoutParams) {
val lp = layoutParams
lp.width = resources.getDimension(R.dimen.bus_p_route_traffic_light_view_width).toInt()
setLayoutParams(lp)
bus_p_traffic_light_time_tv.visibility = VISIBLE
bus_p_traffic_light_bg.layoutParams.width =
resources.getDimension(R.dimen.bus_p_traffic_light_bg_width).toInt()
}
}
}

View File

@@ -4,6 +4,22 @@
android:layout_width="match_parent"
android:layout_height="match_parent">
<com.mogo.eagle.core.function.view.MapBizView
android:id="@+id/mapBizView"
android:layout_width="@dimen/dp_1860"
android:layout_height="match_parent"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintBottom_toBottomOf="parent"/>
<com.mogo.eagle.core.function.hmi.ui.setting.ToggleDebugViewTrigger
android:layout_width="@dimen/dp_400"
android:layout_height="@dimen/dp_100"
android:longClickable="true"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent" />
<com.mogo.eagle.core.function.hmi.ui.widget.SteeringWheelView
android:id="@+id/steering_wheel"
android:layout_width="@dimen/dp_490"
@@ -26,6 +42,20 @@
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintTop_toTopOf="parent"/>
<!--浓雾预警动画-->
<com.mogo.eagle.core.function.hmi.ui.widget.V2XFogEventView
android:layout_width="match_parent"
android:layout_height="match_parent"/>
<!--pnc行为决策-->
<com.mogo.eagle.core.function.hmi.ui.vehicle.PncActionsView
android:layout_width="wrap_content"
android:layout_height="@dimen/dp_100"
android:layout_marginBottom="@dimen/dp_110"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent" />
<com.mogo.och.common.module.wigets.OCHBorderShadowLayout
android:id="@+id/arrive_station_shadow"
android:layout_width="wrap_content"

View File

@@ -0,0 +1,13 @@
<?xml version="1.0" encoding="utf-8"?>
<resources>
<string name="bus_p_speed_unit_txt">KM/H</string>
<string name="bus_p_no_out">您已收车</string>
<string name="bus_p_no_task">暂无班次</string>
<string name="bus_p_start_station_txt_tag"></string>
<string name="bus_p_end_station_txt_tag"></string>
<string name="bus_p_cur_station_title">到达站:</string>
<string name="bus_p_cur_next_station_title">下一站:</string>
<string name="bus_p_cur_station_title_init">始发站:</string>
<string name="bus_p_cur_station_arrived_tip">请携带好随身物品下车。</string>
<string name="bus_p_cur_station_arrived_tip_init">欢迎乘坐蘑菇车联自动驾驶车。</string>
</resources>

View File

@@ -0,0 +1,7 @@
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.mogo.och.bus.passenger">
<uses-permission android:name="android.permission.MOUNT_UNMOUNT_FILESYSTEMS"/>
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
</manifest>

File diff suppressed because one or more lines are too long

View File

@@ -0,0 +1,92 @@
package com.mogo.och.bus.passenger
import android.content.Context
import androidx.fragment.app.Fragment
import androidx.fragment.app.FragmentActivity
import com.alibaba.android.arouter.facade.annotation.Route
import com.mogo.commons.module.status.IMogoStatusChangedListener
import com.mogo.commons.module.status.MogoStatusManager
import com.mogo.commons.module.status.StatusDescriptor
import com.mogo.eagle.core.function.call.map.CallerMapUIServiceManager.getMapUIController
import com.mogo.eagle.core.function.call.setting.CallerMoGoUiSettingManager.stepInDayMode
import com.mogo.eagle.core.utilcode.mogo.logger.CallerLogger.d
import com.mogo.eagle.core.utilcode.mogo.logger.scene.SceneConstant
import com.mogo.och.bus.passenger.constant.BusPassengerConst
import com.mogo.och.bus.passenger.ui.PM2BaseFragment
/**
* 网约车-Bus-乘客端
*
* Created on 2022/3/29
*/
@Route(path = BusPassengerConst.PATH)
class MogoOCHBusPassenger : IMogoOCH, IMogoStatusChangedListener {
private var mActivity: FragmentActivity? = null
private var mContainerId = 0
private var mPM2Fragment: PM2BaseFragment? = null
override fun createCoverage(activity: FragmentActivity, containerId: Int) {}
override fun createCoverage(activity: FragmentActivity?, containerId: Int?): Fragment? {
mActivity = activity
mContainerId = containerId!!
// if (MogoStatusManager.getInstance().isScreenCoverDismiss){
showFragment()
// }else{
// MogoStatusManager.getInstance()
// .registerStatusChangedListener("ochM2Passenger", StatusDescriptor.SCREEN_COVER, this)
// }
return null
}
override val functionName: String
get() = "och-bus-passenger-m2"
override fun onDestroy() {
// 若不调用finish, 设置中打开关闭UITouch,会造成och fragment 重叠
mActivity?.finish()
}
override fun init(context: Context) {
}
/**
* 进入鹰眼模式,设置手势缩放地图失效
*/
private fun stepIntoVrMode() {
d(SceneConstant.M_TAXI_P + TAG, "进入vr模式")
getMapUIController()?.stepInVrMode(true) // 白天模式
stepInDayMode() //白天模式 状态栏字体颜色变黑
}
private fun showFragment() {
if (mPM2Fragment == null) {
d(SceneConstant.M_TAXI_P + TAG, "准备add fragment======")
mPM2Fragment = PM2BaseFragment()
mActivity?.supportFragmentManager?.beginTransaction()
?.add(mContainerId, mPM2Fragment!!)?.commitAllowingStateLoss()
}
d(SceneConstant.M_TAXI_P + TAG, "准备show fragment")
mActivity?.supportFragmentManager?.beginTransaction()?.show(mPM2Fragment!!)
?.commitAllowingStateLoss()
}
private fun hideFragment() {
if (mPM2Fragment != null) {
mActivity?.supportFragmentManager?.beginTransaction()?.hide(mPM2Fragment!!)
?.commitAllowingStateLoss()
}
}
companion object {
private val TAG = MogoOCHBusPassenger::class.java.simpleName
}
override fun onStatusChanged(descriptor: StatusDescriptor?, isTrue: Boolean) {
if (descriptor == StatusDescriptor.SCREEN_COVER){
if (isTrue){
showFragment()
}else{
hideFragment()
}
}
}
}

View File

@@ -0,0 +1,21 @@
package com.mogo.och.bus.passenger.bean;
import com.mogo.eagle.core.data.BaseData;
/**
* @author congtaowang
* @since 2021/3/22
*
* 小巴车运营状态返回参数
*/
public class PM2OperationStatusResponse extends BaseData {
public Result data;
public static class Result {
private String sn; //司机屏sn
private String phone; //司机手机号
public String plateNumber; //车牌号
public int driverStatus;//0:已收车1:已出车
}
}

View File

@@ -0,0 +1,16 @@
package com.mogo.och.bus.passenger.bean;
public
/**
* @author congtaowang
* @since 2021/3/22
*
* 根据车机行驶线路站点信息
*/
class PM2QueryLineRequest {
private String sn;
public PM2QueryLineRequest(String sn) {
this.sn = sn;
}
}

View File

@@ -0,0 +1,28 @@
package com.mogo.och.bus.passenger.bean;
import com.mogo.eagle.core.data.BaseData;
/**
* 网约车小巴路线接口请求响应结果 返回的是对应司机屏的线路信息
*
* @author tongchenfei
*/
public class PM2RoutesResponse extends BaseData {
private PM2RoutesResult data;
public PM2RoutesResult getResult() {
return data;
}
public void setResult(PM2RoutesResult data) {
this.data = data;
}
@Override
public String toString() {
return "OchBusRoutesResponse{" +
"data=" + data +
'}';
}
}

View File

@@ -0,0 +1,79 @@
package com.mogo.och.bus.passenger.bean;
import java.util.List;
import java.util.Objects;
/**
* 网约车小巴路线接口返回接口数据封装
*
* @author tongchenfei
*/
public class PM2RoutesResult {
private List<PM2Station> sites;
private int lineId;
private String name; //线路名称
private int lineType; //线路类型0:环形
private String description;
private int status;
private String runningDur; //运营时间
private long taskTime; //线路时间班次
public List<PM2Station> getSites() {
return sites;
}
public int getLineId() {
return lineId;
}
public String getName() {
return name;
}
public int getLineType() {
return lineType;
}
public String getDescription() {
return description;
}
public int getStatus() {
return status;
}
public String getRunningDur() {
return runningDur;
}
@Override
public String toString() {
return "BusPassengerRoutesResult{" +
"sites=" + sites +
", lineId=" + lineId +
", name='" + name + '\'' +
", lineType=" + lineType +
", description='" + description + '\'' +
", status=" + status +
", runningDur='" + runningDur + '\'' +
'}';
}
@Override
public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
PM2RoutesResult that = (PM2RoutesResult) o;
return lineId == that.lineId
&& lineType == that.lineType
&& status == that.status
&& sites.equals(that.sites)
&& name.equals(that.name)
&& runningDur.equals(that.runningDur);
}
@Override
public int hashCode() {
return Objects.hash(sites, lineId, name, lineType, description, status, runningDur);
}
}

View File

@@ -0,0 +1,173 @@
package com.mogo.och.bus.passenger.bean;
import java.util.Objects;
/**
* 单个网约车小巴车站信息
*
* @author wangmingjun
*/
public class PM2Station {
private String name;
private String description;
private String cityCode;
private double lon; //高精坐标
private double lat; //高精坐标
private double gcjLon; //高德坐标
private double gcjLat; //高德坐标
private int businessType; //站点类型9:taxi10:bus
private int status;
private int siteId;
private int seq;
private int drivingStatus;//行驶信息0初始值1已经过2当前站3未到站
private int ifStop = 1; // 是否需要停靠、1需要、0不需要 // TODO: 2021/10/19 原来站点里有设计是否需要停靠字段,现设计暂无,默认都需要停靠
private boolean leaving;
public void setName(String name) {
this.name = name;
}
public void setDescription(String description) {
this.description = description;
}
public void setCityCode(String cityCode) {
this.cityCode = cityCode;
}
public void setLon(double lon) {
this.lon = lon;
}
public void setLat(double lat) {
this.lat = lat;
}
public void setBusinessType(int businessType) {
this.businessType = businessType;
}
public void setStatus(int status) {
this.status = status;
}
public void setSiteId(int siteId) {
this.siteId = siteId;
}
public void setSeq(int seq) {
this.seq = seq;
}
public void setDrivingStatus(int drivingStatus) {
this.drivingStatus = drivingStatus;
}
public String getName() {
return name;
}
public String getDescription() {
return description;
}
public String getCityCode() {
return cityCode;
}
public double getGcjLon() {
return gcjLon;
}
public double getGcjLat() {
return gcjLat;
}
public int getBusinessType() {
return businessType;
}
public int getStatus() {
return status;
}
public int getSiteId() {
return siteId;
}
public int getSeq() {
return seq;
}
public int getDrivingStatus() {
return drivingStatus;
}
public double getLon() {
return lon;
}
public double getLat() {
return lat;
}
public void setIfStop(int ifStop) {
this.ifStop = ifStop;
}
public int getIfStop() {
return ifStop;
}
public void setLeaving(boolean leaving) {
this.leaving = leaving;
}
public boolean isLeaving() {
return leaving;
}
@Override
public String toString() {
return "OchBusStation{" +
"name='" + name + '\'' +
", description='" + description + '\'' +
", cityCode='" + cityCode + '\'' +
", lon=" + lon +
", lat=" + lat +
", businessType=" + businessType +
", status=" + status +
", siteId=" + siteId +
", seq=" + seq +
", drivingStatus=" + drivingStatus +
", ifStop=" + ifStop +
", leaving=" + leaving +
'}';
}
@Override
public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
PM2Station that = (PM2Station) o;
return Double.compare(that.lon, lon) == 0
&& Double.compare(that.lat, lat) == 0
&& Double.compare(that.gcjLon, gcjLon) == 0
&& Double.compare(that.gcjLat, gcjLat) == 0
&& businessType == that.businessType
&& status == that.status
&& siteId == that.siteId
&& seq == that.seq
&& drivingStatus == that.drivingStatus
&& ifStop == that.ifStop
&& leaving == that.leaving
&& Objects.equals(name, that.name)
&& Objects.equals(cityCode, that.cityCode);
}
@Override
public int hashCode() {
return Objects.hash(name, description, cityCode, lon, lat, gcjLon, gcjLat, businessType, status, siteId, seq, drivingStatus, ifStop, leaving);
}
}

View File

@@ -0,0 +1,10 @@
package com.mogo.och.bus.passenger.callback
/**
* @author: wangmingjun
* @date: 2023/2/15
*/
interface ADASCallback {
fun updateHDMapStations(stations: MutableList<MutableList<Double>>)
fun removeHDMapStations()
}

View File

@@ -0,0 +1,14 @@
package com.mogo.och.bus.passenger.callback
/**
* @author: wangmingjun
* @date: 2023/2/13
*/
interface AutoPilotStatusCallback {
/**
* false: 未开启自驾, true 开启自驾
*/
fun updateAutoStatus(isOpen: Boolean)
fun updateAutoStatus(status: Int)
}

View File

@@ -0,0 +1,18 @@
package com.mogo.och.bus.passenger.callback
import com.mogo.och.bus.passenger.bean.PM2Station
/**
* @author: wangmingjun
* @date: 2023/2/2
*/
interface DrivingInfoCallback {
fun updateSpeed(speed: Int)
fun updatePlateNumber(carNum: String)
fun updateLine(lineName: String, lineDuring: String)
fun updateRemainMT(meters : Long, timeInSecond : Long) // 米,秒
fun changeOperationStatus(loginStatus : Boolean)
fun showNoTaskView(isTrue : Boolean)
fun updateLineStations(stations: MutableList<PM2Station>)
fun updateStationsInfo(stations: MutableList<PM2Station>, i: Int, isArrived: Boolean)
}

View File

@@ -0,0 +1,16 @@
package com.mogo.och.bus.passenger.constant
/**
* Created on 2021/12/6
*/
class M2Const {
companion object {
//站点UUID
const val M2_MAP_STATION_MAKER = "m2_map_station_maker"
/**
* Marker类型
*/
const val TYPE_MARKER_M2_LINE = "TYPE_MARKER_M2_LINE"
}
}

View File

@@ -0,0 +1,46 @@
package com.mogo.och.bus.passenger.model
import android.content.Context
import com.amap.api.maps.model.LatLng
import com.mogo.och.bus.passenger.bean.PM2Station
import com.mogo.och.bus.passenger.callback.ADASCallback
/**
* @author: wangmingjun
* @date: 2023/2/2
*/
class PM2ADASModel private constructor() {
private var mContext: Context? = null
private var mAdasCallback: ADASCallback? = null
companion object {
val TAG = PM2ADASModel::class.java.simpleName
val INSTANCE: PM2ADASModel by lazy(mode = LazyThreadSafetyMode.SYNCHRONIZED) {
PM2ADASModel()
}
}
fun init(context : Context){
this.mContext = context
}
fun setAdasCallback(adasCallback: ADASCallback?){
this.mAdasCallback = adasCallback
}
fun updateHDMapStations(stations: MutableList<PM2Station>){
var stationsList = mutableListOf<MutableList<Double>>()
for (i in stations.indices){
var listLatLng = mutableListOf<Double>() // 0: long 1:lat
listLatLng.add(stations[i].lon)
listLatLng.add(stations[i].lat)
stationsList.add(listLatLng)
}
mAdasCallback?.updateHDMapStations(stationsList)
}
fun removeHDMapStations(){
mAdasCallback?.removeHDMapStations()
}
}

View File

@@ -0,0 +1,530 @@
package com.mogo.och.bus.passenger.model
import android.content.Context
import android.media.AudioAttributes
import android.media.AudioFocusRequest
import android.media.AudioManager
import android.net.ConnectivityManager
import android.os.Build
import android.os.Handler
import androidx.annotation.RequiresApi
import com.mogo.commons.module.intent.IMogoIntentListener
import com.mogo.commons.module.intent.IntentManager
import com.mogo.commons.voice.AIAssist
import com.mogo.commons.voice.IMogoVoiceCmdCallBack
import com.mogo.eagle.core.data.autopilot.AutopilotStatusInfo
import com.mogo.eagle.core.data.config.FunctionBuildConfig
import com.mogo.eagle.core.data.map.MogoLocation
import com.mogo.eagle.core.function.api.autopilot.IMoGoAutopilotStatusListener
import com.mogo.eagle.core.function.api.autopilot.IMoGoChassisLocationGCJ02Listener
import com.mogo.eagle.core.function.api.autopilot.IMoGoPlanningRottingListener
import com.mogo.eagle.core.function.api.telematic.IReceivedMsgListener
import com.mogo.eagle.core.function.call.autopilot.CallerAutoPilotStatusListenerManager
import com.mogo.eagle.core.function.call.autopilot.CallerChassisLocationGCJ02ListenerManager
import com.mogo.eagle.core.function.call.autopilot.CallerPlanningRottingListenerManager
import com.mogo.eagle.core.function.call.telematic.CallerTelematicListenerManager
import com.mogo.eagle.core.utilcode.mogo.logger.CallerLogger.d
import com.mogo.eagle.core.utilcode.mogo.logger.Logger
import com.mogo.eagle.core.utilcode.mogo.logger.scene.SceneConstant
import com.mogo.eagle.core.utilcode.util.CoordinateUtils
import com.mogo.eagle.core.utilcode.util.GsonUtils
import com.mogo.eagle.core.utilcode.util.NetworkUtils
import com.mogo.eagle.core.utilcode.util.ToastUtils
import com.mogo.och.bus.passenger.R
import com.mogo.och.bus.passenger.bean.PM2OperationStatusResponse
import com.mogo.och.bus.passenger.bean.PM2RoutesResponse
import com.mogo.och.bus.passenger.bean.PM2RoutesResult
import com.mogo.och.bus.passenger.bean.PM2Station
import com.mogo.och.bus.passenger.callback.AutoPilotStatusCallback
import com.mogo.och.bus.passenger.callback.DrivingInfoCallback
import com.mogo.och.bus.passenger.constant.BusPassengerConst
import com.mogo.och.bus.passenger.network.PM2ModelLoopManager
import com.mogo.och.common.module.bean.AppConnectMsg
import com.mogo.och.common.module.biz.common.socketmessage.OCHSocketMessageManager
import com.mogo.och.common.module.biz.network.OchCommonServiceCallback
import com.mogo.och.common.module.biz.constant.OchCommonConst
import com.mogo.och.common.module.utils.CoordinateCalculateRouteUtil
import com.mogo.och.common.module.utils.DateTimeUtil
import mogo.telematics.pad.MessagePad
import kotlin.math.abs
/**
* @author: wangmingjun
* @date: 2023/1/31
*/
class PM2DrivingModel private constructor() {
private var mContext: Context? = null
private var mLocation: MogoLocation? = null
private var mRoutePoints = mutableListOf<MogoLocation>()
private var routesResult: PM2RoutesResult? = null
private var mCurrentAutoStatus = -1
var mStations = mutableListOf<PM2Station>()
private var mNextStationIndex = 0 // A-B要到达站的index
private var isGoingToNextStation = false //是否前往下一站过程中
private var mTwoStationsRouts = mutableListOf<MogoLocation>()
private var mPreRouteIndex = 0
private var mWipePreIndex = 0
private var mDrivingInfoCallback: DrivingInfoCallback? = null //行程信息
private var mAutoStatusCallback: AutoPilotStatusCallback? = null //自动驾驶状态
private var operationStatus: PM2OperationStatusResponse.Result? = null
private val handler = Handler(Handler.Callback { msg ->
if (msg.what == MSG_QUERY_BUS_P_STATION) {
queryDriverOperationStatus()
return@Callback true
}
false
})
companion object {
val TAG = PM2DrivingModel::class.java.simpleName
const val MSG_QUERY_BUS_P_STATION = 1001
val INSTANCE: PM2DrivingModel by lazy(mode = LazyThreadSafetyMode.SYNCHRONIZED) {
PM2DrivingModel()
}
}
fun init(context : Context){
mContext = context
initListener()
// TODO: 2022/3/31
queryDriverOperationStatus()
startOrStopOrderLoop(true)
}
private fun initListener() {
//自动驾驶状态监听
CallerAutoPilotStatusListenerManager.addListener(TAG, mAutoPilotStatusListener)
// 定位监听
CallerChassisLocationGCJ02ListenerManager.addListener(TAG, mMapLocationListener)
// CallerChassisLocationGCJ02ListenerManager.setListenerHz(TAG,2)//设置2hz, 1s返回2次
//司乘屏通信监听
CallerTelematicListenerManager.addListener(TAG,mReceivedMsgListener)
//自动驾驶轨迹监听
CallerPlanningRottingListenerManager.addListener(TAG, moGoAutopilotPlanningListener)
//网络监听
IntentManager.getInstance().registerIntentListener(ConnectivityManager.CONNECTIVITY_ACTION, mNetWorkIntentListener)
}
fun releaseListener(){
//自动驾驶状态监听
CallerAutoPilotStatusListenerManager.removeListener(TAG)
// 定位监听
CallerChassisLocationGCJ02ListenerManager.removeListener(TAG)
CallerTelematicListenerManager.removeListener(TAG)
//自动驾驶轨迹监听
CallerPlanningRottingListenerManager.removeListener(TAG)
}
fun setDrivingInfoCallback(drivingInfoCallback : DrivingInfoCallback?){
mDrivingInfoCallback = drivingInfoCallback
}
fun setAutoStatusCallback(autoPilotStatusCallback: AutoPilotStatusCallback?){
mAutoStatusCallback = autoPilotStatusCallback
}
private val mNetWorkIntentListener = IMogoIntentListener { intentStr, _ ->
if (ConnectivityManager.CONNECTIVITY_ACTION == intentStr) {
if (NetworkUtils.isConnected(mContext)) {
queryDriverOperationStatus()
}
}
}
private val mReceivedMsgListener: IReceivedMsgListener =
object : IReceivedMsgListener{
@RequiresApi(Build.VERSION_CODES.O)
override fun onReceivedMsg(type: Int, byteArray: ByteArray) {//接收司机端发来的信息
if (OchCommonConst.BUSINESS_STRING == type){
val msg = GsonUtils.fromJson(String(byteArray),AppConnectMsg::class.java) as AppConnectMsg
Logger.d(SceneConstant.M_BUS_P+TAG,"onReceivedMsg = "+GsonUtils.toJson(msg))
if (msg.isPlay){ //播报
speakTTS(msg.msg)
}
if (msg.isViewShow){ //消息盒子显示内容
OCHSocketMessageManager.pushAppOperationalMsgBox(
DateTimeUtil.getCurrentTimeStamp(),msg.msg)
}
}
}
}
@RequiresApi(Build.VERSION_CODES.O)
private fun speakTTS(msg: String) {
var mAudioManager = mContext?.getSystemService(Context.AUDIO_SERVICE) as AudioManager
var mAudioAttributes = AudioAttributes.Builder()
.setUsage(AudioAttributes.USAGE_MEDIA) //设置声音的用途
.setContentType(AudioAttributes.CONTENT_TYPE_MUSIC) //设置声音的类型
.build()
var mAudioFocusRequest = AudioFocusRequest.Builder(AudioManager.AUDIOFOCUS_GAIN_TRANSIENT_MAY_DUCK) //设置焦点类型
.setAudioAttributes(mAudioAttributes) //设置声音属性
.setAcceptsDelayedFocusGain(false) //设置接受延迟获取焦点需要设置OnAudioFocusChangeListener来监听焦点的获取
.build()
mAudioManager.requestAudioFocus(mAudioFocusRequest) //抢占焦点
AIAssist.getInstance(mContext).speakTTSVoiceWithLevel(msg,AIAssist.LEVEL0,object : IMogoVoiceCmdCallBack{
override fun onSpeakEnd(speakText: String?) {
mAudioManager.abandonAudioFocusRequest(mAudioFocusRequest)
}
override fun onSpeakError(speakText: String?, errorMsg: String?) {
mAudioManager.abandonAudioFocusRequest(mAudioFocusRequest)
}
override fun onSpeakSelectTimeOut(speakText: String?) {
mAudioManager.abandonAudioFocusRequest(mAudioFocusRequest)
}
})
}
private val mMapLocationListener: IMoGoChassisLocationGCJ02Listener =
object : IMoGoChassisLocationGCJ02Listener{
override fun onChassisLocationGCJ02(mogoLocation: MogoLocation?) {
if (null == mogoLocation) return
mLocation = mogoLocation
updateSpeed(mogoLocation)
}
}
private val moGoAutopilotPlanningListener = object : IMoGoPlanningRottingListener{
override fun onAutopilotRotting(globalPathResp: MessagePad.GlobalPathResp?) {
d(SceneConstant.M_BUS_P + TAG, "och-rotting==globalPathResp = " + GsonUtils.toJson(globalPathResp))
globalPathResp?.let {
d(SceneConstant.M_BUS_P + TAG, "och-rotting==wayPointsSize = " + it.wayPointsList.size)
updateRoutePoints(it.wayPointsList)
}
}
}
fun updateRoutePoints(routePoints: List<MessagePad.Location>?) {
mRoutePoints.clear()
val latLngModels = CoordinateCalculateRouteUtil
.coordinateConverterWgsToGcjLocations(mContext, routePoints)
d(SceneConstant.M_BUS_P + TAG, "och-rotting==latLngModels = " + latLngModels.size)
mRoutePoints.addAll(latLngModels)
calculateTwoStationsRoute()
}
private fun updateSpeed(mogoLocation: MogoLocation) {
// km/h
val speedKM = (abs(mogoLocation.gnssSpeed) * 3.6f).toInt()
mDrivingInfoCallback?.updateSpeed(speedKM)
}
private val mAutoPilotStatusListener: IMoGoAutopilotStatusListener =
object : IMoGoAutopilotStatusListener {
override fun onAutopilotArriveAtStation(arrivalNotification: MessagePad.ArrivalNotification?) {
super.onAutopilotArriveAtStation(arrivalNotification)
}
override fun onAutopilotStatusResponse(autoPilotStatusInfo: AutopilotStatusInfo) {
super.onAutopilotStatusResponse(autoPilotStatusInfo)
val status = autoPilotStatusInfo.state
if (mCurrentAutoStatus == status) return
d(SceneConstant.M_BUS_P+TAG, "onAutopilotStatusResponse ===== $status")
if (IMoGoAutopilotStatusListener.STATUS_AUTOPILOT_RUNNING != status){
//美化模式下且行程中
if (FunctionBuildConfig.isDemoMode &&
mNextStationIndex>= 0 && mNextStationIndex <= mStations.size - 1
&& isGoingToNextStation){
mAutoStatusCallback?.updateAutoStatus(true)
}else{//非美化模式下
mAutoStatusCallback?.updateAutoStatus(false)
}
}else{//自驾状态 2
mAutoStatusCallback?.updateAutoStatus(true)
}
mCurrentAutoStatus = status
}
}
private fun queryDriverOperationDelay() {
handler.sendEmptyMessageDelayed(MSG_QUERY_BUS_P_STATION,
BusPassengerConst.QUERY_BUS_P_STATION_DELAY
)
}
private fun queryDriverOperationStatus() {
mContext?.let {
PM2ServiceManager.queryDriverOperationStatus(
it,
object : OchCommonServiceCallback<PM2OperationStatusResponse> {
override fun onSuccess(data: PM2OperationStatusResponse?) {
if (data?.data == null) return
if (data.data.driverStatus != operationStatus?.driverStatus
|| data.data.plateNumber != operationStatus?.plateNumber){
d(SceneConstant.M_BUS_P+TAG, "queryDriverOperationStatus ===== 车牌或者登陆状态有变更")
mDrivingInfoCallback?.changeOperationStatus(data.data.driverStatus == 1)
}
operationStatus = data.data as PM2OperationStatusResponse.Result
// mDrivingInfoCallback?.updatePlateNumber(data.data.plateNumber)
}
override fun onError() {
if (!NetworkUtils.isConnected(mContext)) {
ToastUtils.showShort(mContext!!.getString(R.string.network_error_tip))
} else {
ToastUtils.showShort(mContext!!.getString(R.string.request_error_tip))
}
queryDriverOperationDelay()
}
override fun onFail(code: Int, msg: String) {
//延迟3s再次查询
queryDriverOperationDelay()
}
})
}
}
fun queryDriverSiteByCoordinate(){
mContext?.let {
PM2ServiceManager.queryDriverSiteByCoordinate(it,
object : OchCommonServiceCallback<PM2RoutesResponse>{
override fun onSuccess(data: PM2RoutesResponse?) {
if (data == null || data.result == null){
if (routesResult != null) {
routesResult == null
updateLocalOrder()
d(SceneConstant.M_BUS_P+TAG, "queryDriverSiteByCoordinate= result is null")
return
}
return
}
if (data.result != null && data.result.equals(routesResult)){
d(SceneConstant.M_BUS_P+TAG, "queryDriverSiteByCoordinate= not update")
return
}
routesResult = data.result
updatePassengerRouteInfo(data.result)
}
override fun onFail(code: Int, msg: String?) {
d(SceneConstant.M_BUS_P+TAG, "queryDriverSiteByCoordinate = %s", msg)
if (code == 1003){
queryDriverOperationDelay()
}
if (PM2ServiceManager.driverAppSn.isEmpty()){
return
}
if (code == 1003) {
routesResult = null
isGoingToNextStation = false
startOrStopCalculateRouteInfo(false)
return
}
}
})
}
}
private fun updateLocalOrder(){
routesResult = null
mNextStationIndex = 0
isGoingToNextStation = false
startOrStopCalculateRouteInfo(false)
mDrivingInfoCallback?.showNoTaskView(true)
}
private fun updatePassengerRouteInfo(result: PM2RoutesResult) {
mDrivingInfoCallback?.updateLine(result.name, result.runningDur)
if (result.sites != null) {
mDrivingInfoCallback?.showNoTaskView(false)
val stations: List<PM2Station> = result.sites
mStations.clear()
mStations.addAll(stations)
mDrivingInfoCallback?.updateLineStations(mStations)
for (i in stations.indices) {
val station: PM2Station = stations[i]
if (station.drivingStatus == BusPassengerConst.STATION_STATUS_STOPPED
&& station.isLeaving && i + 1 < stations.size) {
mDrivingInfoCallback?.updateStationsInfo(stations as MutableList<PM2Station>, i + 1, false)
if (mNextStationIndex != i + 1) {
d(SceneConstant.M_BUS_P+TAG,"och-rotting--start ")
mTwoStationsRouts.clear()
startRemainRouteInfo()
}
isGoingToNextStation = true
mNextStationIndex = i + 1
return
} else if (station.drivingStatus == BusPassengerConst.STATION_STATUS_STOPPED && !station.isLeaving) {
mPreRouteIndex = 0
isGoingToNextStation = false
startOrStopCalculateRouteInfo(false)
mDrivingInfoCallback?.updateStationsInfo(stations as MutableList<PM2Station>, i, true)
return
}
}
}
}
fun loopRouteAndWipe(){
if (mRoutePoints != null && mRoutePoints.size > 0 && mLocation != null) {
val haveArrivedIndex = CoordinateCalculateRouteUtil
.getArrivedPointIndexNew(
mWipePreIndex,
mRoutePoints,
mLocation
)
mWipePreIndex = haveArrivedIndex
d(SceneConstant.M_BUS_P + TAG,
"thread = " + Thread.currentThread().name + " haveArrivedIndex== " + haveArrivedIndex
)
// if (mAutopilotPlanningCallback != null) {
// val routePoints = CoordinateCalculateRouteUtil
// .coordinateConverterLocationToLatLng(mContext, mRoutePoints)
// mAutopilotPlanningCallback.routeResult(routePoints, haveArrivedIndex)
// }
}
}
private fun startRemainRouteInfo() {
//开启实时计算剩余距离,剩余时间,预计时间
startOrStopCalculateRouteInfo(true)
}
fun dynamicCalculateRouteInfo(){
//计算当前位置和下一站的剩余点集合
//计算剩余点总里程和时间
//计算当前位置和下一站的剩余点集合
//计算剩余点总里程和时间
if (mTwoStationsRouts.size == 0) {
calculateTwoStationsRoute()
}
if (mTwoStationsRouts.size > 0 && mLocation != null) {
val lastPointsMap = CoordinateCalculateRouteUtil
.getRemainPointListByCompareNew(mPreRouteIndex, mTwoStationsRouts, mLocation)
for (index in lastPointsMap.keys) {
mPreRouteIndex = index
break
}
for (lastPoints in lastPointsMap.values) {
d(SceneConstant.M_BUS_P + TAG, "och-rotting==lastPoints.size() = " + lastPoints.size)
var lastSumLength = 0f
lastSumLength = if (lastPoints.size == 1) { //只是最后一个点,计算当前位置和最后一个点的距离
if (mNextStationIndex <= mStations.size - 1 && mNextStationIndex >= 0) {
val stationNext: PM2Station = mStations[mNextStationIndex]
CoordinateUtils.calculateLineDistance(
stationNext.gcjLon, stationNext.gcjLat,
mLocation!!.longitude, mLocation!!.latitude
)
} else {
CoordinateUtils.calculateLineDistance(
lastPoints[0].longitude, lastPoints[0].latitude,
mLocation!!.longitude, mLocation!!.latitude
)
}
} else {
CoordinateCalculateRouteUtil.calculateRouteSumLength(lastPoints)
}
val lastTime = lastSumLength / BusPassengerConst.SHUTTLE_AVERAGE_SPEED * 3.6 //秒
d(SceneConstant.M_BUS_P + TAG, "och-rotting==lastSumLength = $lastSumLength")
mDrivingInfoCallback?.updateRemainMT(
lastSumLength.toLong(),
lastTime.toLong()
)
}
}
}
private fun calculateTwoStationsRoute() {
//找出前往站对应的轨迹点,拿出两站点的集合
d(SceneConstant.M_BUS_P + TAG, "mRoutePoints.size() = " + mRoutePoints.size)
if (mRoutePoints.size > 0) {
if (mStations.size > 1) { //两个站点及以上要计算两个站点间的轨迹路线
if (mNextStationIndex <= mStations.size - 1 && mNextStationIndex - 1 >= 0) {
mTwoStationsRouts.clear()
val stationNext: PM2Station = mStations[mNextStationIndex]
val stationCur: PM2Station = mStations[mNextStationIndex - 1]
//当前站在轨迹中对应的点
val currentRouteIndex = CoordinateCalculateRouteUtil.getArrivedPointIndexNew(
0, mRoutePoints, stationCur.gcjLon, stationCur.gcjLat
)
//要前往的站在轨迹中对应的点
val nextRouteIndex = CoordinateCalculateRouteUtil.getArrivedPointIndexNew(
currentRouteIndex,
mRoutePoints,
stationNext.gcjLon,
stationNext.gcjLat
)
d(SceneConstant.M_BUS_P + TAG, "och-rotting==currentRouteIndex = " + currentRouteIndex
+ " nextRouteIndex = " + nextRouteIndex)
if (currentRouteIndex < nextRouteIndex) { //如果找到的next在起点的轨迹前面直接舍弃这个轨迹不显示
mTwoStationsRouts.addAll(
mRoutePoints.subList(
currentRouteIndex,
nextRouteIndex + 1
)
)
}
}
}
}
}
/**
* 开始轮询计算剩余里程和时间
* @param isStart
*/
fun startOrStopCalculateRouteInfo(isStart: Boolean) {
d(SceneConstant.M_BUS_P+TAG, "startOrStopCalculateRouteInfo() $isStart")
if (isStart) {
PM2ModelLoopManager.startCalculateRouteInfoLoop()
} else {
mTwoStationsRouts.clear()
PM2ModelLoopManager.stopCalculateRouteInfLoop()
}
}
/**
* 实时轨迹擦除
* @param isStart
*/
private fun startOrStopRouteAndWipe(isStart: Boolean) {
if (isStart) {
PM2ModelLoopManager.startOrStopRouteAndWipe()
} else {
mWipePreIndex = 0
PM2ModelLoopManager.stopOrStopRouteAndWipe()
}
}
private fun startOrStopOrderLoop(start: Boolean) {
d(SceneConstant.M_BUS_P + TAG, "startOrStopOrderLoop() $start")
if (start) {
PM2ModelLoopManager.startQueryDriverLineLoop()
} else {
PM2ModelLoopManager.stopQueryDriverLineLoop()
}
}
}

View File

@@ -0,0 +1,77 @@
package com.mogo.och.bus.passenger.model
import android.content.Context
import com.mogo.eagle.core.function.call.telematic.CallerTelematicManager.getServerToken
import com.mogo.cloud.passport.MoGoAiCloudClientConfig
import com.mogo.eagle.core.network.MoGoRetrofitFactory
import com.mogo.och.bus.passenger.bean.PM2OperationStatusResponse
import com.mogo.och.bus.passenger.bean.PM2QueryLineRequest
import com.mogo.och.bus.passenger.bean.PM2RoutesResponse
import com.mogo.och.bus.passenger.network.PM2ServiceApi
import com.mogo.och.common.module.biz.constant.OchCommonConst
import com.mogo.och.common.module.biz.network.OchCommonServiceCallback
import com.mogo.och.common.module.biz.network.OchCommonSubscribeImpl
import com.mogo.och.common.module.biz.network.interceptor.transformTry
/**
* Created on 2022/3/31
*/
object PM2ServiceManager {
private var mBusPassengerServiceApi =
MoGoRetrofitFactory.getInstance(OchCommonConst.getShuttleUrl()).create(PM2ServiceApi::class.java)
private var driverSnCache = ""
/**
* 获取Bus司机端的sn
* @return
*/
public val driverAppSn: String
get(){
val serverToken = getServerToken()
if (serverToken != driverSnCache && serverToken.isNotEmpty()) {
driverSnCache = serverToken
}
return driverSnCache
}
/**
* 查询绑定行驶的小巴车路线
* @param context
* @param callback
*/
@JvmStatic
fun queryDriverSiteByCoordinate(
context: Context, callback: OchCommonServiceCallback<PM2RoutesResponse>?
) {
mBusPassengerServiceApi.queryDriverSiteByCoordinate(
MoGoAiCloudClientConfig.getInstance().serviceAppId,
MoGoAiCloudClientConfig.getInstance().token,
PM2QueryLineRequest(
driverAppSn
)
).transformTry()
.subscribe(OchCommonSubscribeImpl(context, callback, "queryDriverSiteByCoordinate=sn =$driverAppSn"))
}
/**
* 查询司机端出车收车状态,以及车牌号
* @param context
* @param callback
*/
@JvmStatic
fun queryDriverOperationStatus(
context: Context,
callback: OchCommonServiceCallback<PM2OperationStatusResponse>?
) {
mBusPassengerServiceApi.queryDriverOperationStatus(
MoGoAiCloudClientConfig.getInstance().serviceAppId,
MoGoAiCloudClientConfig.getInstance().token,
driverAppSn
)
.transformTry()
.subscribe(OchCommonSubscribeImpl(context, callback, "queryDriverOperationStatus=sn =$driverAppSn"))
}
}

View File

@@ -0,0 +1,127 @@
package com.mogo.och.bus.passenger.network
import com.mogo.eagle.core.utilcode.mogo.logger.CallerLogger.i
import com.mogo.eagle.core.utilcode.mogo.logger.scene.SceneConstant
import com.mogo.och.bus.passenger.constant.BusPassengerConst
import com.mogo.och.bus.passenger.model.PM2DrivingModel
import io.reactivex.Observable
import io.reactivex.ObservableOnSubscribe
import io.reactivex.android.schedulers.AndroidSchedulers
import io.reactivex.disposables.CompositeDisposable
import io.reactivex.disposables.Disposable
import io.reactivex.schedulers.Schedulers
import java.util.concurrent.TimeUnit
/**
* @author: wangmingjun
* @date: 2023/2/1
*/
object PM2ModelLoopManager {
private val TAG: String = PM2ModelLoopManager::class.java.getSimpleName()
private var mQueryLineDisposable: Disposable? = null //心跳轮询
private var mRouteWipeDisposable: CompositeDisposable? = null //估计擦除
private var mCalculateRouteDisposable: CompositeDisposable? = null //每隔2s计算一次剩余里程和时间
fun startOrStopRouteAndWipe() {
i(SceneConstant.M_BUS_P + TAG, "startOrStopRouteWipe()")
if (mRouteWipeDisposable != null) return
if (mRouteWipeDisposable == null) {
mRouteWipeDisposable = CompositeDisposable()
}
val disposable = startLoopRouteAndWipe()
.doOnSubscribe { }
.doOnError { }
.delay(
BusPassengerConst.LOOP_LINE_1S,
TimeUnit.MILLISECONDS,
true
) // 设置delayError为true表示出现错误的时候也需要延迟5s进行通知达到无论是请求正常还是请求失败都是5s后重新订阅即重新请求。
.subscribeOn(Schedulers.io())
.repeat() // repeat保证请求成功后能够重新订阅。
.retry() // retry保证请求失败后能重新订阅
.observeOn(AndroidSchedulers.mainThread())
.subscribe { }
mRouteWipeDisposable!!.add(disposable)
}
fun stopOrStopRouteAndWipe() {
if (mRouteWipeDisposable != null) {
mRouteWipeDisposable!!.dispose()
mRouteWipeDisposable = null
}
}
fun startQueryDriverLineLoop() {
if (mQueryLineDisposable != null && !mQueryLineDisposable!!.isDisposed) {
return
}
i(SceneConstant.M_BUS_P + TAG, "startQueryDriverLineLoop()")
mQueryLineDisposable = Observable.interval(
BusPassengerConst.LOOP_DELAY,
BusPassengerConst.LOOP_LINE_2S, TimeUnit.MILLISECONDS
)
.map { aLong: Long -> aLong + 1 }
.subscribeOn(Schedulers.io())
.observeOn(AndroidSchedulers.mainThread())
.subscribe { aLong: Long? ->
PM2DrivingModel.INSTANCE.queryDriverSiteByCoordinate()
}
}
fun stopQueryDriverLineLoop() {
if (mQueryLineDisposable != null) {
i(SceneConstant.M_BUS_P + TAG, "stopQueryDriverLineLoop()")
mQueryLineDisposable!!.dispose()
mQueryLineDisposable = null
}
}
fun startCalculateRouteInfoLoop() {
i(SceneConstant.M_BUS_P + TAG, "startCalculateRouteInfoLoop()")
if (mCalculateRouteDisposable != null) return
if (mCalculateRouteDisposable == null) {
mCalculateRouteDisposable = CompositeDisposable()
}
val disposable = startLoopCalculateRouteInfo()
.doOnSubscribe { }
.doOnError { }
.delay(
BusPassengerConst.LOOP_LINE_2S,
TimeUnit.MILLISECONDS,
true
) // 设置delayError为true表示出现错误的时候也需要延迟5s进行通知达到无论是请求正常还是请求失败都是5s后重新订阅即重新请求。
.subscribeOn(Schedulers.io())
.repeat() // repeat保证请求成功后能够重新订阅。
.retry() // retry保证请求失败后能重新订阅
.observeOn(AndroidSchedulers.mainThread())
.subscribe { }
mCalculateRouteDisposable!!.add(disposable)
}
fun stopCalculateRouteInfLoop() {
if (mCalculateRouteDisposable != null) {
i(SceneConstant.M_BUS_P + TAG, "stopCalculateRouteInfLoop()")
mCalculateRouteDisposable!!.dispose()
mCalculateRouteDisposable = null
}
}
private fun startLoopRouteAndWipe(): Observable<Int?> {
return Observable.create(ObservableOnSubscribe { emitter ->
if (emitter.isDisposed) return@ObservableOnSubscribe
PM2DrivingModel.INSTANCE.loopRouteAndWipe()
emitter.onComplete()
})
}
private fun startLoopCalculateRouteInfo(): Observable<Int?> {
return Observable.create(ObservableOnSubscribe { emitter ->
if (emitter.isDisposed) return@ObservableOnSubscribe
PM2DrivingModel.INSTANCE.dynamicCalculateRouteInfo()
emitter.onComplete()
})
}
}

View File

@@ -0,0 +1,40 @@
package com.mogo.och.bus.passenger.network;
import com.mogo.och.bus.passenger.bean.PM2OperationStatusResponse;
import com.mogo.och.bus.passenger.bean.PM2QueryLineRequest;
import com.mogo.och.bus.passenger.bean.PM2RoutesResponse;
import io.reactivex.Observable;
import retrofit2.http.Body;
import retrofit2.http.GET;
import retrofit2.http.Header;
import retrofit2.http.Headers;
import retrofit2.http.POST;
import retrofit2.http.Query;
/**
* Created on 2022/3/31
*
* Bus乘客端接口定义
*/
public interface PM2ServiceApi {
/**
* 查询bus司机端绑定路线
* @return 接口返回数据
*/
@Headers( {"Content-Type:application/json;charset=UTF-8"} )
@POST( "/och-shuttle-cabin/api/business/v1/passenger/lineDataWithDriver/query" )
Observable<PM2RoutesResponse> queryDriverSiteByCoordinate(@Header("appId") String appId, @Header("ticket") String ticket, @Body PM2QueryLineRequest request);
/**
* 查询司机端的登陆状态
* @param sn
* @return
*/
@Headers({"Content-type:application/json;charset=UTF-8"})
// @GET("/autopilot-car-hailing/car/v2/driver/bus/passenger/takeOrderStatus/query")
@GET("/och-shuttle-cabin/api/business/v1/passenger/loginStatus")
Observable<PM2OperationStatusResponse> queryDriverOperationStatus(@Header ("appId") String appId, @Header("ticket") String ticket, @Query("sn") String sn);
}

View File

@@ -0,0 +1,41 @@
package com.mogo.och.bus.passenger.presenter
import androidx.lifecycle.LifecycleOwner
import com.mogo.commons.mvp.Presenter
import com.mogo.och.bus.passenger.callback.ADASCallback
import com.mogo.och.bus.passenger.constant.M2Const.Companion.M2_MAP_STATION_MAKER
import com.mogo.och.bus.passenger.model.PM2ADASModel
import com.mogo.och.bus.passenger.ui.PM2HPMapFragment
class PM2ADASPresenter(view: PM2HPMapFragment?) :
Presenter<PM2HPMapFragment?>(view), ADASCallback {
init {
PM2ADASModel.INSTANCE.init(context)
initListener()
}
private fun initListener() {
PM2ADASModel.INSTANCE.setAdasCallback(this)
}
private fun removeListener() {
PM2ADASModel.INSTANCE.setAdasCallback(null)
}
override fun onDestroy(owner: LifecycleOwner) {
super.onDestroy(owner)
removeListener()
}
override fun updateHDMapStations(stations: MutableList<MutableList<Double>>) {
for (i in stations.indices){
mView?.setMapMaker(M2_MAP_STATION_MAKER,stations[i])
}
}
override fun removeHDMapStations() {
mView?.removeMapMaker(M2_MAP_STATION_MAKER)
}
}

View File

@@ -0,0 +1,105 @@
package com.mogo.och.bus.passenger.presenter
import androidx.lifecycle.LifecycleOwner
import com.mogo.commons.mvp.Presenter
import com.mogo.eagle.core.utilcode.mogo.logger.CallerLogger
import com.mogo.eagle.core.utilcode.mogo.logger.scene.SceneConstant
import com.mogo.eagle.core.utilcode.util.ThreadUtils
import com.mogo.och.bus.passenger.bean.PM2Station
import com.mogo.och.bus.passenger.callback.AutoPilotStatusCallback
import com.mogo.och.bus.passenger.callback.DrivingInfoCallback
import com.mogo.och.bus.passenger.model.PM2ADASModel
import com.mogo.och.bus.passenger.model.PM2DrivingModel
import com.mogo.och.bus.passenger.ui.PM2DrivingInfoFragment
class PM2DrivingPresenter(view: PM2DrivingInfoFragment?) :
Presenter<PM2DrivingInfoFragment?>(view), DrivingInfoCallback, AutoPilotStatusCallback {
init {
PM2DrivingModel.INSTANCE.init(context)
PM2ADASModel.INSTANCE.init(context)
initListener()
}
override fun onDestroy(owner: LifecycleOwner) {
super.onDestroy(owner)
destroyListener()
PM2DrivingModel.INSTANCE.releaseListener()
}
private fun initListener(){
PM2DrivingModel.INSTANCE.setDrivingInfoCallback(this)
PM2DrivingModel.INSTANCE.setAutoStatusCallback(this)
}
private fun destroyListener(){
PM2DrivingModel.INSTANCE.setDrivingInfoCallback(null)
PM2DrivingModel.INSTANCE.setAutoStatusCallback(null)
}
override fun updateSpeed(speed: Int) {
// CallerLogger.d(
// SceneConstant.M_BUS_P + "speed = ",speed.toString()
// )
ThreadUtils.runOnUiThread {
mView?.updateSpeed(speed)
}
}
override fun updatePlateNumber(carNum: String) {
ThreadUtils.runOnUiThread {
mView?.updateCarPlateNum(carNum)
}
}
override fun updateLine(lineName: String, lineDuring: String) {
ThreadUtils.runOnUiThread {
mView?.updateTaskName(lineName)
mView?.updateTaskDuringTime(lineDuring)
}
}
override fun updateRemainMT(meters: Long, timeInSecond: Long) {
ThreadUtils.runOnUiThread {
mView?.updateRemainMT(meters, timeInSecond) //米,秒
}
}
override fun changeOperationStatus(loginStatus: Boolean) {
ThreadUtils.runOnUiThread {
mView?.changeOperationStatus(loginStatus)
}
}
override fun showNoTaskView(isTrue: Boolean) {
ThreadUtils.runOnUiThread {
mView?.showNoTaskView(!isTrue)
}
if (isTrue){
PM2ADASModel.INSTANCE.removeHDMapStations()
}
}
override fun updateLineStations(stations: MutableList<PM2Station>) {
ThreadUtils.runOnUiThread {
mView?.updateLineStations(stations)
}
PM2ADASModel.INSTANCE.updateHDMapStations(stations)
}
override fun updateStationsInfo(stations: MutableList<PM2Station>, i: Int, isArrived: Boolean) {
ThreadUtils.runOnUiThread {
mView?.updateStationsInfo(stations,i,isArrived)
}
}
override fun updateAutoStatus(isOpen: Boolean) {
ThreadUtils.runOnUiThread {
mView?.updateAutoStatus(isOpen)
}
}
override fun updateAutoStatus(status: Int) {
}
}

View File

@@ -0,0 +1,7 @@
package com.mogo.och.bus.passenger.presenter
import com.mogo.commons.mvp.Presenter
import com.mogo.och.bus.passenger.ui.PM2BaseFragment
class PM2Presenter(view: PM2BaseFragment?) :
Presenter<PM2BaseFragment?>(view)

View File

@@ -0,0 +1,7 @@
package com.mogo.och.bus.passenger.presenter
import com.mogo.commons.mvp.Presenter
import com.mogo.och.bus.passenger.ui.video.PM2VideoFragment
class PM2VideoPresenter(view: PM2VideoFragment?) :
Presenter<PM2VideoFragment?>(view)

View File

@@ -0,0 +1,33 @@
package com.mogo.och.bus.passenger.provider;
import android.content.Context;
import android.view.View;
import com.mogo.och.bus.passenger.ui.widget.M2StatusBarView;
import androidx.annotation.NonNull;
import com.alibaba.android.arouter.facade.annotation.Route;
import com.mogo.eagle.core.data.constants.MogoServicePaths;
import com.mogo.eagle.core.function.api.hmi.view.IStatusViewLayout;
/**
* @author congtaowang
* @since 2020-01-06
* <p>
* 根据优先级控制显示 window view.
*/
@Route( path = MogoServicePaths.PATH_STATUS_VIEW_MANAGER )
public class M2StatusViewManager implements IStatusViewLayout {
@NonNull
@Override
public View getStatusView(Context context) {
return new M2StatusBarView(context);
}
@Override
public void init(Context context) {
}
}

View File

@@ -0,0 +1,72 @@
package com.mogo.och.bus.passenger.ui
import android.provider.Settings
import android.view.Surface
import com.mogo.commons.mvp.MvpFragment
import com.mogo.och.bus.passenger.R
import com.mogo.och.bus.passenger.presenter.PM2Presenter
import com.mogo.och.bus.passenger.ui.video.PM2VideoFragment
/**
* @author: wangmingjun
* @date: 2022/4/12
*/
class PM2BaseFragment :
MvpFragment<PM2BaseFragment?, PM2Presenter?>() {
private var drivingFragment : PM2DrivingInfoFragment? = null
private var hdMapFragment : PM2HPMapFragment? = null
private var videoFragment : PM2VideoFragment? = null
override fun getLayoutId(): Int {
return R.layout.p_m2_fragment
}
override fun getTagName(): String {
return TAG
}
override fun initViews() {
//横竖屏
// setScreenDirection()
//隐藏小地图
initFragment()
}
// private fun setScreenDirection() {
// var ro = Settings.System.getInt(context?.contentResolver,
// Settings.System.USER_ROTATION,Surface.ROTATION_270)
// if (ro != Surface.ROTATION_270){
// ro = Surface.ROTATION_270
// }
// Settings.System.putInt(context?.contentResolver,
// Settings.System.USER_ROTATION,ro)
// }
/**
* 初始化行程信息,高静地图,宣传 三个fragment
*/
private fun initFragment() {
if (drivingFragment == null) drivingFragment = PM2DrivingInfoFragment()
childFragmentManager.beginTransaction().add(R.id.driving_fragment, drivingFragment!!)
.show(drivingFragment!!).commitAllowingStateLoss()
if (hdMapFragment == null) hdMapFragment = PM2HPMapFragment()
childFragmentManager.beginTransaction().add(R.id.hd_map_fragment, hdMapFragment!!)
.show(hdMapFragment!!).commitAllowingStateLoss()
if (videoFragment == null) videoFragment = PM2VideoFragment()
childFragmentManager.beginTransaction().add(R.id.video_fragment, videoFragment!!)
.show(videoFragment!!).commitAllowingStateLoss()
}
override fun createPresenter(): PM2Presenter {
return PM2Presenter(this)
}
companion object {
private val TAG = PM2BaseFragment::class.java.simpleName
}
}

View File

@@ -0,0 +1,253 @@
package com.mogo.och.bus.passenger.ui
import android.graphics.BitmapFactory
import android.os.Bundle
import android.os.Handler
import android.os.Looper
import android.os.Message
import android.view.View
import androidx.core.content.ContextCompat
import com.amap.api.maps.model.LatLng
import com.mogo.commons.mvp.MvpFragment
import com.mogo.eagle.core.function.hmi.ui.setting.ToggleDebugView
import com.mogo.eagle.core.utilcode.kotlin.onClick
import com.mogo.eagle.core.utilcode.util.DateTimeUtils
import com.mogo.eagle.core.utilcode.util.UiThreadHandler
import com.mogo.och.bus.passenger.R
import com.mogo.och.bus.passenger.bean.PM2Station
import com.mogo.och.bus.passenger.presenter.PM2DrivingPresenter
import com.mogo.och.common.module.utils.DateTimeUtil.*
import com.mogo.och.common.module.utils.NumberFormatUtil
import kotlinx.android.synthetic.m2.p_m2_driving_info_fragment.*
import java.lang.ref.WeakReference
import kotlin.math.ceil
import kotlin.math.roundToInt
/**
* @author: wangmingjun
* @date: 2022/4/12
*/
class PM2DrivingInfoFragment :
MvpFragment<PM2DrivingInfoFragment?, PM2DrivingPresenter?>() {
// private var timeHandler: TimeHandler? = null
/**
* 改变自动驾驶状态
*
* @param status 2 - running 1 - enable 2 - disable
*/
override fun getLayoutId(): Int {
return R.layout.p_m2_driving_info_fragment
}
override fun getTagName(): String {
return TAG
}
override fun initViews() {
speed_tv.setOnLongClickListener {
context?.let { ToggleDebugView.toggleDebugView.toggle(it) }
true
}
line_name_tv.setTextColor(resources.getColor(R.color.m2_line_name_tv_color))
station_name_tv.setTextColor(resources.getColor(R.color.m2_line_name_tv_color))
// current_time_tv.onClick {
// //测试V2X消息
// CallerMsgBoxManager.saveMsgBox(
// MsgBoxBean(
// MsgBoxType.V2X,
// V2XMsg(
// "6666",
// "超速行驶",
// ""
// )
// )
// )
//
// val noticeTrafficStylePushData = NoticeTrafficStylePushData()
// noticeTrafficStylePushData.content= "测试公告布局"
// val noticeFromCloudMsg = NoticeFrCloudMsg(null, noticeTrafficStylePushData, 1)
// CallerMsgBoxManager.saveMsgBox(
// MsgBoxBean(
// MsgBoxType.NOTICE, noticeFromCloudMsg)
// )
// BPRouteDataTestUtils.converToRouteData()
// }
updateCurrentTime()
}
override fun initViews(savedInstanceState: Bundle?) {
super.initViews(savedInstanceState)
overMapView?.let {
it.onCreateView(savedInstanceState)
}
}
override fun onResume() {
super.onResume()
overMapView?.let{
it.onResume()
}
}
override fun onPause() {
super.onPause()
overMapView?.let{
it.onPause()
}
}
override fun onDestroy() {
// timeHandler?.removeCallbacksAndMessages(null)
super.onDestroy()
overMapView?.let{
it.onDestroy()
}
}
fun updateSpeed(speed: Int){
speed_tv.text = speed.toString()
}
fun updateCarPlateNum(plateNum : String){
}
fun updateTaskName(name: String){
line_name_tv.text = name
}
fun updateTaskDuringTime(time : String){
line_during_tv.text = time
}
private fun updateCurrentTime(){
current_time_tv.text = formatCalendarToString(
DateTimeUtils.getCurrentDateTime(),HH_mm)
val date = formatCalendarToString(
DateTimeUtils.getCurrentDateTime(), yy_MM_dd)
val weekDay = DateTimeUtils.getWeekDayFromCalendar1(DateTimeUtils.getCurrentDateTime())
"$date $weekDay".also { current_weekday_tv.text = it }
sendUpdateTimeTask() // 每10s更新一次
}
fun changeOperationStatus(status:Boolean){
if (!status){
updateNoOrderUI()
}
}
fun showNoTaskView(haveTask: Boolean){
setLineInfoView(haveTask)
}
private fun setLineInfoView(isShow: Boolean){
if (isShow){
line_name_tv.visibility = View.VISIBLE
line_during_tv.visibility = View.VISIBLE
no_line_tv.visibility = View.GONE
}else{
updateNoOrderUI()
}
}
private fun updateNoOrderUI() {
line_name_tv.visibility = View.GONE
line_during_tv.visibility = View.GONE
no_line_tv.visibility = View.VISIBLE
updateNoStationView()
overMapView?.let {
it.clearSiteMarkers()
}
overMapView?.let {
it.clearCustomPolyline()
}
}
private fun updateNoStationView(){
station_name_tv.setTextColor(resources.getColor(R.color.m2_next_tv_color))
station_name_title_tv.text = resources.getString(R.string.m2_p_station_title_tv)
station_name_tv.text = resources.getString(R.string.m2_p_empty_tv)
remain_mt.text = resources.getString(R.string.m2_p_empty_remain_km_minute)
}
override fun createPresenter(): PM2DrivingPresenter {
return PM2DrivingPresenter(this)
}
fun updateAutoStatus(isAutoPilot: Boolean) {
if (isAutoPilot){
context?.let { auto_tv.setTextColor(ContextCompat.getColor(it,R.color.m2_p_white_color)) }
context?.let { auto_tv.background = ContextCompat.getDrawable(it,R.drawable.auto_button_bg) }
}else{
context?.let { auto_tv.setTextColor(ContextCompat.getColor(it,R.color.m2_button_auto_tv_color)) }
context?.let { auto_tv.background = ContextCompat.getDrawable(it,R.drawable.bg_p_m2_auto) }
}
}
fun updateLineStations(stations: MutableList<PM2Station>){
var stationsList = mutableListOf<LatLng>()
for (i in stations.indices){
val station = stations[i]
var latLng = LatLng(station.gcjLat,station.gcjLon)
stationsList.add(latLng)
}
overMapView?.let {
it.drawSiteMarkers(stationsList,
BitmapFactory.decodeResource(resources,R.drawable.m2_map_staton_icon),0.5f,0.9f)
}
}
fun updateStationsInfo(stations: MutableList<PM2Station>, i: Int, isArrived: Boolean){
if (stations.size == 0) return
if (0<= i && i<stations.size){
station_name_tv.setTextColor(resources.getColor(R.color.m2_next_tv_color))
station_name_tv.text = stations[i].name
}
if (isArrived){//到站
station_name_title_tv.text = resources.getString(R.string.m2_p_station_title_arrived_tv)
remain_mt.text = resources.getString(R.string.m2_p_empty_remain_km_minute)
}else{ //前往目的地中
station_name_title_tv.text = resources.getString(R.string.m2_p_station_title_tv)
}
}
/**
* 剩余里程和时间
*/
fun updateRemainMT(meters: Long, timeInSecond: Long) { //米。秒
var disUnit = "公里"
var remainDis: String? = "0"
if (meters > 0) {
if (meters / 1000 < 1) {
disUnit = ""
remainDis = meters.toFloat().roundToInt().toString()
} else {
disUnit = "公里"
remainDis = NumberFormatUtil.formatLong(meters.toDouble() / 1000)
}
}
val time = ceil(timeInSecond / 60f).toInt()
"$remainDis$disUnit | $time 分钟".also { remain_mt.text = it }
}
private fun sendUpdateTimeTask() {
UiThreadHandler.postDelayed({
updateCurrentTime()
},LOOP_TIME_TEXT)
}
companion object {
private val TAG = PM2DrivingInfoFragment::class.java.simpleName
const val LOOP_TIME_TEXT = 10 * 1000L
}
}

View File

@@ -0,0 +1,122 @@
package com.mogo.och.bus.passenger.ui
import android.os.Bundle
import com.mogo.commons.AbsMogoApplication
import com.mogo.commons.mvp.MvpFragment
import com.mogo.eagle.core.function.call.map.CallerMapUIServiceManager.getMapUIController
import com.mogo.eagle.core.function.call.map.CallerMapUIServiceManager.getMarkerManager
import com.mogo.eagle.core.utilcode.mogo.logger.CallerLogger.d
import com.mogo.map.marker.MogoMarkerOptions
import com.mogo.och.bus.passenger.R
import com.mogo.och.bus.passenger.constant.M2Const.Companion.TYPE_MARKER_M2_LINE
import com.mogo.och.bus.passenger.presenter.PM2ADASPresenter
import com.mogo.och.common.module.utils.OCHThreadPoolManager
import kotlinx.android.synthetic.m2.p_m2_hpmap_fragment.*
import java.util.*
/**
* @author: wangmingjun
* @date: 2022/4/12
*/
class PM2HPMapFragment :
MvpFragment<PM2HPMapFragment?, PM2ADASPresenter?>() {
/**
* 改变自动驾驶状态
*
* @param status 2 - running 1 - enable 2 - disable
*/
override fun getLayoutId(): Int {
return R.layout.p_m2_hpmap_fragment
}
override fun getTagName(): String {
return TAG
}
override fun initViews() {
}
override fun initViews(savedInstanceState: Bundle?) {
super.initViews(savedInstanceState)
mapBizView.onCreate(savedInstanceState)
}
override fun onResume() {
super.onResume()
mapBizView.onResume()
}
override fun onLowMemory() {
super.onLowMemory()
mapBizView.onLowMemory()
}
override fun onSaveInstanceState(outState: Bundle) {
super.onSaveInstanceState(outState)
mapBizView.onSaveInstanceState(outState)
}
override fun onPause() {
super.onPause()
mapBizView.onPause()
}
override fun onDestroyView() {
mapBizView.onDestroy()
super.onDestroyView()
}
override fun createPresenter(): PM2ADASPresenter {
return PM2ADASPresenter(this)
}
companion object {
private val TAG = PM2HPMapFragment::class.java.simpleName
}
fun setMapMaker(
uuid: String,
station: MutableList<Double>,
) {
//开启线程执行起终点marker设置
val setMapMarkerRunnable = Runnable {
d("setMapMaker= " + Thread.currentThread().name,
uuid + "=latitude=" + station[1] + ",longitude=" + station[0])
val options = MogoMarkerOptions()
.owner(TYPE_MARKER_M2_LINE)
.anchor(0.5f, 0.5f)
.set3DMode(true)
.gps(true)
.controlAngle(true)
.icon3DRes(R.raw.star_marker)
.longitude(station[0])
.latitude(station[1])
val marker = Objects.requireNonNull(
getMarkerManager(AbsMogoApplication.getApp())
)?.addMarker(uuid, options)
val centerLine =
getMapUIController()!!
.getCenterLineInfo(
station[0], station[1], -1f
)
if (null != centerLine && marker != null) { // 有可能鹰眼map为空没有角度。判空使用后可能造成maker角度跟道路角度不一致
marker.setRotateAngle(centerLine.angle!!.toFloat())
}
}
OCHThreadPoolManager.getsInstance().execute(setMapMarkerRunnable)
}
fun removeMapMaker(
uuid: String,
) {
//开启线程移除起终点marker设置
val removeMapMarkerRunnable = Runnable {
d("RemoveMapMaker=" + Thread.currentThread().name, uuid)
Objects.requireNonNull(
getMarkerManager(AbsMogoApplication.getApp())
)?.removeMarkers(uuid)
}
OCHThreadPoolManager.getsInstance().execute(removeMapMarkerRunnable)
}
}

View File

@@ -0,0 +1,234 @@
package com.mogo.och.bus.passenger.ui.video
import com.mogo.commons.mvp.MvpFragment
import com.mogo.och.bus.passenger.R
import com.mogo.och.bus.passenger.presenter.PM2VideoPresenter
import com.mogo.och.bus.passenger.ui.widget.video.RotationItem
import kotlinx.android.synthetic.m2.p_m2_video_fragment.*
/**
* @author: wangmingjun
* @date: 2022/4/12
*/
class PM2VideoFragment :
MvpFragment<PM2VideoFragment?, PM2VideoPresenter?>() {
private var arrayListOf = mutableListOf<RotationItem>()
override fun getLayoutId(): Int {
return R.layout.p_m2_video_fragment
}
override fun createPresenter(): PM2VideoPresenter {
return PM2VideoPresenter(this)
}
companion object {
private val TAG = PM2VideoFragment::class.java.simpleName
}
override fun getTagName(): String {
return TAG
}
override fun initViews() {
initResourceData()
imageVideoRotationView.setData(arrayListOf)
}
override fun onPause() {
super.onPause()
imageVideoRotationView.setPause()
}
override fun onResume() {
super.onResume()
imageVideoRotationView.setResume()
}
private fun initResourceData() {
arrayListOf.clear()
arrayListOf.add(
RotationItem(
"https://img.zhidaohulian.com/fileServer/online_car_hailing/1678946244305/dalim2.mp4",
1,
"",
"1"
)
)
// if (BuildConfig.FLAVOR.contains("dali")){ //大理 目前还都使用的mogo 的cos https://img.zhidaohulian.com/fileServer/online_car_hailing/1678932482045/1080%2A565%20.mp4
// arrayListOf.add(
// RotationItem(
// "https://img.zhidaohulian.com/fileServer/online_car_hailing/1678932482045/1080%2A565%20.mp4",
// 1,
// "",
// "1"
// )
// )
// }else if (BuildConfig.FLAVOR.contains("yantai")){ //烟台
// arrayListOf.add(
// RotationItem(
// "https://img.zhidaohulian.com/fileServer/online_car_hailing/1676357256102/1.jpg",
// 0,
// "",
// "1"
// )
// )
// arrayListOf.add(
// RotationItem(
// "https://img.zhidaohulian.com/fileServer/online_car_hailing/1676357382357/2.png",
// 0,
// "",
// "2"
// )
// )
// arrayListOf.add(
// RotationItem(
// "https://img.zhidaohulian.com/fileServer/online_car_hailing/1676357557335/3.mp4",
// 1,
// "https://img.zhidaohulian.com/fileServer/online_car_hailing/1676357382357/2.png",
// "3"
// )
// )
// arrayListOf.add(
// RotationItem(
// "https://img.zhidaohulian.com/fileServer/online_car_hailing/1676357598483/4.jpg",
// 0,
// "",
// "4"
// )
// )
// arrayListOf.add(
// RotationItem(
// "https://img.zhidaohulian.com/fileServer/online_car_hailing/1676357834634/5.m4v",
// 1,
// "https://img.zhidaohulian.com/fileServer/online_car_hailing/1676357598483/4.jpg",
// "5"
// )
// )
// arrayListOf.add(
// RotationItem(
// "https://img.zhidaohulian.com/fileServer/online_car_hailing/1676358660379/6.m4v",
// 1,
// "https://img.zhidaohulian.com/fileServer/online_car_hailing/1676357598483/4.jpg",
// "6"
// )
// )
// arrayListOf.add(
// RotationItem(
// "https://img.zhidaohulian.com/fileServer/online_car_hailing/1676360154589/7.jpg",
// 0,
// "",
// "7"
// )
// )
// arrayListOf.add(
// RotationItem(
// "https://img.zhidaohulian.com/fileServer/online_car_hailing/1676360185500/8.jpg",
// 0,
// "",
// "8"
// )
// )
// arrayListOf.add(
// RotationItem(
// "https://img.zhidaohulian.com/fileServer/online_car_hailing/1676360224773/9.png",
// 0,
// "",
// "9"
// )
// )
// arrayListOf.add(
// RotationItem(
// "https://img.zhidaohulian.com/fileServer/online_car_hailing/1676360274126/10.mp4",
// 1,
// "https://img.zhidaohulian.com/fileServer/online_car_hailing/1676360224773/9.png",
// "10"
// )
// )
// }else{ // mogo
// arrayListOf.add(
// RotationItem(
// "https://img.zhidaohulian.com/fileServer/online_car_hailing/1676357256102/1.jpg",
// 0,
// "",
// "1"
// )
// )
// arrayListOf.add(
// RotationItem(
// "https://img.zhidaohulian.com/fileServer/online_car_hailing/1676357382357/2.png",
// 0,
// "",
// "2"
// )
// )
// arrayListOf.add(
// RotationItem(
// "https://img.zhidaohulian.com/fileServer/online_car_hailing/1676357557335/3.mp4",
// 1,
// "https://img.zhidaohulian.com/fileServer/online_car_hailing/1676357382357/2.png",
// "3"
// )
// )
// arrayListOf.add(
// RotationItem(
// "https://img.zhidaohulian.com/fileServer/online_car_hailing/1676357598483/4.jpg",
// 0,
// "",
// "4"
// )
// )
// arrayListOf.add(
// RotationItem(
// "https://img.zhidaohulian.com/fileServer/online_car_hailing/1676357834634/5.m4v",
// 1,
// "https://img.zhidaohulian.com/fileServer/online_car_hailing/1676357598483/4.jpg",
// "5"
// )
// )
// arrayListOf.add(
// RotationItem(
// "https://img.zhidaohulian.com/fileServer/online_car_hailing/1676358660379/6.m4v",
// 1,
// "https://img.zhidaohulian.com/fileServer/online_car_hailing/1676357598483/4.jpg",
// "6"
// )
// )
// arrayListOf.add(
// RotationItem(
// "https://img.zhidaohulian.com/fileServer/online_car_hailing/1676360154589/7.jpg",
// 0,
// "",
// "7"
// )
// )
// arrayListOf.add(
// RotationItem(
// "https://img.zhidaohulian.com/fileServer/online_car_hailing/1676360185500/8.jpg",
// 0,
// "",
// "8"
// )
// )
// arrayListOf.add(
// RotationItem(
// "https://img.zhidaohulian.com/fileServer/online_car_hailing/1676360224773/9.png",
// 0,
// "",
// "9"
// )
// )
// arrayListOf.add(
// RotationItem(
// "https://img.zhidaohulian.com/fileServer/online_car_hailing/1676360274126/10.mp4",
// 1,
// "https://img.zhidaohulian.com/fileServer/online_car_hailing/1676360224773/9.png",
// "10"
// )
// )
// }
//
}
}

View File

@@ -0,0 +1,37 @@
package com.mogo.och.bus.passenger.ui.widget
import android.content.Context
import android.util.AttributeSet
import android.view.LayoutInflater
import com.mogo.eagle.core.function.api.devatools.IMoGoDevaToolsListener
import com.mogo.eagle.core.function.hmi.ui.widget.BlueToothView
import com.mogo.eagle.core.utilcode.util.ThreadUtils
import com.mogo.och.bus.passenger.R
import kotlinx.android.synthetic.m2.p_m2_view_blue_tooth.view.*
/**
* 魔戒蓝牙控件
* 放置于StatusBar右侧位置
* todo arrow
*/
class M2BlueToothView @JvmOverloads constructor(
context: Context,
attrs: AttributeSet? = null,
defStyleAttr: Int = 0
) : BlueToothView(context, attrs, defStyleAttr),IMoGoDevaToolsListener {
init {
LayoutInflater.from(context).inflate(R.layout.p_m2_view_blue_tooth, this, true)
}
override fun mofangStatus(status: Boolean) {
ThreadUtils.runOnUiThread {
if (status) {
blueView.setImageResource(R.drawable.m2_blue_tooth_close)
} else {
blueView.setImageResource(R.drawable.m2_blue_tooth_open)
}
}
}
}

View File

@@ -0,0 +1,179 @@
package com.mogo.och.bus.passenger.ui.widget
import android.content.Context
import android.util.AttributeSet
import android.view.LayoutInflater
import android.widget.LinearLayout
import com.mogo.eagle.core.data.enums.DataSourceType
import com.mogo.eagle.core.data.enums.TrafficLightEnum
import com.mogo.eagle.core.function.api.datacenter.union.IMoGoTrafficLightListener
import com.mogo.eagle.core.function.call.v2x.CallerTrafficLightListenerManager
import com.mogo.eagle.core.utilcode.util.UiThreadHandler
import com.mogo.och.bus.passenger.R
import kotlinx.android.synthetic.m2.m2_p_traffic_light_view.view.*
/**
* bus乘客端红绿灯view
*
* Created on 2022/3/14
*/
class M2PTrafficLightView @JvmOverloads constructor(
context: Context?,
attrs: AttributeSet? = null,
defStyleAttr: Int = 0
) : LinearLayout(context, attrs, defStyleAttr), IMoGoTrafficLightListener {
companion object {
private const val TAG = "M2PTrafficLightView"
}
private var mCurrentLightId = TrafficLightEnum.BLACK
init {
init(context)
}
private fun init(context: Context?) {
LayoutInflater.from(context).inflate(R.layout.m2_p_traffic_light_view, this, true)
}
override fun onAttachedToWindow() {
super.onAttachedToWindow()
CallerTrafficLightListenerManager.addListener(TAG, this)
}
override fun onDetachedFromWindow() {
super.onDetachedFromWindow()
CallerTrafficLightListenerManager.removeListener(TAG)
}
/**
* 展示红绿灯预警
*
* @param checkLightId 0-都是默认1-红2-黄3-绿
* @param lightSource 1:云端下发2:自车感知
*/
override fun showTrafficLight(checkLightId: TrafficLightEnum, lightSource: DataSourceType) {
super.showTrafficLight(checkLightId, lightSource)
mCurrentLightId = checkLightId
updateTrafficLightIcon(checkLightId)
}
/**
* 关闭红绿灯预警展示,并重制灯态
*/
override fun disableTrafficLight() {
super.disableTrafficLight()
UiThreadHandler.post {
mCurrentLightId = TrafficLightEnum.BLACK
this@M2PTrafficLightView.visibility = GONE
}
}
/**
* @param redNum 红灯倒计时
* @param yellowNum 黄灯倒计时
* @param greenNum 绿灯倒计时
*/
override fun changeCountdownTrafficLightNum(redNum: Int, yellowNum: Int, greenNum: Int) {
super.changeCountdownTrafficLightNum(redNum, yellowNum, greenNum)
resetView()
when (mCurrentLightId) {
TrafficLightEnum.RED -> changeCountdownRed(redNum)
TrafficLightEnum.YELLOW -> changeCountdownYellow(yellowNum)
TrafficLightEnum.GREEN -> changeCountdownGreen(greenNum)
else -> UiThreadHandler.post { m2_p_traffic_light_time_tv.text = "" }
}
}
override fun changeCountdownRed(redNum: Int) {
super.changeCountdownRed(redNum)
UiThreadHandler.post {
if (redNum > 0) {
resetView()
m2_p_traffic_light_time_tv.text = redNum.toString()
} else {
disableTrafficLightCountDown()
m2_p_traffic_light_time_tv.text = ""
}
}
}
override fun changeCountdownGreen(greenNum: Int) {
super.changeCountdownGreen(greenNum)
UiThreadHandler.post {
if (greenNum > 0) {
resetView()
m2_p_traffic_light_time_tv.text = greenNum.toString()
} else {
disableTrafficLightCountDown()
m2_p_traffic_light_time_tv.text = ""
}
}
}
override fun changeCountdownYellow(yellowNum: Int) {
super.changeCountdownYellow(yellowNum)
UiThreadHandler.post {
if (yellowNum > 0) {
resetView()
m2_p_traffic_light_time_tv.text = yellowNum.toString()
} else {
disableTrafficLightCountDown()
m2_p_traffic_light_time_tv.text = ""
}
}
}
/**
* 更新红绿灯icon
*
* @param lightId 0-都是默认1-红2-黄3-绿
*/
private fun updateTrafficLightIcon(lightId: TrafficLightEnum) {
UiThreadHandler.post {
when (lightId) {
TrafficLightEnum.RED -> {
m2_p_traffic_light_iv.setBackgroundResource(R.drawable.m2_light_red_nor)
this@M2PTrafficLightView.visibility = VISIBLE
}
TrafficLightEnum.YELLOW -> {
m2_p_traffic_light_iv.setBackgroundResource(R.drawable.m2_light_yellow_nor)
this@M2PTrafficLightView.visibility = VISIBLE
}
TrafficLightEnum.GREEN -> {
m2_p_traffic_light_iv.setBackgroundResource(R.drawable.m2_light_green_nor)
this@M2PTrafficLightView.visibility = VISIBLE
}
else -> this@M2PTrafficLightView.visibility = GONE
}
}
}
override fun disableTrafficLightCountDown() {
super.disableTrafficLightCountDown()
UiThreadHandler.post {
val layoutParams = layoutParams
if (layoutParams is MarginLayoutParams) {
val lp = layoutParams
lp.width = resources.getDimension(R.dimen.dp_40).toInt()
setLayoutParams(lp)
m2_p_traffic_light_time_tv.visibility = GONE
m2_p_traffic_light_bg.layoutParams.width =
resources.getDimension(R.dimen.dp_40).toInt()
}
}
}
private fun resetView() {
val layoutParams = layoutParams
if (layoutParams is MarginLayoutParams) {
val lp = layoutParams
lp.width = resources.getDimension(R.dimen.m2_p_light_width).toInt()
setLayoutParams(lp)
m2_p_traffic_light_time_tv.visibility = VISIBLE
m2_p_traffic_light_bg.layoutParams.width =
resources.getDimension(R.dimen.m2_p_light_width).toInt()
}
}
}

Some files were not shown because too many files have changed in this diff Show More