Merge remote-tracking branch 'origin/dev_robotaxi-d_240912_6.7.0' into dev_robotaxi-d_240912_6.7.0

This commit is contained in:
yangyakun
2024-09-25 20:04:22 +08:00
184 changed files with 4809 additions and 778 deletions

View File

@@ -59,5 +59,7 @@ class OchCommonConst {
// 自动驾驶自动规划的最大距离
const val AUTOMATIC_PLANNING_MAX_DISTANCE = 15
const val ARRIVE_AT_END_STATION_DISTANCE = 10
}
}

View File

@@ -69,8 +69,8 @@ object OchAutoPilotManager : IMoGoReceiveReceivedAckListener, IMoGoFsm2024Listen
fun canStartAutoPilotSSM(): Boolean {
if (!FunctionBuildConfig.isDemoMode && !OCHAdasAbilityManager.getInstance().autopilotAbilityStatus) {
val reasons = OCHAdasAbilityManager.getInstance().unableAutopilotReasons
if ("AutopilotAbility440" == OCHAdasAbilityManager.getInstance().abilityVersion && !reasons.isNullOrEmpty()) {
val msg = reasons[0].unableLaunchReason + " 来源:" + reasons[0].source
if ("AutopilotAbilityFSM" == OCHAdasAbilityManager.getInstance().abilityVersion && !reasons.isNullOrEmpty()) {
val msg = reasons[0].getUnableLaunchReason() + " 来源:" + reasons[0].source
CallerMsgBoxManager.saveMsgBox(
MsgBoxBean(
MsgBoxType.AUTOPILOT,
@@ -95,7 +95,6 @@ object OchAutoPilotManager : IMoGoReceiveReceivedAckListener, IMoGoFsm2024Listen
@JvmStatic
fun startAutoPilot(controlParameters: AutopilotControlParameters?): Long {
val sessionId = CallerAutoPilotControlManager.startAutoPilot(controlParameters)
LineManager.isReStartAutopilot = false
globalSessionId.set(sessionId)
fsmBackSessionId.set(-1L)
OchAutopilotAnalytics.triggerStartAutopilotParameters(controlParameters, sessionId)

View File

@@ -6,11 +6,13 @@ import com.mogo.eagle.core.function.api.autopilot.IMoGoAutopilotStatusListener
import com.mogo.eagle.core.function.call.autopilot.CallerAutoPilotControlManager
import com.mogo.eagle.core.function.call.autopilot.CallerAutoPilotStatusListenerManager
import com.mogo.eagle.core.utilcode.mogo.AppIdentityModeUtils
import com.mogo.eagle.core.utilcode.util.StringUtils
import com.mogo.eagle.core.utilcode.util.ToastUtils
import com.mogo.och.common.module.R
import com.mogo.och.common.module.manager.autopilot.autopilot.bean.ArrivedStation
import com.mogo.och.common.module.manager.autopilot.line.LineManager
import com.mogo.och.common.module.manager.autopilot.trajectory.TrajectoryManager
import com.mogo.och.common.module.manager.logchainanalytic.OchChainLogManager
import com.mogo.och.common.module.utils.CallerBase
import com.zhjt.mogo.adas.data.AdasConstants
import com.zhjt.mogo.adas.data.bean.MogoReport
@@ -51,10 +53,12 @@ object OchAutoPilotStatusListenerManager : CallerBase<IOchAutopilotStatusListene
LineManager.triggerStartServiceEvent(true, 0)
}
M_LISTENERS.forEach {
val listener = it.value
listener.onAutopilotStatusResponse(newValue)
}
LineManager.searchAutopilotState()
}
}
val autopilotState:Int
@@ -93,15 +97,6 @@ object OchAutoPilotStatusListenerManager : CallerBase<IOchAutopilotStatusListene
}
}
override fun onAutopilotArriveAtStation(arrivalNotification: MessagePad.ArrivalNotification?) {
super.onAutopilotArriveAtStation(arrivalNotification)
val trasform = ArrivedStation.trasform(arrivalNotification)
M_LISTENERS.forEach {
val listener = it.value
listener.onAutopilotArriveAtStation(trasform)
}
}
override fun onAutopilotSNRequest(basicInfoReq: MessagePad.BasicInfoReq) {
super.onAutopilotSNRequest(basicInfoReq)
M_LISTENERS.forEach {
@@ -196,6 +191,7 @@ object OchAutoPilotStatusListenerManager : CallerBase<IOchAutopilotStatusListene
override fun onAutopilotStatusResponseFromCan(state: Int) {
super.onAutopilotStatusResponseFromCan(state)
LineManager.searchAutopilotState()
M_LISTENERS.forEach {
val listener = it.value
listener.onAutopilotStatusResponseFromCan(state)
@@ -206,4 +202,36 @@ object OchAutoPilotStatusListenerManager : CallerBase<IOchAutopilotStatusListene
}
}
}
override fun onAutopilotArriveAtStation(arrivalNotification: MessagePad.ArrivalNotification?) {
super.onAutopilotArriveAtStation(arrivalNotification)
val trasform = ArrivedStation.trasform(arrivalNotification)
M_LISTENERS.forEach {
val listener = it.value
listener.onAutopilotArriveAtStation(trasform)
}
}
override fun onAutoPilotStation(
token: Long,
timestamp: Long,
autoPilotStation: SsmInfo.AutoPilotStation?
) {
OchChainLogManager.writeChainLogAutopilot("到站逻辑",
"token:$token 通过主动查询到站底盘传递:${autoPilotStation?.orderId}_${autoPilotStation?.arrivedStationFlag}")
autoPilotStation?.let {
if (it.hasOrderId() && !StringUtils.isEmpty(it.orderId)&&it.hasArrivedStationFlag()) {
LineManager.invokeArrivedStation(it.orderId,it.arrivedStationFlag)
}
}
}
override fun onAutoPilotInfo(token: Long, timestamp: Long, autoPilotInfo: SsmInfo.AutoPilotInfo?) {
OchChainLogManager.writeChainLogAutopilot("自驾状态",
"token:$token 通过主动查询到站底盘传递:${autoPilotInfo?.orderId}_第一次启动自驾${autoPilotInfo?.firstAutopilotFlag}_次数${autoPilotInfo?.count}")
autoPilotInfo?.let {
if (it.hasOrderId() && !StringUtils.isEmpty(it.orderId)) {
LineManager.invokeSetIsFirstAutopilot(it.orderId,it.firstAutopilotFlag,it.count)
}
}
}
}

View File

@@ -12,4 +12,6 @@ public interface ILineCallback {
default void startAutopilotTimeOut(){}
default void startAutopilotFailure(String startFailedCode,String startFailedMessage){}
default void arrivedStationSuccessBySearch(){}
}

View File

@@ -8,6 +8,7 @@ import com.mogo.eagle.core.data.autopilot.AutopilotControlParameters.AutoPilotLi
import com.mogo.eagle.core.data.autopilot.AutopilotControlParameters.AutoPilotLonLat
import com.mogo.eagle.core.data.config.FunctionBuildConfig
import com.mogo.eagle.core.data.map.MogoLocation
import com.mogo.eagle.core.function.api.autopilot.IMoGoChassisLocationGCJ02Listener
import com.mogo.eagle.core.function.call.autopilot.CallerAutoPilotControlManager
import com.mogo.eagle.core.function.call.autopilot.CallerAutoPilotStatusListenerManager
import com.mogo.eagle.core.function.call.map.CallerMapGlobalTrajectoryDrawManager
@@ -15,12 +16,15 @@ import com.mogo.eagle.core.function.call.order.CallerOrderListenerManager
import com.mogo.eagle.core.utilcode.mogo.logger.CallerLogger.d
import com.mogo.eagle.core.utilcode.mogo.logger.CallerLogger.e
import com.mogo.eagle.core.utilcode.mogo.logger.scene.SceneConstant.Companion.M_BUS
import com.mogo.eagle.core.utilcode.util.CoordinateUtils
import com.mogo.eagle.core.utilcode.util.StringUtils
import com.mogo.eagle.core.utilcode.util.ToastUtils
import com.mogo.och.common.module.constant.OchCommonConst
import com.mogo.och.common.module.manager.autopilot.OCHAdasAbilityManager
import com.mogo.och.common.module.manager.autopilot.autopilot.OchAutoPilotManager
import com.mogo.och.common.module.manager.autopilot.autopilot.OchAutoPilotManager.startAutoPilot
import com.mogo.och.common.module.manager.autopilot.autopilot.OchAutopilotAnalytics
import com.mogo.och.common.module.manager.autopilot.location.OchLocationManager
import com.mogo.och.common.module.manager.distance.TrajectoryAndDistanceManager
import com.mogo.och.common.module.manager.logchainanalytic.OchChainLogManager
import com.mogo.och.common.module.utils.CallerBase
@@ -64,14 +68,54 @@ object LineManager : CallerBase<ILineCallback>() {
*/
private var endStation: BusStationBean? = null
var isReStartAutopilot = true
var isFirstStartAutopilot = true
private var orderId = ""
// 自车定位
private val mMapLocationListener = object : IMoGoChassisLocationGCJ02Listener {
override fun onChassisLocationGCJ02(mogoLocation: MogoLocation?) {
if (null == mogoLocation) return
getStations { start, end ->
val startLon = end.gcjLon
val startLat = end.gcjLat
val distance = CoordinateUtils.calculateLineDistance(
startLon, startLat,
mogoLocation.longitude, mogoLocation.latitude
)
if (distance <= OchCommonConst.ARRIVE_AT_END_STATION_DISTANCE) {
val token = CallerAutoPilotControlManager.sendSsmFuncQueryAutoPilotStation(orderId)
OchChainLogManager.writeChainLogAutopilot("到站逻辑","距离站点:$distance 请求token$token")
}
}
}
}
fun invokeArrivedStation(orderId: String, arrivedStationFlag: Boolean) {
if (this.orderId==orderId&&arrivedStationFlag){
M_LISTENERS.forEach {
it.value.arrivedStationSuccessBySearch()
}
}
}
fun invokeSetIsFirstAutopilot(orderId: String?, firstAutopilotFlag: Boolean, count: Int) {
if (this.orderId==orderId){
if(count>=1){
isFirstStartAutopilot = false
}else{
isFirstStartAutopilot = true
}
}
}
/**
* 设置站点信息
*/
fun setStartAndEndStation(startStation: BusStationBean?, endStation: BusStationBean?) {
if(this.startStation!=startStation||this.endStation!=endStation){
isReStartAutopilot = true
isFirstStartAutopilot = true
}
this.startStation = startStation
this.endStation = endStation
@@ -197,11 +241,19 @@ object LineManager : CallerBase<ILineCallback>() {
endStationLocation.latitude = end.gcjLat
endStationLocation.longitude = end.gcjLon
TrajectoryAndDistanceManager.setStationPoint(startStationLocation, endStationLocation, lineInfo.lineId)
OchLocationManager.addGCJ02Listener(TAG,1,mMapLocationListener)
// 恢复启动自驾信息
searchAutopilotState()
}
}
fun searchAutopilotState(){
CallerAutoPilotControlManager.sendSsmFuncQueryAutoPilotInfo()
}
private fun clearAutopilotControlParameters(){
CallerAutoPilotStatusListenerManager.updateAutopilotControlParameters(null)
TrajectoryAndDistanceManager.setStationPoint(null, null, null)
this.orderId = ""
OchLocationManager.removeGCJ02Listener(TAG)
}
fun hasDrawnGlobalTrajectory(): Boolean {
@@ -245,6 +297,9 @@ object LineManager : CallerBase<ILineCallback>() {
parameters?.startLatLon = AutoPilotLonLat(start.lat, start.lon)
parameters?.endLatLon = AutoPilotLonLat(end.lat, end.lon)
parameters?.vehicleType = 10
this.orderId = "${lineInfo.lineId}_${start.siteId}_${end.siteId}"
parameters?.orderId = this.orderId
parameters?.firstAutopilotFlag = isFirstStartAutopilot
if (parameters?.autoPilotLine == null) {
parameters?.autoPilotLine = AutoPilotLine(
@@ -334,7 +389,7 @@ object LineManager : CallerBase<ILineCallback>() {
M_BUS + TAG,
"行程日志-开启自动驾驶====" + GsonUtil.jsonFromObject(parameters)
+ " startLatLon=" + parameters.startName + "endLatLon=" + parameters.endName +
"isRestart = " + LineManager.isReStartAutopilot
"isRestart = " + LineManager.isFirstStartAutopilot
)
M_LISTENERS.forEach {
@@ -354,7 +409,7 @@ object LineManager : CallerBase<ILineCallback>() {
fun triggerStartServiceEvent(send: Boolean,source:Int) {
getStationsWithLine { start, end, lineInfo ->
OchAutopilotAnalytics.triggerStartAutopilotEvent(
isReStartAutopilot,
isFirstStartAutopilot,
send,
start.name,
end.name,

View File

@@ -0,0 +1,48 @@
package com.mogo.och.common.module.wigets.biz
import android.content.Context
import android.util.AttributeSet
import android.view.LayoutInflater
import androidx.constraintlayout.widget.ConstraintLayout
import com.mogo.eagle.core.utilcode.kotlin.onClick
import com.mogo.och.common.module.R
import com.mogo.och.common.module.utils.ResourcesUtils
import kotlinx.android.synthetic.main.common_line_view.view.iv_toolkit_item_head
import kotlinx.android.synthetic.main.common_line_view.view.iv_toolkit_item_title
/**
*
*/
class OperationalInfoGatewayView : ConstraintLayout {
private val TAG = "LineView"
constructor(context: Context) : super(context)
constructor(context: Context, attributeSet: AttributeSet) : super(context, attributeSet)
constructor(context: Context, attributeSet: AttributeSet, defStyleAttr: Int) : super(
context,
attributeSet,
defStyleAttr
)
private fun initView() {
LayoutInflater.from(context).inflate(R.layout.common_line_view, this, true)
iv_toolkit_item_head.setImageResource(R.drawable.common_biz_operation)
iv_toolkit_item_title.text = ResourcesUtils.getString(R.string.common_operation)
}
override fun onAttachedToWindow() {
super.onAttachedToWindow()
}
init {
try {
initView()
} catch (e: Exception) {
e.printStackTrace()
}
}
}

View File

@@ -2,18 +2,22 @@ package com.mogo.och.common.module.wigets.map.drawline
import android.content.Context
import android.util.AttributeSet
import androidx.appcompat.widget.AppCompatImageView
import android.view.LayoutInflater
import androidx.constraintlayout.widget.ConstraintLayout
import androidx.lifecycle.ViewModelProvider
import androidx.lifecycle.findViewTreeViewModelStoreOwner
import com.mogo.eagle.core.utilcode.kotlin.onClick
import com.mogo.eagle.core.utilcode.util.ToastUtils
import com.mogo.och.common.module.R
import com.mogo.och.common.module.manager.autopilot.line.LineManager
import com.mogo.och.common.module.utils.ResourcesUtils
import kotlinx.android.synthetic.main.common_line_view.view.iv_toolkit_item_head
import kotlinx.android.synthetic.main.common_line_view.view.iv_toolkit_item_title
/**
*
*/
class LineView : AppCompatImageView, LineViewModel.ILineViewCallback {
class LineView : ConstraintLayout, LineViewModel.ILineViewCallback {
private val TAG = "LineView"
@@ -28,7 +32,9 @@ class LineView : AppCompatImageView, LineViewModel.ILineViewCallback {
)
private fun initView() {
setImageResource(R.drawable.common_map_line_close)
LayoutInflater.from(context).inflate(R.layout.common_line_view, this, true)
iv_toolkit_item_head.setImageResource(R.drawable.common_map_line_close)
iv_toolkit_item_title.text = ResourcesUtils.getString(R.string.common_line_info)
}
override fun onAttachedToWindow() {
@@ -62,7 +68,7 @@ class LineView : AppCompatImageView, LineViewModel.ILineViewCallback {
}
override fun setImageViewResource(name: Int) {
setImageResource(name)
iv_toolkit_item_head.setImageResource(name)
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 18 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 20 KiB

After

Width:  |  Height:  |  Size: 5.4 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 24 KiB

After

Width:  |  Height:  |  Size: 4.8 KiB

View File

@@ -0,0 +1,36 @@
<?xml version="1.0" encoding="utf-8"?>
<merge xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:background="@color/acc_default_txt_color"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:parentTag="androidx.constraintlayout.widget.ConstraintLayout">
<ImageView
android:id="@+id/iv_toolkit_item_head"
android:layout_width="@dimen/dp_160"
android:layout_height="@dimen/dp_160"
android:scaleType="fitXY"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintTop_toTopOf="parent"
android:src="@drawable/common_map_line_close"
/>
<TextView
android:id="@+id/iv_toolkit_item_title"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="@dimen/dp_1"
android:ellipsize="end"
android:gravity="center"
android:maxLines="2"
android:text="车道指引"
android:textColor="@color/color_FFFFFF"
android:textSize="@dimen/sp_38"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintTop_toBottomOf="@+id/iv_toolkit_item_head"/>
</merge>

View File

@@ -7,6 +7,9 @@
<string name="common_autopilot_start">START</string>
<string name="common_autopilot_fail">启动失败</string>
<string name="common_line_info">车道指引</string>
<string name="common_operation">运营看板</string>
<string name="module_och_taxi_login_title">欢迎您登录</string>
<string name="module_och_taxi_login_btn">登录</string>
<string name="module_och_taxi_login_get_code">获取验证码</string>

View File

@@ -18,6 +18,7 @@ import com.mogo.eagle.core.utilcode.util.ToastUtils
import com.mogo.eagle.core.utilcode.util.UiThreadHandler
import com.mogo.och.common.module.biz.login.LoginStatusManager
import com.mogo.och.common.module.manager.autopilot.autopilot.bean.ArrivedStation
import com.mogo.och.common.module.manager.autopilot.line.ILineCallback
import com.mogo.och.common.module.manager.autopilot.line.LineManager
import com.mogo.och.common.module.manager.autopilot.location.OchLocationManager
import com.mogo.och.common.module.manager.logchainanalytic.OchChainLogManager
@@ -73,8 +74,8 @@ object OrderModel {
// 加载核销模块
TicketModel.load()
// 定位监听
OchLocationManager.addGCJ02Listener(TAG, 5, mMapLocationListener)
LineManager.addListener(TAG,arriveStationBySearch)
OchTransform.addListener(TAG,ochTransform)
@@ -89,7 +90,7 @@ object OrderModel {
TicketModel.release()
OchLocationManager.removeGCJ02Listener(TAG)
LineManager.removeListener(TAG)
OchTransform.removeListener(TAG)
}
@@ -107,34 +108,17 @@ object OrderModel {
// 自车定位
private val mMapLocationListener = object : IMoGoChassisLocationGCJ02Listener {
override fun onChassisLocationGCJ02(mogoLocation: MogoLocation?) {
if (null == mogoLocation) return
private val arriveStationBySearch = object : ILineCallback {
override fun arrivedStationSuccessBySearch() {
//是否到站的围栏判断 离站状态并且自动驾驶还未触发到站
if (isGoingToNextStation && !isArrivedStation) {
OCHThreadPoolManager.getsInstance().locationExecute {
judgeArrivedStation(mogoLocation)
onArriveAt(null, "兜底:根据定位计算到站")
}
}
}
}
//根据围栏判断,是否到达站点
private fun judgeArrivedStation(location: MogoLocation) {
LineManager.getStations { start, end ->
val startLon = end.gcjLon
val startLat = end.gcjLat
val distance = CoordinateUtils.calculateLineDistance(
startLon, startLat,
location.longitude, location.latitude
)
if (distance <= BusConst.ARRIVE_AT_END_STATION_DISTANCE) {
d(M_BUS + TAG, "行程日志-judgeArrivedStation() distance = $distance to ${end.name}")
onArriveAt(null, "兜底:根据定位计算到站")
}
}
}
/**
* 查询小巴路线

View File

@@ -1,5 +1,6 @@
package com.mogo.och.weaknet.ui.fragment
import android.content.Context
import android.graphics.BitmapFactory
import android.os.Bundle
import android.view.LayoutInflater
@@ -10,11 +11,14 @@ import com.mogo.commons.mvp.MvpFragment
import com.mogo.commons.storage.SharedPrefsMgr
import com.mogo.eagle.core.data.config.FunctionBuildConfig
import com.mogo.eagle.core.data.temp.EventLogout
import com.mogo.eagle.core.function.api.och.toolkit.IToolKitItemClickListener
import com.mogo.eagle.core.function.call.autopilot.CallerAutopilotRecordListenerManager
import com.mogo.eagle.core.function.call.och.CallerEagleBaseFunctionCall4OchManager
import com.mogo.eagle.core.utilcode.mogo.logger.CallerLogger.d
import com.mogo.eagle.core.utilcode.mogo.logger.scene.SceneConstant
import com.mogo.och.common.module.utils.createQRCodeWithPicture
import com.mogo.och.common.module.wigets.BindQRCodeDialog
import com.mogo.och.common.module.wigets.map.drawline.LineView
import com.mogo.och.shuttle.weaknet.R
import com.mogo.och.weaknet.ui.bizswitch.SwitchBizView
import com.mogo.och.weaknet.ui.taskrunned.RunningTaskManager
@@ -35,6 +39,11 @@ import org.greenrobot.eventbus.ThreadMode
*/
class ShuttleFragment : MvpFragment<ShuttleFragment?, BusPresenter?>() {
private val runningTaskGateWay = "RUNNINGTASKGATEWAY"
private val lineView = "LINEVIEW"
override fun getLayoutId(): Int {
return R.layout.shuttle_weak_base_fragment
}
@@ -47,6 +56,15 @@ class ShuttleFragment : MvpFragment<ShuttleFragment?, BusPresenter?>() {
context?.let {
boneContainerView.addBizView(SwitchBizView(it))
CallerEagleBaseFunctionCall4OchManager.addSingleToolKitDefaultItem(runningTaskGateWay,"本地缓存任务", R.drawable.bus_running_task_history,4)
CallerEagleBaseFunctionCall4OchManager.addToolKitDefaultItemClickListener(runningTaskGateWay,object :
IToolKitItemClickListener{
override fun onItemClick(toolTag: String, ctx: Context?) {
RunningTaskManager.showBadCaseConfigWindow(it)
}
})
CallerEagleBaseFunctionCall4OchManager.addSingleToolKitCustomItem(lineView, LineView(it),10)
}
initListener()

View File

@@ -0,0 +1,53 @@
package com.mogo.och.weaknet.ui.taskrunned
import android.content.Context
import android.util.AttributeSet
import android.view.LayoutInflater
import android.widget.ImageView
import android.widget.TextView
import androidx.constraintlayout.widget.ConstraintLayout
import com.mogo.eagle.core.utilcode.kotlin.onClick
import com.mogo.och.common.module.utils.ResourcesUtils
import com.mogo.och.shuttle.weaknet.R
/**
*
*/
class RunningTaskGatewayView : ConstraintLayout {
private val TAG = "LineView"
constructor(context: Context) : super(context)
constructor(context: Context, attributeSet: AttributeSet) : super(context, attributeSet)
constructor(context: Context, attributeSet: AttributeSet, defStyleAttr: Int) : super(
context,
attributeSet,
defStyleAttr
)
private fun initView() {
LayoutInflater.from(context).inflate(R.layout.common_line_view, this, true)
findViewById<ImageView>(R.id.iv_toolkit_item_head).setImageResource(R.drawable.bus_running_task_history)
findViewById<TextView>(R.id.iv_toolkit_item_title).text = ResourcesUtils.getString(R.string.bus_running_tasked_gateway)
}
override fun onAttachedToWindow() {
super.onAttachedToWindow()
onClick {
RunningTaskManager.showBadCaseConfigWindow(context)
}
}
init {
try {
initView()
} catch (e: Exception) {
e.printStackTrace()
}
}
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 17 KiB

View File

@@ -60,6 +60,7 @@
<string name="bus_before_tips_s">距离发车时间还有%1$s分钟</string>
<string name="bus_pingxing_driver">平行驾驶</string>
<string name="bus_running_tasked_gateway">本地缓存任务</string>
<!-- region tts -->

View File

@@ -3,6 +3,7 @@ package com.mogo.och.taxi.ui;
import static com.mogo.och.taxi.constant.TaxiConst.TIMER_START_AUTOPILOT_INTERVAL;
import android.animation.ObjectAnimator;
import android.content.Context;
import android.os.Bundle;
import android.os.Handler;
import android.os.Looper;
@@ -15,6 +16,7 @@ import android.widget.RelativeLayout;
import android.widget.TextView;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.constraintlayout.widget.ConstraintLayout;
import androidx.constraintlayout.widget.Group;
import androidx.fragment.app.FragmentTransaction;
@@ -23,10 +25,12 @@ import com.mogo.commons.mvp.IView;
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.api.och.toolkit.IToolKitItemClickListener;
import com.mogo.eagle.core.function.call.autopilot.CallerAutoPilotControlManager;
import com.mogo.eagle.core.function.call.autopilot.CallerAutoPilotStatusListenerManager;
import com.mogo.eagle.core.function.call.autopilot.CallerAutopilotRecordListenerManager;
import com.mogo.eagle.core.function.call.devatools.CallerDevaToolsManager;
import com.mogo.eagle.core.function.call.och.CallerEagleBaseFunctionCall4OchManager;
import com.mogo.eagle.core.function.hmi.map.MapContainerLayout;
import com.mogo.eagle.core.function.view.MapRoamView;
import com.mogo.eagle.core.utilcode.mogo.view.OnPreventFastClickListener;
@@ -34,12 +38,14 @@ import com.mogo.eagle.core.utilcode.util.ToastUtils;
import com.mogo.eagle.core.utilcode.util.UiThreadHandler;
import com.mogo.map.listener.IMogoMapListener;
import com.mogo.och.common.module.utils.ResourcesUtils;
import com.mogo.och.common.module.wigets.map.drawline.LineView;
import com.mogo.och.common.module.wigets.map.orderstatus.OrderStatusView;
import com.mogo.och.common.module.wigets.map.overmapview.OverMapDialog;
import com.mogo.och.common.module.wigets.map.switchvisual.VisualViewDirver;
import com.mogo.eagle.core.function.call.hmi.CallerHmiViewControlListenerManager;
import com.mogo.och.taxi.R;
import java.lang.ref.WeakReference;
import me.jessyan.autosize.utils.AutoSizeUtils;
@@ -60,11 +66,11 @@ public abstract class BaseTaxiTabFragment<V extends IView, P extends Presenter<V
private FrameLayout flNaviPanelContainer;
private MapRoamView mapRoamView;
private Group groupTestPanel;
private FrameLayout mSpeedView;
// private FrameLayout mSpeedView;
private ImageView mAutopilotImage;
private TextView mAutopilotTv;
private ImageView mCloseNaviIcon;
protected VisualViewDirver visualViewDirver;
// protected VisualViewDirver visualViewDirver;
protected TaxiAmapNaviFragment ochAmapNaviFragment = null;
protected TaxiRottingNaviFragment taxiRottingNaviFragment = null;
@@ -74,6 +80,13 @@ public abstract class BaseTaxiTabFragment<V extends IView, P extends Presenter<V
private OverMapDialog overMapDialog;
private final Handler mHandler = new Handler(Looper.getMainLooper());
private String runningTaskGateWay = "RUNNINGTASKGATEWAY";
private String lineView = "LINEVIEW";
// 查看运营情况 点击账户信息右边的箭头展示
private WeakReference<TaxiPersonalDialogFragment> personalDialogFragment = null;
@Override
protected int getLayoutId() {
return R.layout.taxi_base_fragment;
@@ -90,15 +103,15 @@ public abstract class BaseTaxiTabFragment<V extends IView, P extends Presenter<V
mAutopilotImage = findViewById(R.id.module_och_autopilot_iv);
mAutopilotTv = findViewById(R.id.module_och_autopilot_tv);
flStationPanelContainer = findViewById(R.id.module_mogo_och_station_panel_container);
visualViewDirver = findViewById(R.id.vvd_change_angle);
// visualViewDirver = findViewById(R.id.vvd_change_angle);
mSpeedView = findViewById(R.id.taxi_speed_contain);
if (mSpeedView != null) {
CallerDevaToolsManager.INSTANCE.attachAutopilotBeforeLaunchView(mSpeedView.getContext(), mSpeedView);
}
// mSpeedView = findViewById(R.id.taxi_speed_contain);
// if (mSpeedView != null) {
// CallerDevaToolsManager.INSTANCE.attachAutopilotBeforeLaunchView(mSpeedView.getContext(), mSpeedView);
// }
mCloseNaviIcon = findViewById(R.id.taxi_close_navi_icon);
flNaviPanelContainer = findViewById(R.id.module_mogo_och_navi_panel_container);
mSpeedView.setLongClickable(true); //调试按钮任意模式下都开
// mSpeedView.setLongClickable(true); //调试按钮任意模式下都开
tvOperationStatus = findViewById(R.id.module_mogo_och_operation_status);
mDriverRole = findViewById(R.id.taxi_driver_role_tv);
@@ -120,14 +133,14 @@ public abstract class BaseTaxiTabFragment<V extends IView, P extends Presenter<V
});
// debug下调用测试面板 长按速度值 任意模式下调试都打开
mSpeedView.setOnLongClickListener(v -> {
if (groupTestPanel.getVisibility() == View.VISIBLE) {
groupTestPanel.setVisibility(View.GONE);
} else {
groupTestPanel.setVisibility(View.VISIBLE);
}
return false;
});
// mSpeedView.setOnLongClickListener(v -> {
// if (groupTestPanel.getVisibility() == View.VISIBLE) {
// groupTestPanel.setVisibility(View.GONE);
// } else {
// groupTestPanel.setVisibility(View.VISIBLE);
// }
// return false;
// });
CallerHmiViewControlListenerManager.INSTANCE.invokeMainPageViewVisible(View.VISIBLE);
onAutopilotStatusChanged(CallerAutoPilotStatusListenerManager.INSTANCE.getState(), CallerAutoPilotControlManager.INSTANCE.isCanStartAutopilot(false, 0));
@@ -176,6 +189,19 @@ public abstract class BaseTaxiTabFragment<V extends IView, P extends Presenter<V
// overMapDialog.showDialog();
// }
// });
if(getContext()!=null){
CallerEagleBaseFunctionCall4OchManager.INSTANCE.addSingleToolKitDefaultItem(runningTaskGateWay,"运营面板", R.drawable.common_biz_operation,4);
CallerEagleBaseFunctionCall4OchManager.INSTANCE.addToolKitDefaultItemClickListener(runningTaskGateWay,new IToolKitItemClickListener() {
@Override
public void onItemClick(@NonNull String toolTag, @Nullable Context ctx) {
personalDialogFragment = new WeakReference<>(new TaxiPersonalDialogFragment());
personalDialogFragment.get().show(getActivity().getSupportFragmentManager(), "service_data");
}
});
CallerEagleBaseFunctionCall4OchManager.INSTANCE.addSingleToolKitCustomItem(lineView, new LineView(getContext()),10);
}
}
@Override
@@ -233,7 +259,6 @@ public abstract class BaseTaxiTabFragment<V extends IView, P extends Presenter<V
mapContainerLayout = null;
mapRoamView = null;
groupTestPanel = null;
mSpeedView = null;
mAutopilotImage = null;
mAutopilotTv = null;
mCloseNaviIcon = null;
@@ -401,13 +426,13 @@ public abstract class BaseTaxiTabFragment<V extends IView, P extends Presenter<V
public void run() {
if(flStationPanelContainer!=null) {
flStationPanelContainer.setVisibility(View.GONE);
ConstraintLayout.LayoutParams layoutParams = (ConstraintLayout.LayoutParams) visualViewDirver.getLayoutParams();
layoutParams.startToStart = ConstraintLayout.LayoutParams.PARENT_ID;
layoutParams.bottomToTop = R.id.toolsView;
if (getContext() != null) {
layoutParams.setMarginStart(AutoSizeUtils.dp2px(getContext(), 29));
}
visualViewDirver.setLayoutParams(layoutParams);
// ConstraintLayout.LayoutParams layoutParams = (ConstraintLayout.LayoutParams) visualViewDirver.getLayoutParams();
// layoutParams.startToStart = ConstraintLayout.LayoutParams.PARENT_ID;
// layoutParams.bottomToTop = R.id.toolsView;
// if (getContext() != null) {
// layoutParams.setMarginStart(AutoSizeUtils.dp2px(getContext(), 29));
// }
// visualViewDirver.setLayoutParams(layoutParams);
}
}
},UiThreadHandler.MODE.QUEUE);
@@ -419,13 +444,13 @@ public abstract class BaseTaxiTabFragment<V extends IView, P extends Presenter<V
public void run() {
if(flStationPanelContainer!=null) {
flStationPanelContainer.setVisibility(View.VISIBLE);
ConstraintLayout.LayoutParams layoutParams = (ConstraintLayout.LayoutParams) visualViewDirver.getLayoutParams();
layoutParams.startToStart = ConstraintLayout.LayoutParams.PARENT_ID;
layoutParams.bottomToTop = R.id.toolsView;
if (getContext() != null) {
layoutParams.setMarginStart(AutoSizeUtils.dp2px(getContext(), 618));
}
visualViewDirver.setLayoutParams(layoutParams);
// ConstraintLayout.LayoutParams layoutParams = (ConstraintLayout.LayoutParams) visualViewDirver.getLayoutParams();
// layoutParams.startToStart = ConstraintLayout.LayoutParams.PARENT_ID;
// layoutParams.bottomToTop = R.id.toolsView;
// if (getContext() != null) {
// layoutParams.setMarginStart(AutoSizeUtils.dp2px(getContext(), 618));
// }
// visualViewDirver.setLayoutParams(layoutParams);
}
}
},UiThreadHandler.MODE.QUEUE);

View File

@@ -60,8 +60,6 @@ public class TaxiFragment extends BaseTaxiTabFragment<TaxiFragment, TaxiPresente
// 待服务信息
private WeakReference<TaxiServerOrdersFragment> serverOrdersFragmentWR;
// 查看运营情况 点击账户信息右边的箭头展示
private WeakReference<TaxiPersonalDialogFragment> personalDialogFragment = null;
@Override
public void onActivityCreated(@Nullable Bundle savedInstanceState) {
@@ -366,16 +364,12 @@ public class TaxiFragment extends BaseTaxiTabFragment<TaxiFragment, TaxiPresente
@Subscribe(threadMode = ThreadMode.MAIN)
public void openOperationalInfoView(EventLogout eventLogout){
if (eventLogout.getMessgae() == EventLogout.PERSONAL_TYPE){
CallerLogger.d(M_TAXI + TAG,"openOperationalInfoView Event个人中心");
openOperationalInfoView();
}
// if (eventLogout.getMessgae() == EventLogout.PERSONAL_TYPE){
// CallerLogger.d(M_TAXI + TAG,"openOperationalInfoView Event个人中心");
// openOperationalInfoView();
// }
}
private void openOperationalInfoView(){
personalDialogFragment = new WeakReference<>(new TaxiPersonalDialogFragment());
personalDialogFragment.get().show(getActivity().getSupportFragmentManager(), "service_data");
}
private void testRouteInfoUpload() {
TPRouteDataTestUtils.converToRouteData();

View File

@@ -219,14 +219,14 @@
app:layout_constraintTop_toBottomOf="@+id/module_mogo_och_autopilot_status"
tools:visibility="visible" />
<com.mogo.och.common.module.wigets.map.switchvisual.VisualViewDirver
android:id="@+id/vvd_change_angle"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginStart="@dimen/dp_618"
android:layout_marginBottom="@dimen/dp_48"
app:layout_constraintBottom_toTopOf="@+id/toolsView"
app:layout_constraintStart_toStartOf="parent" />
<!-- <com.mogo.och.common.module.wigets.map.switchvisual.VisualViewDirver-->
<!-- android:id="@+id/vvd_change_angle"-->
<!-- android:layout_width="wrap_content"-->
<!-- android:layout_height="wrap_content"-->
<!-- android:layout_marginStart="@dimen/dp_618"-->
<!-- android:layout_marginBottom="@dimen/dp_48"-->
<!-- app:layout_constraintBottom_toTopOf="@+id/toolsView"-->
<!-- app:layout_constraintStart_toStartOf="parent" />-->
<com.mogo.och.common.module.wigets.map.orderstatus.OrderStatusView
@@ -377,20 +377,6 @@
<!-- app:layout_constraintStart_toStartOf="@+id/smallMapView" />-->
<!-- TODO:"挪到ExchangeChildLayout中去" -->
<!-- <com.mogo.eagle.core.function.hmi.ui.viewport.VisualAngleToggleView-->
<!-- android:id="@+id/visualAngleToggle"-->
<!-- android:layout_width="wrap_content"-->
<!-- android:layout_height="wrap_content"-->
<!-- app:layout_constraintEnd_toEndOf="parent"-->
<!-- app:layout_constraintBottom_toTopOf="@+id/smallMapView"-->
<!-- android:layout_marginEnd="@dimen/dp_50"-->
<!-- android:layout_marginBottom="@dimen/dp_30"/>-->
<!-- <com.mogo.eagle.core.function.hmi.ui.mofang.MoFangStatusView-->
<!-- android:layout_width="wrap_content"-->
<!-- android:layout_height="wrap_content"-->
<!-- app:layout_constraintTop_toTopOf="@+id/visualAngleToggle"-->
<!-- app:layout_constraintEnd_toStartOf="@+id/visualAngleToggle"/>-->
<com.mogo.och.common.module.wigets.LoadingMapStatusView
android:layout_width="match_parent"
@@ -411,13 +397,4 @@
android:elevation="100dp"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintTop_toTopOf="parent" />
<!-- 运营面板 -->
<ViewStub
android:id="@+id/vsOperateView"
android:layout_width="@dimen/dp_1000"
android:layout_height="match_parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
</androidx.constraintlayout.widget.ConstraintLayout>

View File

@@ -2,6 +2,7 @@ package com.mogo.och.unmanned.taxi.ui.base
import android.animation.ObjectAnimator
import android.annotation.SuppressLint
import android.content.Context
import android.content.Intent
import android.os.Bundle
import android.view.LayoutInflater
@@ -16,11 +17,13 @@ import com.mogo.commons.mvp.MvpFragment
import com.mogo.commons.mvp.Presenter
import com.mogo.eagle.core.function.api.autopilot.IMoGoAutopilotRecordListener
import com.mogo.eagle.core.function.api.autopilot.IMoGoAutopilotStatusListener
import com.mogo.eagle.core.function.api.och.toolkit.IToolKitItemClickListener
import com.mogo.eagle.core.function.call.autopilot.CallerAutoPilotControlManager
import com.mogo.eagle.core.function.call.autopilot.CallerAutoPilotStatusListenerManager.getState
import com.mogo.eagle.core.function.call.autopilot.CallerAutopilotRecordListenerManager
import com.mogo.eagle.core.function.call.devatools.CallerDevaToolsManager
import com.mogo.eagle.core.function.call.hmi.CallerHmiViewControlListenerManager
import com.mogo.eagle.core.function.call.och.CallerEagleBaseFunctionCall4OchManager
import com.mogo.eagle.core.function.hmi.ui.widget.ParallelDriveView
import com.mogo.eagle.core.utilcode.kotlin.onClick
import com.mogo.eagle.core.utilcode.mogo.view.OnPreventFastClickListener
@@ -29,6 +32,7 @@ import com.mogo.eagle.core.utilcode.util.UiThreadHandler
import com.mogo.map.listener.IMogoMapListener
import com.mogo.map.uicontroller.VisualAngleMode
import com.mogo.och.common.module.wigets.StartAutopilotAnimationView
import com.mogo.och.common.module.wigets.map.drawline.LineView
import com.mogo.och.common.module.wigets.map.overmapview.OverMapDialog
import com.mogo.och.unmanned.taxi.R
import com.mogo.och.unmanned.taxi.constant.TaxiUnmannedConst
@@ -36,6 +40,7 @@ import com.mogo.och.unmanned.taxi.constant.TaxiUnmannedConst.Companion.START_AUT
import com.mogo.och.unmanned.taxi.ui.debug.DebugView
import com.mogo.och.unmanned.taxi.ui.navi.amap.TaxiAmapNaviFragment
import com.mogo.och.unmanned.taxi.ui.navi.auto.TaxiRoutingNaviFragment
import com.mogo.och.unmanned.taxi.ui.operational.TaxiOperationalDialogFragment
import kotlinx.android.synthetic.main.unmanned_taxi_base_fragment.aciv_show_guid
import kotlinx.android.synthetic.main.unmanned_taxi_base_fragment.groupTestPanel
import kotlinx.android.synthetic.main.unmanned_taxi_base_fragment.mapBizView
@@ -50,6 +55,8 @@ import kotlinx.android.synthetic.main.unmanned_taxi_base_fragment.parallelDriveV
import kotlinx.android.synthetic.main.unmanned_taxi_base_fragment.smallMapView
import kotlinx.android.synthetic.main.unmanned_taxi_base_fragment.startAutopilotAnimationView
import kotlinx.android.synthetic.main.unmanned_taxi_base_fragment.taxi_close_navi_icon
import java.lang.ref.WeakReference
/**
* @author: wangmingjun
* @date: 2023/7/24
@@ -70,6 +77,12 @@ abstract class BaseTaxiTabFragment<V : IView, P : Presenter<V>> : MvpFragment<V,
private var overMapDialog: OverMapDialog? = null
private val runningTaskGateWay = "RUNNINGTASKGATEWAY"
private val lineView = "LINEVIEW"
private var personalDialogFragment: WeakReference<TaxiOperationalDialogFragment>? = null
override fun getLayoutId(): Int {
return R.layout.unmanned_taxi_base_fragment
}
@@ -184,6 +197,20 @@ abstract class BaseTaxiTabFragment<V : IView, P : Presenter<V>> : MvpFragment<V,
overMapDialog?.showDialog()
}
}
context?.let {
CallerEagleBaseFunctionCall4OchManager.addSingleToolKitDefaultItem(runningTaskGateWay,"运营面板", R.drawable.common_biz_operation,4);
CallerEagleBaseFunctionCall4OchManager.addToolKitDefaultItemClickListener(runningTaskGateWay,object :
IToolKitItemClickListener {
override fun onItemClick(toolTag: String, ctx: Context?) {
personalDialogFragment = WeakReference(TaxiOperationalDialogFragment())
activity?.supportFragmentManager?.let {
personalDialogFragment!!.get()
?.show(it, "service_data")
}
}
});
CallerEagleBaseFunctionCall4OchManager.addSingleToolKitCustomItem(lineView, LineView(it),10);
}
}
abstract fun stopAutoStartAutopilot()

View File

@@ -46,7 +46,7 @@ class TaxiFragment : BaseTaxiTabFragment<TaxiFragment, TaxiPresenter>(),
}
private var taskTabFragment: WeakReference<TaxiTaskTabFragment>? = null
private var personalDialogFragment: WeakReference<TaxiOperationalDialogFragment>? = null
private var routingVerifyFragment: WeakReference<TaxiRoutingFragment>? = null
private var moFanglistener: IMogoStatusChangedListener? = object :IMogoStatusChangedListener{
@@ -76,19 +76,11 @@ class TaxiFragment : BaseTaxiTabFragment<TaxiFragment, TaxiPresenter>(),
@Subscribe(threadMode = ThreadMode.MAIN)
fun openOperationalInfoView(eventLogout: EventLogout) {
// V6.2.0 增加订单统计功能
if (eventLogout.messgae == EventLogout.PERSONAL_TYPE) {
// 个人信息, 运营数据在无人化阶段暂时不展示
d(SceneConstant.M_TAXI + TAG, "openOperationalInfoView Event个人中心")
openOperationalInfoView()
}
}
private fun openOperationalInfoView() {
personalDialogFragment = WeakReference(TaxiOperationalDialogFragment())
activity?.supportFragmentManager?.let {
personalDialogFragment!!.get()
?.show(it, "service_data")
}
// if (eventLogout.messgae == EventLogout.PERSONAL_TYPE) {
//// 个人信息, 运营数据在无人化阶段暂时不展示
// d(SceneConstant.M_TAXI + TAG, "openOperationalInfoView Event个人中心")
// openOperationalInfoView()
// }
}
override fun getTagName(): String {

View File

@@ -15,8 +15,8 @@ import com.mogo.eagle.core.function.call.autopilot.CallerChassisLocationGCJ02Lis
import com.mogo.eagle.core.function.call.autopilot.CallerChassisStatesListenerManager
import com.mogo.eagle.core.function.main.MainLauncherActivity
import com.mogo.eagle.core.utilcode.util.ToastUtils
import com.zhjt.mogo.adas.data.bean.MogoReport
import com.zhjt.mogo.adas.data.bean.LaunchConditionData
import com.zhjt.mogo.adas.data.bean.MogoReport
import com.zhjt.mogo.adas.data.bean.UnableLaunchReason
import com.zhjt.mogo.adas.data.bean.UnableLaunchReason.SourceType.CHASSIS
import com.zhjt.mogo.adas.data.bean.UnableLaunchReason.UnableType.CHASSIS_BRAKE
@@ -154,7 +154,12 @@ class TestAutoPilotBeforeLaunch {
.setRemotePilotReady(false).build(),
FSMStatusReasonRespond.getDefaultInstance()
), ArrayList<UnableLaunchReason>().also {
it += UnableLaunchReason(CHASSIS, CHASSIS_GEAR, "gear")
it += UnableLaunchReason(CHASSIS, CHASSIS_GEAR,
object : ArrayList<String>() {
init {
add("gear")
}
})
})
}
@@ -169,7 +174,12 @@ class TestAutoPilotBeforeLaunch {
.setRemotePilotReady(false).build(),
FSMStatusReasonRespond.getDefaultInstance()
), ArrayList<UnableLaunchReason>().also {
it += UnableLaunchReason(CHASSIS, CHASSIS_STEERING, "steering")
it += UnableLaunchReason(CHASSIS, CHASSIS_STEERING,
object : ArrayList<String>() {
init {
add("steering")
}
})
})
}
@@ -185,7 +195,12 @@ class TestAutoPilotBeforeLaunch {
.setRemotePilotReady(false).build(),
FSMStatusReasonRespond.getDefaultInstance()
), ArrayList<UnableLaunchReason>().also {
it += UnableLaunchReason(CHASSIS, CHASSIS_BRAKE, "brake")
it += UnableLaunchReason(CHASSIS, CHASSIS_BRAKE,
object : ArrayList<String>() {
init {
add("brake")
}
})
})
}
@@ -200,7 +215,12 @@ class TestAutoPilotBeforeLaunch {
.setRemotePilotReady(false).build(),
FSMStatusReasonRespond.getDefaultInstance()
), ArrayList<UnableLaunchReason>().also {
it += UnableLaunchReason(CHASSIS, CHASSIS_HAZARD_LIGHTS, "lights")
it += UnableLaunchReason(CHASSIS, CHASSIS_HAZARD_LIGHTS,
object : ArrayList<String>() {
init {
add("lights")
}
})
})
}
@@ -215,7 +235,12 @@ class TestAutoPilotBeforeLaunch {
.setRemotePilotReady(false).build(),
FSMStatusReasonRespond.getDefaultInstance()
), ArrayList<UnableLaunchReason>().also {
it += UnableLaunchReason(CHASSIS, CHASSIS_THROTTLE, "throttle")
it += UnableLaunchReason(CHASSIS, CHASSIS_THROTTLE,
object : ArrayList<String>() {
init {
add("throttle")
}
})
})
}
@@ -230,11 +255,36 @@ class TestAutoPilotBeforeLaunch {
.setRemotePilotReady(false).build(),
FSMStatusReasonRespond.getDefaultInstance()
), ArrayList<UnableLaunchReason>().also {
it += UnableLaunchReason(CHASSIS, CHASSIS_GEAR, "gear")
it += UnableLaunchReason(CHASSIS, CHASSIS_STEERING, "steering")
it += UnableLaunchReason(CHASSIS, CHASSIS_HAZARD_LIGHTS, "lights")
it += UnableLaunchReason(CHASSIS, CHASSIS_THROTTLE, "throttle")
it += UnableLaunchReason(CHASSIS, CHASSIS_BRAKE, "brake")
it += UnableLaunchReason(CHASSIS, CHASSIS_GEAR,
object : ArrayList<String>() {
init {
add("gear")
}
})
it += UnableLaunchReason(CHASSIS, CHASSIS_STEERING,
object : ArrayList<String>() {
init {
add("steering")
}
})
it += UnableLaunchReason(CHASSIS, CHASSIS_HAZARD_LIGHTS,
object : ArrayList<String>() {
init {
add("lights")
}
})
it += UnableLaunchReason(CHASSIS, CHASSIS_THROTTLE,
object : ArrayList<String>() {
init {
add("throttle")
}
})
it += UnableLaunchReason(CHASSIS, CHASSIS_BRAKE,
object : ArrayList<String>() {
init {
add("brake")
}
})
})
}
CallerAutoPilotControlManager.isCanStartAutopilot(true)

View File

@@ -58,12 +58,12 @@ class V2NTest {
if (millis > 0) {
delay(millis)
}
FunctionBuildConfig.isNewV2NData = true
FunctionBuildConfig.v2nMainSwitch = true
FunctionBuildConfig.v2nNewLinked = true
FunctionBuildConfig.v2nTotalSwitch = true
runCatching {
val map = HashMap<String, Boolean>().also {
it["f1"] = FunctionBuildConfig.v2nMainSwitch
it["f2"] = FunctionBuildConfig.isNewV2NData
it["f1"] = FunctionBuildConfig.v2nTotalSwitch
it["f2"] = FunctionBuildConfig.v2nNewLinked
}
CallerTelematicManager.sendMsgToAllClients(TelematicConstant.V2N_NEW_LINK_SWITCH, GsonUtils.toJson(map).toByteArray())
}
@@ -99,12 +99,12 @@ class V2NTest {
if (millis > 0) {
delay(millis)
}
FunctionBuildConfig.isNewV2NData = true
FunctionBuildConfig.v2nMainSwitch = true
FunctionBuildConfig.v2nNewLinked = true
FunctionBuildConfig.v2nTotalSwitch = true
runCatching {
val map = HashMap<String, Boolean>().also {
it["f1"] = FunctionBuildConfig.v2nMainSwitch
it["f2"] = FunctionBuildConfig.isNewV2NData
it["f1"] = FunctionBuildConfig.v2nTotalSwitch
it["f2"] = FunctionBuildConfig.v2nNewLinked
}
CallerTelematicManager.sendMsgToAllClients(TelematicConstant.V2N_NEW_LINK_SWITCH, GsonUtils.toJson(map).toByteArray())
}
@@ -179,12 +179,12 @@ class V2NTest {
}
val newPoint = DrivingDirectionUtils.calculateNewPoint(car.longitude, car.latitude, car.heading , 200.0)
Log.d(TAG, "获取到路口数据..., 自车:[${car.longitude}, ${car.latitude}]前方200米外的点: [${newPoint.first}, ${newPoint.second}]")
FunctionBuildConfig.isNewV2NData = true
FunctionBuildConfig.v2nMainSwitch = true
FunctionBuildConfig.v2nNewLinked = true
FunctionBuildConfig.v2nTotalSwitch = true
runCatching {
val map = HashMap<String, Boolean>().also {
it["f1"] = FunctionBuildConfig.v2nMainSwitch
it["f2"] = FunctionBuildConfig.isNewV2NData
it["f1"] = FunctionBuildConfig.v2nTotalSwitch
it["f2"] = FunctionBuildConfig.v2nNewLinked
}
CallerTelematicManager.sendMsgToAllClients(TelematicConstant.V2N_NEW_LINK_SWITCH, GsonUtils.toJson(map).toByteArray())
}
@@ -211,12 +211,12 @@ class V2NTest {
if (millis > 0) {
delay(millis)
}
FunctionBuildConfig.isNewV2NData = true
FunctionBuildConfig.v2nMainSwitch = true
FunctionBuildConfig.v2nNewLinked = true
FunctionBuildConfig.v2nTotalSwitch = true
runCatching {
val map = HashMap<String, Boolean>().also {
it["f1"] = FunctionBuildConfig.v2nMainSwitch
it["f2"] = FunctionBuildConfig.isNewV2NData
it["f1"] = FunctionBuildConfig.v2nTotalSwitch
it["f2"] = FunctionBuildConfig.v2nNewLinked
}
CallerTelematicManager.sendMsgToAllClients(TelematicConstant.V2N_NEW_LINK_SWITCH, GsonUtils.toJson(map).toByteArray())
}
@@ -261,12 +261,12 @@ class V2NTest {
if (millis > 0) {
delay(millis)
}
FunctionBuildConfig.isNewV2NData = true
FunctionBuildConfig.v2nMainSwitch = true
FunctionBuildConfig.v2nNewLinked = true
FunctionBuildConfig.v2nTotalSwitch = true
runCatching {
val map = HashMap<String, Boolean>().also {
it["f1"] = FunctionBuildConfig.v2nMainSwitch
it["f2"] = FunctionBuildConfig.isNewV2NData
it["f1"] = FunctionBuildConfig.v2nTotalSwitch
it["f2"] = FunctionBuildConfig.v2nNewLinked
}
CallerTelematicManager.sendMsgToAllClients(TelematicConstant.V2N_NEW_LINK_SWITCH, GsonUtils.toJson(map).toByteArray())
}

View File

@@ -118,7 +118,7 @@ class FuncBizProvider : IMoGoFuncBizProvider {
}
override fun queryV2XEvents() {
if (V2NCarTypeCheck.verifyCarType() && (!FunctionBuildConfig.v2nMainSwitch || !FunctionBuildConfig.isNewV2NData)) {
if (V2NCarTypeCheck.verifyCarType() && (!FunctionBuildConfig.v2nTotalSwitch || !FunctionBuildConfig.v2nNewLinked)) {
v2xPoiLoader.queryWholeRoadEvents()
}
}

View File

@@ -107,7 +107,7 @@ object OverViewDataManager {
.observeOn(AndroidSchedulers.mainThread())
.subscribe {
it?.apply {
if (V2NCarTypeCheck.verifyCarType() && (!FunctionBuildConfig.v2nMainSwitch || !FunctionBuildConfig.isNewV2NData)) {
if (V2NCarTypeCheck.verifyCarType() && (!FunctionBuildConfig.v2nTotalSwitch || !FunctionBuildConfig.v2nNewLinked)) {
CallerFuncBizListenerManager.invokeV2XEvents(this)
}
}

View File

@@ -196,8 +196,8 @@ object V2XEventManager : IMoGoChassisLocationGCJ02Listener, IV2XCallback,
}
is V2XEvent.RoadEventX -> {
val flag = verifyCarType()
Log.d("$M_V2X$TAG", "---- 收到ai云V2N事件 ---:${flag}, ${FunctionBuildConfig.v2nMainSwitch}, ${FunctionBuildConfig.isNewV2NData}")
if (flag && (!FunctionBuildConfig.v2nMainSwitch || !FunctionBuildConfig.isNewV2NData)) {
Log.d("$M_V2X$TAG", "---- 收到ai云V2N事件 ---:${flag}, ${FunctionBuildConfig.v2nTotalSwitch}, ${FunctionBuildConfig.v2nNewLinked}")
if (flag && (!FunctionBuildConfig.v2nTotalSwitch || !FunctionBuildConfig.v2nNewLinked)) {
// try {
if (AppIdentityModeUtils.isDriver(FunctionBuildConfig.appIdentityMode)) {
Log.d("$M_V2X$TAG", "onAck -> 司机端: 将收到云端事件给到乘客端...")
@@ -210,7 +210,7 @@ object V2XEventManager : IMoGoChassisLocationGCJ02Listener, IV2XCallback,
// }
handleRoadMarkerEvent(event.data.toRoadMarker())
} else{
V2XBizTrace.onAck("事件未触发,被开关拦截",mapOf("roadEvent" to event, "v2nMainSwitch" to FunctionBuildConfig.v2nMainSwitch,"isNewV2NData" to FunctionBuildConfig.isNewV2NData), true)
V2XBizTrace.onAck("事件未触发,被开关拦截",mapOf("roadEvent" to event, "v2nMainSwitch" to FunctionBuildConfig.v2nTotalSwitch,"isNewV2NData" to FunctionBuildConfig.v2nNewLinked), true)
}
}
else -> {

View File

@@ -45,7 +45,6 @@ import com.mogo.eagle.function.biz.v2x.v2n.utils.EventDismissBean
import com.mogo.eagle.function.biz.v2x.v2n.utils.EventDismissManager
import com.mogo.eagle.function.biz.v2x.v2n.utils.IEventDismissListener
import com.mogo.eagle.function.biz.v2x.v2n.utils.V2XEventAnalyticsManager
import com.mogo.map.entities.Lane
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.asCoroutineDispatcher
import kotlinx.coroutines.delay
@@ -484,42 +483,42 @@ internal object V2NIdentifyDrawer: IEventDismissListener {
}
private fun drawShiGong(events: List<TrackedObject>) {
if (V2NCarTypeCheck.verifyCarType() && FunctionBuildConfig.v2nMainSwitch && FunctionBuildConfig.isNewV2NData) {
if (V2NCarTypeCheck.verifyCarType() && FunctionBuildConfig.v2nTotalSwitch && FunctionBuildConfig.v2nNewLinked) {
handler.removeMessages(MSG_WHAT_DRAW_SHIGONE)
handler.sendMessage(Message.obtain(handler, MSG_WHAT_DRAW_SHIGONE, events))
}
}
private fun drawShiGu(events: List<TrackedObject>) {
if (V2NCarTypeCheck.verifyCarType() && FunctionBuildConfig.v2nMainSwitch && FunctionBuildConfig.isNewV2NData) {
if (V2NCarTypeCheck.verifyCarType() && FunctionBuildConfig.v2nTotalSwitch && FunctionBuildConfig.v2nNewLinked) {
handler.removeMessages(MSG_WHAT_DRAW_SHIGU)
handler.sendMessage(Message.obtain(handler, MSG_WHAT_DRAW_SHIGU, events))
}
}
private fun drawYongDu(events: List<MogoV2X.RTEData_PB>) {
if (V2NCarTypeCheck.verifyCarType() && FunctionBuildConfig.v2nMainSwitch && FunctionBuildConfig.isNewV2NData) {
if (V2NCarTypeCheck.verifyCarType() && FunctionBuildConfig.v2nTotalSwitch && FunctionBuildConfig.v2nNewLinked) {
handler.removeMessages(MSG_WHAT_DRAW_YONGDU)
handler.sendMessage(Message.obtain(handler, MSG_WHAT_DRAW_YONGDU, events))
}
}
private fun drawOtherRetrogradeVehicle(event: MessagePad.Event) {
if (V2NCarTypeCheck.verifyCarType() && FunctionBuildConfig.v2nMainSwitch && FunctionBuildConfig.isNewV2NData) {
if (V2NCarTypeCheck.verifyCarType() && FunctionBuildConfig.v2nTotalSwitch && FunctionBuildConfig.v2nNewLinked) {
handler.removeMessages(MSG_WHAT_DRAW_OTHER_RETROGRADE_VEHICLE)
handler.sendMessage(Message.obtain(handler, MSG_WHAT_DRAW_OTHER_RETROGRADE_VEHICLE, event))
}
}
private fun drawGreenWave(crossSpeed: V2nCrossSpeed) {
if (V2NCarTypeCheck.verifyCarType() && FunctionBuildConfig.v2nMainSwitch && FunctionBuildConfig.isNewV2NData) {
if (V2NCarTypeCheck.verifyCarType() && FunctionBuildConfig.v2nTotalSwitch && FunctionBuildConfig.v2nNewLinked) {
handler.removeMessages(MSG_WHAT_DRAW_GREEN_WAVE)
handler.sendMessage(Message.obtain(handler, MSG_WHAT_DRAW_GREEN_WAVE, crossSpeed))
}
}
private fun drawPeopleCross(event: MessagePad.Event) {
if (V2NCarTypeCheck.verifyCarType() && FunctionBuildConfig.v2nMainSwitch && FunctionBuildConfig.isNewV2NData) {
if (V2NCarTypeCheck.verifyCarType() && FunctionBuildConfig.v2nTotalSwitch && FunctionBuildConfig.v2nNewLinked) {
handler.removeMessages(MSG_WHAT_DRAW_PEOPLE_CROSS)
handler.sendMessage(Message.obtain(handler, MSG_WHAT_DRAW_PEOPLE_CROSS, event))
}

View File

@@ -68,7 +68,6 @@ import com.zhidao.support.adas.high.common.Constants
import com.zhidao.support.adas.high.common.CupidLogUtils
import com.zhjt.mogo.adas.common.MessageType
import com.zhjt.mogo.adas.common.power.PowerUnitChannel
import com.zhjt.mogo.adas.data.Adas
import com.zhjt.mogo.adas.data.AdasConstants
import com.zhjt.mogo.adas.data.bean.MogoReport
import com.zhjt.mogo.adas.data.bean.NodeStateInfo
@@ -1166,8 +1165,8 @@ class MoGoAutopilotControlProvider :
CallerLogger.d("$M_D_C$TAG", status)
runCatching {
val map = HashMap<String, Boolean>().also {
it["f1"] = FunctionBuildConfig.v2nMainSwitch
it["f2"] = FunctionBuildConfig.isNewV2NData
it["f1"] = FunctionBuildConfig.v2nTotalSwitch
it["f2"] = FunctionBuildConfig.v2nNewLinked
}
CallerTelematicManager.sendMsgToAllClients(TelematicConstant.V2N_NEW_LINK_SWITCH, GsonUtils.toJson(map).toByteArray())
}

View File

@@ -149,8 +149,8 @@ class TeleMsgHandler : IMsgHandler {
val f1 = data["f1"] as Boolean
val f2 = data["f2"] as Boolean
Log.d(TAG, "乘客屏收到司机屏转发的新链路开关 --- 3 ---:$data, f1: $f1, f2:$f2")
FunctionBuildConfig.v2nMainSwitch = f1
FunctionBuildConfig.isNewV2NData = f2
FunctionBuildConfig.v2nTotalSwitch = f1
FunctionBuildConfig.v2nNewLinked = f2
} catch (t: Throwable) {
t.printStackTrace()
Log.e(TAG, "乘客屏收到司机屏转发的新链路开关异常", t)
@@ -270,11 +270,11 @@ class TeleMsgHandler : IMsgHandler {
TelematicConstant.OBU_RUNREDLIGHT_WARNING -> {
when (String(it.body)) {
"0" -> {
HmiBuildConfig.isShowRunRedLightView = false
HmiBuildConfig.v2iRedLightWarning = false
}
"1" -> {
HmiBuildConfig.isShowRunRedLightView = true
HmiBuildConfig.v2iRedLightWarning = true
}
}
}

View File

@@ -64,25 +64,25 @@ class MogoObuDcCombineManager private constructor() : IMoGoObuWarningRsiListener
}
override fun onMoGoObuRsiWarning(rsiWarningData: ObuScene.RsiWarningData) {
if (FunctionBuildConfig.v2xMainSwitch && HmiBuildConfig.isShowObuV2iView) {
if (FunctionBuildConfig.v2xTotalSwitch && HmiBuildConfig.v2iTotalSwitch) {
onMogoObuDcRsiWarning(rsiWarningData)
}
}
override fun onMoGoObuRsmWarning(rsmWarningData: ObuScene.RsmWarningData) {
if (FunctionBuildConfig.v2xMainSwitch && HmiBuildConfig.isShowObuV2iView) {
if (FunctionBuildConfig.v2xTotalSwitch && HmiBuildConfig.v2iTotalSwitch) {
onMogoObuDcRsmWarning(rsmWarningData)
}
}
override fun onMoGoObuSpatWarning(spatWarningData: ObuScene.SpatWarningData) {
if (FunctionBuildConfig.v2xMainSwitch && HmiBuildConfig.isShowObuV2iView) {
if (FunctionBuildConfig.v2xTotalSwitch && HmiBuildConfig.v2iTotalSwitch) {
onMogoObuDcSpatWarning(spatWarningData)
}
}
override fun onMoGoObuMapMath(mapMatchData: ObuScene.MapMatchData) {
if (FunctionBuildConfig.v2xMainSwitch && HmiBuildConfig.isShowObuV2iView) {
if (FunctionBuildConfig.v2xTotalSwitch && HmiBuildConfig.v2iTotalSwitch) {
onMogoObuMapMath(mapMatchData)
}
}
@@ -339,7 +339,7 @@ class MogoObuDcCombineManager private constructor() : IMoGoObuWarningRsiListener
* RSM预警信息 CvxPtcThreatIndInfo CvxPtcInfoIndInfo主车与弱势交通参与者之间的预警弱势交通参与者碰撞预警
*/
fun onMogoObuDcRsmWarning(rsmWarningData: ObuScene.RsmWarningData?) {
if (HmiBuildConfig.isShowObuWeaknessTrafficView) {
if (HmiBuildConfig.v2iWeaknessTraffic) {
CallerLogger.d(
"${M_OBU}${TAG}",
"MogoObuDcCombineManager onMogoObuRsmWarning ------> ${rsmWarningData.toString()}"
@@ -576,8 +576,8 @@ class MogoObuDcCombineManager private constructor() : IMoGoObuWarningRsiListener
}
1 -> { //闯红灯 V2I_RLVW_VIOLATION_TYPE_RUNNING_RED_LIGHT 一个红灯周期只显示一次
if(FunctionBuildConfig.v2xMainSwitch && HmiBuildConfig.isShowObuV2iView){
if (HmiBuildConfig.isShowRunRedLightView) {
if(FunctionBuildConfig.v2xTotalSwitch && HmiBuildConfig.v2iTotalSwitch){
if (HmiBuildConfig.v2iRedLightWarning) {
if (!isShowRunRedLight) {
isShowRunRedLight = true
ttsContent =
@@ -609,7 +609,7 @@ class MogoObuDcCombineManager private constructor() : IMoGoObuWarningRsiListener
}
2 -> { //绿波通行引导 V2I_RLVW_VIOLATION_TYPE_NO_VIOLATION 一个绿灯周期只显示一次
if (FunctionBuildConfig.v2xMainSwitch && FunctionBuildConfig.v2nMainSwitch && HmiBuildConfig.isShowGreenWaveView) {
if (FunctionBuildConfig.v2xTotalSwitch && FunctionBuildConfig.v2nTotalSwitch && HmiBuildConfig.isShowGreenWaveView) {
if (!isShowGreenWave) {
isShowGreenWave = true
CallerLogger.d(

View File

@@ -296,7 +296,7 @@ class MogoPrivateObuNewManager private constructor() : OnUpgradeListener {
* v2v预警信息 CvxRvInfoIndInfo CvxV2vThreatIndInfo 他车
*/
override fun onObuRvWarning(data: ObuScene.RvWarningData) {
if (FunctionBuildConfig.v2xMainSwitch && HmiBuildConfig.isShowObuV2vView) {
if (FunctionBuildConfig.v2xTotalSwitch && HmiBuildConfig.v2vTotalSwitch) {
if (data.warningMsg != null) {
// 更新数据远车数据之前要匹配uuid
data.vehBasicsMsg?.let {
@@ -343,7 +343,7 @@ class MogoPrivateObuNewManager private constructor() : OnUpgradeListener {
* 红绿灯预警信息 CvxIvpThreatIndInfo
*/
override fun onObuSpatWarning(data: ObuScene.SpatWarningData) {
if (FunctionBuildConfig.v2xMainSwitch && HmiBuildConfig.isShowObuV2iView) {
if (FunctionBuildConfig.v2xTotalSwitch && HmiBuildConfig.v2iTotalSwitch) {
handlerTrafficLight(
data.warningType,
data.status,
@@ -356,7 +356,7 @@ class MogoPrivateObuNewManager private constructor() : OnUpgradeListener {
* RSI预警信息 onMogoObuRsiWarning交通标志预警前方限速、前方学校等等交通事件预警前方拥堵、前方积水等等
*/
override fun onObuRsiWarning(data: ObuScene.RsiWarningData) {
if (FunctionBuildConfig.v2xMainSwitch && HmiBuildConfig.isShowObuV2iView) {
if (FunctionBuildConfig.v2xTotalSwitch && HmiBuildConfig.v2iTotalSwitch) {
if (data.warningMsgList != null && data.warningMsgList.size > 0) {
var alertContent = ""
var ttsContent = ""
@@ -643,8 +643,8 @@ class MogoPrivateObuNewManager private constructor() : OnUpgradeListener {
"$M_OBU${MogoObuConst.TAG_MOGO_NEW_OBU}",
"onMogoObuRsmWarning ------> ${data?.toString()}"
)
if (FunctionBuildConfig.v2xMainSwitch && HmiBuildConfig.isShowObuV2iView) {
if (HmiBuildConfig.isShowObuWeaknessTrafficView) {
if (FunctionBuildConfig.v2xTotalSwitch && HmiBuildConfig.v2iTotalSwitch) {
if (HmiBuildConfig.v2iWeaknessTraffic) {
// 交通参与者类型 0x0:未知 UNKNOWN | 1机动车 2:非机动车 NON_MOTOR | 3:行人 PEDESTRIAN 4:obu
if (data != null && data.participant != null) {
val v2xType = when (data.participant.ptcType) {
@@ -736,7 +736,7 @@ class MogoPrivateObuNewManager private constructor() : OnUpgradeListener {
* 地图匹配 是OBU算法输出地图匹配结果主车匹配道路哪条路或者哪条车道
*/
override fun onObuMapMath(data: ObuScene.MapMatchData?) {
if (FunctionBuildConfig.v2xMainSwitch && HmiBuildConfig.isShowObuV2iView) {
if (FunctionBuildConfig.v2xTotalSwitch && HmiBuildConfig.v2iTotalSwitch) {
if (data != null) {
CallerLogger.d(
"$M_OBU${MogoObuConst.TAG_MOGO_NEW_OBU}",
@@ -1056,8 +1056,8 @@ class MogoPrivateObuNewManager private constructor() : OnUpgradeListener {
}
1 -> {//闯红灯 V2I_RLVW_VIOLATION_TYPE_RUNNING_RED_LIGHT 一个红灯周期只显示一次
if(FunctionBuildConfig.v2xMainSwitch && HmiBuildConfig.isShowObuV2iView){
if (HmiBuildConfig.isShowRunRedLightView) {
if(FunctionBuildConfig.v2xTotalSwitch && HmiBuildConfig.v2iTotalSwitch){
if (HmiBuildConfig.v2iRedLightWarning) {
if (!isShowRunRedLight) {
isShowRunRedLight = true
ttsContent =

View File

@@ -34,7 +34,6 @@ import com.mogo.eagle.core.function.api.devatools.strict.IStrictModeProvider
import com.mogo.eagle.core.function.api.lookaround.IMoGoLookAroundProvider
import com.mogo.eagle.core.function.api.map.route.IMapRouteProvider
import com.mogo.eagle.core.function.api.upgrade.IMoGoUpgradeProvider
import com.mogo.eagle.core.function.call.devatools.CallerDevaToolsManager
import com.mogo.eagle.core.utilcode.kotlin.lifeCycleScope
import com.mogo.eagle.core.utilcode.mogo.AppIdentityModeUtils
import com.mogo.eagle.core.utilcode.mogo.logger.CallerLogger
@@ -84,10 +83,8 @@ import com.zhjt.mogo_core_function_devatools.weaknetwork.DetectResultImpl
import com.zhjt.mogo_core_function_devatools.weaknetwork.WeakNetworkStrategy
import com.zhjt.mogo_core_function_devatools.workorder.WorkOrderManager
import com.zhjt.service.chain.ChainLog
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.delay
import kotlinx.coroutines.launch
import java.io.File
import java.lang.ref.WeakReference
import java.util.concurrent.ConcurrentHashMap
@@ -410,8 +407,8 @@ class DevaToolsProvider : IDevaToolsProvider, IAppStateListener {
/**
* 展示考试车辆控制窗口
*/
override fun showExamControlWindow(view: View,isShow: Boolean) {
ExamControlManager.showExamControlWindow(view,isShow)
override fun showExamControlWindow(isShow: Boolean) {
ExamControlManager.showExamControlWindow(isShow)
}
override fun onReceiveBadCaseRecord(

View File

@@ -1,14 +1,10 @@
package com.zhjt.mogo_core_function_devatools.exam
import android.annotation.SuppressLint
import android.view.View
import androidx.fragment.app.FragmentActivity
import com.mogo.eagle.core.data.config.FunctionBuildConfig
import com.mogo.eagle.core.function.call.setting.CallerSopSettingManager
import com.mogo.eagle.core.utilcode.util.ClickUtils
import com.mogo.eagle.core.utilcode.util.NetworkUtils
import com.mogo.eagle.core.utilcode.util.ToastUtils
import com.zhjt.mogo_core_function_devatools.badcase.consts.BadCaseConfig
import com.mogo.eagle.core.utilcode.util.AppStateManager
/**
* 考试控制管理
@@ -21,9 +17,8 @@ internal object ExamControlManager {
/**
* 开启考试车辆控制窗口
*/
fun showExamControlWindow(view: View,isShow: Boolean){
val activity = view.context as? FragmentActivity
?: throw IllegalStateException("please ensure context is FragmentActivity.")
fun showExamControlWindow(isShow: Boolean){
val activity = AppStateManager.currentActivity() ?: return
if(examControlWindow == null){
examControlWindow = ExamControlWindow(activity)
}

View File

@@ -173,8 +173,8 @@ object StatusManager {
}, 500L)
}
private fun randomNoFSMChange(ctx: Context) {
val fsmStatus = FSMStatus(FSMStateCode.ExistNormal, "正常")
val noFsmStatus = FSMStatus(FSMStateCode.NotExist, "")
val fsmStatus = FSMStatus(FSMStateCode.ExistNormal, listOf("正常"))
val noFsmStatus = FSMStatus(FSMStateCode.NotExist, listOf(""))
ctx.lifeCycleScope.launch(dispatcher) {
model.update(if (hasFSM) fsmStatus else noFsmStatus)
@@ -182,8 +182,8 @@ object StatusManager {
}
private fun randomFSMStatus(ctx: Context) {
val fsmNormalStatus = FSMStatus(FSMStateCode.ExistNormal, "正常")
val fsmErrorStatus = FSMStatus(FSMStateCode.ExistError, "异常")
val fsmNormalStatus = FSMStatus(FSMStateCode.ExistNormal, listOf("正常"))
val fsmErrorStatus = FSMStatus(FSMStateCode.ExistError, listOf("异常"))
val fSMList = ArrayList<Status>()?.also {
it += fsmNormalStatus

View File

@@ -141,28 +141,31 @@ enum class FSMStateCode {
/**
* FSM模块状态
*/
class FSMStatus(var state: FSMStateCode, var desc: String = ""): Status(), IAutopilotPreLaunchStatus {
class FSMStatus(var state: FSMStateCode, var descList: List<String> = emptyList<String>()): Status(), IAutopilotPreLaunchStatus {
override fun equals(other: Any?): Boolean {
if (javaClass != other?.javaClass) return false
other as FSMStatus
if (desc != other.desc) {
if (state != other.state) {
return false
}
if (state != other.state) {
if (descList.size != other.descList.size) {
return false
}
if (descList != other.descList) {
return false
}
return true
}
override fun hashCode(): Int {
var result = desc.hashCode()
var result = descList.hashCode()
result = 31 * result + state.hashCode()
return result
}
override fun toString(): String {
return "FSMStatus(state=$state, desc='$desc', raw_data=$rawData)"
return "FSMStatus(state=$state, descList='$descList', raw_data=$rawData)"
}
override fun isException(): Boolean = state == FSMStateCode.ExistError

View File

@@ -34,9 +34,9 @@ internal class FSMImpl(ctx: Context) : IFlow<FSMStatus>(ctx), IMoGoAutopilotStat
AtomicReference<Fsm2024.FSMStateMsg>(null)
}
private fun getDesc(): String {
private fun getDesc(): List<String> {
if (!CallerAutoPilotStatusListenerManager.isConnect()) {
return "未知"
return listOf("未知")
} else {
val nodeState = CallerAutoPilotControlManager.getNodeStateInfo(AdasConstants.NodeName.FSM2024)?.nodeState ?: AdasConstants.NodeState.NODE_UNKNOWN
return getStateDescByNodeStateInfo(nodeState)
@@ -61,12 +61,12 @@ internal class FSMImpl(ctx: Context) : IFlow<FSMStatus>(ctx), IMoGoAutopilotStat
}
}
private fun getStateDescByNodeStateInfo(nodeState: AdasConstants.NodeState): String {
private fun getStateDescByNodeStateInfo(nodeState: AdasConstants.NodeState): List<String> {
return when(nodeState) {
AdasConstants.NodeState.NODE_UNKNOWN -> "未知"
AdasConstants.NodeState.NODE_NOT_EXIST -> "FSM不存在"
AdasConstants.NodeState.NODE_EXIST -> if(fsmStateMsg.get()?.pilotStandbyFlag == true) "状态正常" else fsmStateMsg.get()?.pilotNotStandbyReason ?: ""
else -> "未知"
AdasConstants.NodeState.NODE_UNKNOWN -> listOf("未知")
AdasConstants.NodeState.NODE_NOT_EXIST -> listOf("FSM不存在")
AdasConstants.NodeState.NODE_EXIST -> if(fsmStateMsg.get()?.pilotStandbyFlag == true) listOf("状态正常") else fsmStateMsg.get()?.repeatedPilotNotStandbyReasonList ?: listOf("")
else -> listOf("未知")
}
}
@@ -92,7 +92,7 @@ internal class FSMImpl(ctx: Context) : IFlow<FSMStatus>(ctx), IMoGoAutopilotStat
} else {
CallerLogger.d("$M_DEVA$TAG", "工控机断开了....")
fsmStateMsg.set(null)
send(FSMStatus(FSMStateCode.UnKnown, "工控机断开了"))
send(FSMStatus(FSMStateCode.UnKnown, listOf("工控机断开了")))
}
}
@@ -122,9 +122,9 @@ internal class FSMImpl(ctx: Context) : IFlow<FSMStatus>(ctx), IMoGoAutopilotStat
)
fsmStateMsg.set(fsmState)
if (fsmState.pilotStandbyFlag) {
send(FSMStatus(FSMStateCode.ExistNormal, "状态正常"))
send(FSMStatus(FSMStateCode.ExistNormal, listOf("状态正常")))
} else {
send(FSMStatus(FSMStateCode.ExistError, fsmState.pilotNotStandbyReason))
send(FSMStatus(FSMStateCode.ExistError, fsmState.repeatedPilotNotStandbyReasonList))
}
}

View File

@@ -14,7 +14,7 @@ internal class StatusModel : ViewModel() {
const val TAG = "StatusModel"
val DEFAULTS = Pair(null, ArrayList<Status>().also {
it += OverViewStatus()
it += FSMStatus(FSMStateCode.UnKnown, "")
it += FSMStatus(FSMStateCode.UnKnown, listOf(""))
it += RTKStatus("", -1)
it += IpcStatus(CallerAutoPilotStatusListenerManager.isConnect())
it += CanStatus(false)

View File

@@ -141,9 +141,7 @@ internal class StatusAdapter(val ctx: Context, var data: List<Status>) : Recycle
FSMStateCode.ExistError -> {
iv.background = ContextCompat.getDrawable(itemView.context, drawable.icon_dev_status_fsm_error)
CallerHmiManager.showFSMExceptionStatusWindow(ArrayList<String>().also {
it += status.desc
})
CallerHmiManager.showFSMExceptionStatusWindow(status.descList)
}
}
}

View File

@@ -131,8 +131,8 @@ class TakeOverReasonWindow constructor(activity: Activity) : View.OnTouchListene
it.format = PixelFormat.RGBA_8888
it.flags = WindowManager.LayoutParams.FLAG_NOT_TOUCH_MODAL
it.gravity = Gravity.START or Gravity.TOP
it.width = 844
it.height = 846
it.width = 902
it.height = 1530
it.alpha = 1.0f
}
}
@@ -445,8 +445,8 @@ class TakeOverReasonWindow constructor(activity: Activity) : View.OnTouchListene
val metrics = DisplayMetrics()
// 默认固定位置,靠屏幕右边缘的中间
mWindowManager!!.defaultDisplay.getMetrics(metrics)
mWindowParams!!.x = metrics.widthPixels-890
mWindowParams!!.y = metrics.heightPixels - BarUtils.getStatusBarHeight()-1140
mWindowParams!!.x = metrics.widthPixels-1560
mWindowParams!!.y = metrics.heightPixels - BarUtils.getStatusBarHeight()
mWindowManager!!.addView(mFloatLayout, mWindowParams)
}
mTakeOverRecordInfo = takeOverRecordInfo

View File

@@ -44,7 +44,7 @@ class WorkOrderManager{
})
context.enqueuePop(
takeOverRecordView,
AutoSizeUtils.dp2px(context, 960f),
AutoSizeUtils.dp2px(context, 1046f),
WindowManager.LayoutParams.MATCH_PARENT,
key = "BadCaseManagerView"
).also {

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.6 KiB

After

Width:  |  Height:  |  Size: 2.6 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.4 KiB

View File

@@ -5,11 +5,11 @@
>
<!--内部填充-->
<solid android:color="#1AA7B6F0" />
<solid android:color="#19C1C1C1" />
<stroke
android:width="@dimen/dp_1"
android:color="#A7B6F0"
android:color="#A3A3A3"
/>
<corners android:radius="@dimen/dp_8"/>

Binary file not shown.

After

Width:  |  Height:  |  Size: 66 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 8.6 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 108 KiB

After

Width:  |  Height:  |  Size: 176 KiB

View File

@@ -0,0 +1,8 @@
<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android">
<gradient
android:startColor="#E5333333"
android:endColor="#E5333333"
/>
<corners android:radius="@dimen/dp_10" />
</shape>

View File

@@ -0,0 +1,9 @@
<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android">
<gradient
android:startColor="#19FFCB"
android:endColor="#1970FF"
android:angle="315"
/>
<corners android:radius="@dimen/dp_10" />
</shape>

Binary file not shown.

Before

Width:  |  Height:  |  Size: 29 KiB

After

Width:  |  Height:  |  Size: 1.4 MiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 44 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.1 KiB

After

Width:  |  Height:  |  Size: 1.3 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.2 KiB

After

Width:  |  Height:  |  Size: 1.7 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 3.3 KiB

After

Width:  |  Height:  |  Size: 2.2 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 13 KiB

After

Width:  |  Height:  |  Size: 4.2 KiB

View File

@@ -1,5 +1,10 @@
<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android">
<solid android:color="#0056FF"/>
<corners android:radius="@dimen/dp_8"/>
<shape xmlns:android="http://schemas.android.com/apk/res/android" android:shape="rectangle">
<gradient
android:startColor="#22C9F8"
android:endColor="#3E6DFC"
android:angle="270"
/>
<corners
android:radius="@dimen/dp_0"/>
</shape>

View File

@@ -5,13 +5,8 @@
>
<!--内部填充-->
<solid android:color="#1AA7B6F0" />
<solid android:color="#4D4D4D" />
<stroke
android:width="@dimen/dp_1"
android:color="#A7B6F0"
/>
<corners android:radius="@dimen/dp_8"/>
<corners android:radius="@dimen/dp_10"/>
</shape>

View File

@@ -6,11 +6,12 @@
<CheckBox
android:id="@+id/cbRecordSelect"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_width="@dimen/dp_40"
android:layout_height="@dimen/dp_40"
android:button="@drawable/record_radio_button_style"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintStart_toStartOf="parent"
android:layout_marginTop="@dimen/dp_35"
android:paddingTop="@dimen/dp_30"
android:paddingBottom="@dimen/dp_30"
android:paddingEnd="@dimen/dp_10"
@@ -28,6 +29,7 @@
android:src="@drawable/icon_record_cannot_check"
android:contentDescription="@string/take_over_record_cannot_check"
android:visibility="gone"
android:layout_marginTop="@dimen/dp_5"
/>
<TextView
@@ -38,15 +40,17 @@
app:layout_constraintBottom_toBottomOf="@id/cbRecordSelect"
app:layout_constraintLeft_toRightOf="@id/cbRecordSelect"
android:textSize="@dimen/sp_38"
android:textColor="#8E9DD4"
android:textColor="@color/white"
android:layout_marginStart="@dimen/dp_20"
android:layout_marginTop="@dimen/dp_m_4"
/>
<ImageView
android:id="@+id/ivRecordStatusLabel"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
app:layout_constraintTop_toTopOf="@id/cbRecordSelect"
app:layout_constraintBottom_toBottomOf="@id/cbRecordSelect"
app:layout_constraintTop_toTopOf="@id/tvFaultStartTime"
app:layout_constraintBottom_toBottomOf="@id/tvFaultStartTime"
app:layout_constraintRight_toRightOf="parent"
android:src="@drawable/icon_record_edit"
android:contentDescription="@string/take_over_record_status_label"
@@ -58,10 +62,10 @@
android:layout_height="wrap_content"
app:layout_constraintLeft_toRightOf="@id/tvFaultStartTime"
app:layout_constraintRight_toLeftOf="@id/ivRecordStatusLabel"
app:layout_constraintTop_toTopOf="@id/cbRecordSelect"
app:layout_constraintBottom_toBottomOf="@id/cbRecordSelect"
app:layout_constraintTop_toTopOf="@id/tvFaultStartTime"
app:layout_constraintBottom_toBottomOf="@id/tvFaultStartTime"
android:textSize="@dimen/sp_38"
android:textColor="#8E9DD4"
android:textColor="@color/white"
android:maxLines="1"
android:ellipsize="end"
android:layout_marginStart="@dimen/dp_20"
@@ -74,7 +78,7 @@
app:layout_constraintLeft_toLeftOf="@id/tvFaultStartTime"
app:layout_constraintRight_toRightOf="@id/ivRecordStatusLabel"
app:layout_constraintTop_toBottomOf="@id/tvFaultStartTime"
android:layout_marginTop="@dimen/dp_27"
android:layout_marginTop="@dimen/dp_28"
android:textSize="@dimen/sp_30"
android:textColor="#D4D4D4"
android:maxLines="2"

View File

@@ -1,30 +1,22 @@
<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="@dimen/dp_844"
android:layout_height="@dimen/dp_846"
android:layout_width="@dimen/dp_931"
android:layout_height="@dimen/dp_1528"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:background="@drawable/bg_take_over_reason">
<View
android:id="@+id/viewTitleBg"
android:layout_width="match_parent"
android:layout_height="@dimen/dp_102"
android:background="@drawable/icon_work_order_title"
app:layout_constraintTop_toTopOf="parent"
/>
<TextView
android:id="@+id/tvTakeOverTitle"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/take_over_reason"
android:textSize="@dimen/sp_34"
android:textSize="@dimen/sp_45"
android:textColor="@color/white"
android:textStyle="bold"
app:layout_constraintTop_toTopOf="@id/viewTitleBg"
app:layout_constraintBottom_toBottomOf="@id/viewTitleBg"
app:layout_constraintStart_toStartOf="@id/viewTitleBg"
android:layout_marginStart="@dimen/dp_32"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintLeft_toLeftOf="parent"
android:layout_marginStart="@dimen/dp_60"
android:layout_marginTop="@dimen/dp_100"
/>
<TextView
@@ -33,22 +25,11 @@
android:layout_height="wrap_content"
android:text="@string/take_over_time"
android:textColor="@color/white"
android:textSize="@dimen/sp_30"
app:layout_constraintTop_toTopOf="@id/viewTitleBg"
app:layout_constraintBottom_toBottomOf="@id/viewTitleBg"
app:layout_constraintEnd_toEndOf="@id/viewTitleBg"
android:layout_marginEnd="@dimen/dp_30"
/>
<View
android:id="@+id/viewTakeOverTypeLabel"
android:layout_width="@dimen/dp_6"
android:layout_height="@dimen/dp_29"
android:background="#FF0176FF"
app:layout_constraintTop_toBottomOf="@id/viewTitleBg"
app:layout_constraintStart_toStartOf="parent"
android:layout_marginStart="@dimen/dp_32"
android:layout_marginTop="@dimen/dp_48"
android:textSize="@dimen/sp_32"
app:layout_constraintTop_toTopOf="@id/tvTakeOverTitle"
app:layout_constraintBottom_toBottomOf="@id/tvTakeOverTitle"
app:layout_constraintRight_toRightOf="parent"
android:layout_marginEnd="@dimen/dp_62"
/>
<TextView
@@ -56,23 +37,21 @@
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/take_over_type"
android:textSize="@dimen/sp_32"
android:textSize="@dimen/sp_38"
android:textColor="@color/white"
android:textStyle="bold"
app:layout_constraintTop_toTopOf="@id/viewTakeOverTypeLabel"
app:layout_constraintBottom_toBottomOf="@id/viewTakeOverTypeLabel"
app:layout_constraintLeft_toRightOf="@id/viewTakeOverTypeLabel"
android:layout_marginStart="@dimen/dp_14"
app:layout_constraintTop_toBottomOf="@id/tvTakeOverTitle"
app:layout_constraintLeft_toLeftOf="@id/tvTakeOverTitle"
android:layout_marginTop="@dimen/dp_65"
/>
<androidx.appcompat.widget.AppCompatTextView
android:id="@+id/tvTakeOverType"
android:layout_width="@dimen/dp_781"
android:layout_height="@dimen/dp_70"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintTop_toTopOf="parent"
android:layout_marginTop="@dimen/dp_203"
app:layout_constraintTop_toBottomOf="@id/tvTypeTitle"
app:layout_constraintLeft_toLeftOf="@id/tvTypeTitle"
android:layout_marginTop="@dimen/dp_12"
android:background="@drawable/bg_fault_type"
android:elevation="@dimen/dp_10"
android:textSize="@dimen/sp_30"
@@ -83,29 +62,17 @@
app:drawableEndCompat="@drawable/icon_fault_expand"
/>
<View
android:id="@+id/viewTakeOverReasonLabel"
android:layout_width="@dimen/dp_6"
android:layout_height="@dimen/dp_29"
android:background="#FF0176FF"
app:layout_constraintTop_toBottomOf="@id/tvTakeOverType"
app:layout_constraintStart_toStartOf="parent"
android:layout_marginStart="@dimen/dp_32"
android:layout_marginTop="@dimen/dp_48"
/>
<TextView
android:id="@+id/tvTakeOverReasonTitle"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/take_over_reason"
android:textSize="@dimen/sp_32"
android:textSize="@dimen/sp_38"
android:textColor="@color/white"
android:textStyle="bold"
app:layout_constraintTop_toTopOf="@id/viewTakeOverReasonLabel"
app:layout_constraintBottom_toBottomOf="@id/viewTakeOverReasonLabel"
app:layout_constraintLeft_toRightOf="@id/viewTakeOverReasonLabel"
android:layout_marginStart="@dimen/dp_14"
app:layout_constraintTop_toBottomOf="@id/tvTakeOverType"
app:layout_constraintLeft_toLeftOf="@id/tvTakeOverType"
android:layout_marginTop="@dimen/dp_36"
/>
@@ -114,10 +81,9 @@
android:layout_width="@dimen/dp_781"
android:layout_height="@dimen/dp_70"
android:background="@drawable/bg_fault_type"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintTop_toTopOf="parent"
android:layout_marginTop="@dimen/dp_374"
app:layout_constraintTop_toBottomOf="@id/tvTakeOverReasonTitle"
app:layout_constraintLeft_toLeftOf="@id/tvTakeOverReasonTitle"
android:layout_marginTop="@dimen/dp_12"
android:paddingStart="@dimen/dp_21"
android:paddingEnd="@dimen/dp_21"
app:drawableEndCompat="@drawable/icon_fault_expand"
@@ -126,30 +92,17 @@
android:gravity="center_vertical"
/>
<View
android:id="@+id/viewTakeOverNoteLabel"
android:layout_width="@dimen/dp_6"
android:layout_height="@dimen/dp_29"
android:background="#FF0176FF"
app:layout_constraintTop_toBottomOf="@id/tvTakeOverReason"
app:layout_constraintStart_toStartOf="parent"
android:layout_marginStart="@dimen/dp_32"
android:layout_marginTop="@dimen/dp_47"
/>
<TextView
android:id="@+id/tvTakeOverNoteTitle"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/fault_note"
android:textSize="@dimen/sp_32"
android:textSize="@dimen/sp_38"
android:textColor="@color/white"
android:textStyle="bold"
app:layout_constraintTop_toTopOf="@id/viewTakeOverNoteLabel"
app:layout_constraintBottom_toBottomOf="@id/viewTakeOverNoteLabel"
app:layout_constraintLeft_toRightOf="@id/viewTakeOverNoteLabel"
android:layout_marginStart="@dimen/dp_14"
app:layout_constraintTop_toBottomOf="@id/tvTakeOverReason"
app:layout_constraintLeft_toLeftOf="@id/tvTakeOverReason"
android:layout_marginTop="@dimen/dp_36"
/>
<TextView
@@ -161,16 +114,15 @@
app:layout_constraintLeft_toRightOf="@id/tvTakeOverNoteTitle"
android:text="@string/fault_note_supplement"
android:textSize="@dimen/sp_30"
android:textColor="#A3ABC0"
android:textColor="#CCCCCC"
/>
<androidx.appcompat.widget.AppCompatEditText
android:id="@+id/etNoteInput"
android:layout_width="@dimen/dp_779"
android:layout_height="@dimen/dp_115"
app:layout_constraintTop_toBottomOf="@id/viewTakeOverNoteLabel"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintTop_toBottomOf="@id/tvTakeOverNoteTitle"
app:layout_constraintLeft_toLeftOf="@id/tvTakeOverNoteTitle"
android:hint="@string/take_over_note_input"
android:textColorHint="#A3ABC0"
android:textCursorDrawable="@drawable/work_order_input_cursor"
@@ -200,16 +152,15 @@
android:id="@+id/tvTakeOverSave"
android:layout_width="@dimen/dp_380"
android:layout_height="@dimen/dp_80"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintBottom_toBottomOf="parent"
android:background="@drawable/report_button_bg"
app:layout_constraintLeft_toLeftOf="@id/etNoteInput"
android:background="@drawable/bg_take_over_reason_save"
android:text="@string/take_over_save"
android:textColor="#FFFFFF"
android:textSize="@dimen/sp_27"
android:textSize="@dimen/sp_36"
android:textStyle="bold"
android:gravity="center"
android:layout_marginBottom="@dimen/dp_40"
android:layout_marginLeft="@dimen/dp_33"
android:layout_marginBottom="@dimen/dp_75"
/>
<TextView
@@ -217,15 +168,14 @@
android:layout_width="@dimen/dp_380"
android:layout_height="@dimen/dp_80"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintRight_toRightOf="@id/etNoteInput"
android:text="@string/take_over_cancel"
android:textColor="#FFFFFF"
android:textSize="@dimen/sp_27"
android:textSize="@dimen/sp_36"
android:textStyle="bold"
android:gravity="center"
android:background="@drawable/icon_cancel_bg"
android:layout_marginBottom="@dimen/dp_40"
android:layout_marginRight="@dimen/dp_33"
android:background="@drawable/bg_take_over_reason_cancel"
android:layout_marginBottom="@dimen/dp_75"
/>
<androidx.recyclerview.widget.RecyclerView
@@ -235,7 +185,7 @@
app:layout_constraintLeft_toLeftOf="@id/tvTakeOverType"
app:layout_constraintRight_toRightOf="@id/tvTakeOverType"
app:layout_constraintTop_toBottomOf="@id/tvTakeOverType"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintBottom_toTopOf="@id/tvTakeOverSave"
android:layout_marginBottom="@dimen/dp_39"
android:background="@drawable/bg_reason_list"
android:visibility="gone"

View File

@@ -1,6 +1,6 @@
<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="@dimen/dp_960"
android:layout_width="@dimen/dp_1046"
android:layout_height="match_parent"
android:layout_marginTop="@dimen/dp_72"
xmlns:app="http://schemas.android.com/apk/res-auto"
@@ -8,11 +8,11 @@
<View
android:id="@+id/viewTakeOverRecordLine"
android:layout_width="@dimen/dp_14"
android:layout_height="@dimen/dp_50"
android:layout_width="@dimen/dp_24"
android:layout_height="@dimen/dp_60"
android:layout_marginStart="@dimen/dp_80"
android:layout_marginTop="@dimen/dp_92"
android:background="#2966EC"
android:background="@drawable/icon_take_over_label"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
@@ -24,30 +24,31 @@
android:textColor="#FFFFFFFF"
android:textSize="@dimen/sp_42"
app:layout_constraintTop_toTopOf="@id/viewTakeOverRecordLine"
app:layout_constraintBottom_toBottomOf="@id/viewTakeOverRecordLine"
app:layout_constraintLeft_toLeftOf="@id/viewTakeOverRecordLine"
android:layout_marginStart="50dp"
app:layout_constraintLeft_toRightOf="@id/viewTakeOverRecordLine"
android:layout_marginStart="@dimen/dp_19"
android:layout_marginTop="@dimen/dp_m_2"
/>
<ImageView
android:id="@+id/ivTakeOverRecordClose"
android:layout_width="@dimen/dp_107"
android:layout_height="@dimen/dp_107"
android:layout_marginEnd="@dimen/dp_40"
android:src="@drawable/icon_close_nor"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintTop_toTopOf="@id/viewTakeOverRecordLine"
app:layout_constraintBottom_toBottomOf="@id/viewTakeOverRecordLine"
android:layout_width="@dimen/dp_44"
android:layout_height="@dimen/dp_45"
android:background="@drawable/icon_close_take_over"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="@id/tvTakeOverRecordTitle"
app:layout_constraintBottom_toBottomOf="@id/tvTakeOverRecordTitle"
android:contentDescription="@string/take_over_record_close"
android:layout_marginStart="@dimen/dp_896"
/>
<TextView
android:id="@+id/tvTakeOverRecordDate"
android:layout_width="match_parent"
android:layout_width="@dimen/dp_880"
android:layout_height="@dimen/dp_61"
app:layout_constraintTop_toTopOf="parent"
android:layout_marginTop="@dimen/dp_223"
android:background="#203076"
app:layout_constraintTop_toBottomOf="@id/viewTakeOverRecordLine"
app:layout_constraintLeft_toLeftOf="@id/viewTakeOverRecordLine"
android:layout_marginTop="@dimen/dp_35"
android:background="#7F000000"
android:textSize="@dimen/sp_32"
android:textColor="@color/white"
android:gravity="center"
@@ -63,34 +64,51 @@
app:layout_constraintBottom_toBottomOf="parent"
/>
<TextView
android:id="@+id/tvUpload"
android:layout_width="@dimen/dp_330"
android:layout_height="@dimen/dp_120"
<androidx.appcompat.widget.AppCompatTextView
android:id="@+id/tvRecordNoData"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintLeft_toLeftOf="parent"
android:layout_marginStart="@dimen/dp_401"
android:layout_marginTop="@dimen/dp_606"
app:drawableTopCompat="@drawable/icon_record_no_data"
android:text="@string/take_over_record_no_data"
android:drawablePadding="@dimen/dp_31"
android:textColor="#B2FFFFFF"
android:textSize="@dimen/sp_40"
android:gravity="center_horizontal"
/>
<View
android:id="@+id/viewTakeOverBottom"
android:layout_width="@dimen/dp_1000"
android:layout_height="@dimen/dp_364"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintBottom_toBottomOf="parent"
android:layout_marginBottom="@dimen/dp_74"
android:layout_marginLeft="@dimen/dp_85"
android:background="@drawable/upload_cloud_button_bg"
android:text="@string/take_over_record_upload"
android:textColor="#FFFFFFFF"
android:textSize="@dimen/sp_42"
android:gravity="center"
android:background="@drawable/bg_take_over_bottom"
/>
<TextView
android:id="@+id/tvUpload"
android:layout_width="@dimen/dp_421"
android:layout_height="@dimen/dp_126"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintBottom_toBottomOf="parent"
android:layout_marginBottom="@dimen/dp_75"
android:layout_marginLeft="@dimen/dp_60"
android:background="@drawable/bg_take_over_upload"
/>
<TextView
android:id="@+id/tvDeleteSelect"
android:layout_width="@dimen/dp_330"
android:layout_height="@dimen/dp_120"
android:layout_width="@dimen/dp_441"
android:layout_height="@dimen/dp_146"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintBottom_toBottomOf="parent"
android:layout_marginBottom="@dimen/dp_74"
android:layout_marginBottom="@dimen/dp_55"
android:layout_marginRight="@dimen/dp_85"
android:background="@drawable/delete_button_bg"
android:text="@string/take_over_record_delete"
android:textColor="#FFFFFFFF"
android:textSize="@dimen/sp_42"
android:gravity="center"
android:background="@drawable/bg_take_over_delete"
/>
<androidx.constraintlayout.widget.Group
@@ -98,25 +116,9 @@
android:layout_width="wrap_content"
android:layout_height="wrap_content"
app:constraint_referenced_ids="tvTakeOverRecordDate,
rvTakeOverList,tvUpload,tvDeleteSelect"
rvTakeOverList,tvUpload,tvDeleteSelect,viewTakeOverBottom"
android:visibility="gone"
/>
<androidx.appcompat.widget.AppCompatTextView
android:id="@+id/tvRecordNoData"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent"
android:layout_marginTop="@dimen/dp_652"
app:drawableTopCompat="@drawable/icon_record_no_data"
android:text="@string/take_over_record_no_data"
android:drawablePadding="@dimen/dp_33"
android:textColor="#CAD6FF"
android:textSize="@dimen/sp_34"
android:gravity="center_horizontal"
/>
</androidx.constraintlayout.widget.ConstraintLayout>

View File

@@ -4,7 +4,7 @@
<string name="work_order_report_title">问题上报</string>
<string name="work_order_type">问题类型</string>
<string name="work_order_occurrence_time">发生时间</string>
<string name="work_order_describe">问题描述</string>
<string name="work_order_describe">补充描述</string>
<string name="work_order_describe_input">手动输入</string>
<string name="work_order_report">上报</string>
<string name="work_order_cancel">取消</string>
@@ -64,7 +64,7 @@
<string name="fault_report">上报</string>
<string name="take_over_save">保存</string>
<string name="take_over_cancel">取消</string>
<string name="take_over_record_no_data">暂无接管记录</string>
<string name="take_over_record_no_data">暂无内容</string>
<string name="take_over_record_cannot_check">不能选则</string>
</resources>

View File

@@ -23,7 +23,6 @@
<item name="android:textSize">@dimen/sp_30</item>
<item name="android:background">@drawable/work_order_type_radio_button</item>
<item name="android:layout_weight">1</item>
<item name="android:layout_margin">@dimen/dp_8</item>
</style>

View File

@@ -79,6 +79,7 @@ dependencies {
implementation rootProject.ext.dependencies.koomxhook
implementation rootProject.ext.dependencies.preference
implementation rootProject.ext.dependencies.preference_ktx
implementation rootProject.ext.dependencies.amapsearch
implementation rootProject.ext.dependencies.thread_opt
api project(':test:crashreport-apmbyte')

View File

@@ -8,16 +8,20 @@ import com.mogo.eagle.core.data.enums.Carmodel
import com.mogo.eagle.core.function.api.datacenter.msgbox.IMsgBoxEventListener
import com.mogo.eagle.core.function.call.msgbox.CallerMsgBoxEventListenerManager
import com.mogo.eagle.core.function.hmi.R
import com.mogo.eagle.core.function.hmi.bone.tab.ReportTypeView
import com.mogo.eagle.core.utilcode.mogo.logger.CallerLogger
import com.mogo.eagle.core.utilcode.mogo.logger.scene.SceneConstant.Companion.M_HMI
import com.mogo.eagle.core.utilcode.util.UiThreadHandler
import kotlinx.android.synthetic.main.view_bone_tab.view.carInfoTabView
import kotlinx.android.synthetic.main.view_bone_tab.view.faultReasonView
import kotlinx.android.synthetic.main.view_bone_tab.view.msgBoxTabView
import kotlinx.android.synthetic.main.view_bone_tab.view.reportTypeView
import kotlinx.android.synthetic.main.view_bone_tab.view.tabSwitchCarInfo
import kotlinx.android.synthetic.main.view_bone_tab.view.tabSwitchMore
import kotlinx.android.synthetic.main.view_bone_tab.view.tabSwitchMsgBox
import kotlinx.android.synthetic.main.view_bone_tab.view.tabSwitchReport
import kotlinx.android.synthetic.main.view_bone_tab.view.toolKitTabView
import kotlinx.android.synthetic.main.view_bone_tab.view.workOrderView
import kotlin.properties.Delegates
class BoneTabLayout @JvmOverloads constructor(
@@ -83,6 +87,15 @@ class BoneTabLayout @JvmOverloads constructor(
logOut?.invoke()
}
reportTypeView.setClickListener(object: ReportTypeView.ClickListener{
override fun openFaultReasonView() {
faultReasonView.visibility = VISIBLE
}
override fun openWorkOrderView() {
workOrderView.visibility = VISIBLE
}
})
}
fun setCarNo(carNo: String?) {
@@ -132,9 +145,10 @@ class BoneTabLayout @JvmOverloads constructor(
TabType.REPORT_INFO -> {
tabSwitchReport.switchTab(check)
if (check) {
reportTypeView.visibility = VISIBLE
reportTypeView.showTypeSelectView()
} else {
reportTypeView.visibility = GONE
}
}

View File

@@ -22,7 +22,6 @@ import com.zhjt.mogo_core_function_devatools.status.entity.FSMStateCode
import com.zhjt.mogo_core_function_devatools.status.entity.FSMStatus
import com.zhjt.mogo_core_function_devatools.status.entity.GearStatus
import com.zhjt.mogo_core_function_devatools.status.entity.IAutopilotPreLaunchStatus
import com.zhjt.mogo_core_function_devatools.status.entity.SpeedStatus
import com.zhjt.mogo_core_function_devatools.status.entity.Status
import com.zhjt.mogo_core_function_devatools.status.entity.SteerStatus
import kotlinx.android.synthetic.main.view_start_autopilot_status.view.fSMStatusLayout
@@ -72,7 +71,7 @@ class StartAutoPilotStatusView @JvmOverloads constructor(
private fun initView() {
// 默认展示 FSM 情况未知的状态
handleFSM(FSMStatus(FSMStateCode.UnKnown, "未知"))
handleFSM(FSMStatus(FSMStateCode.UnKnown, listOf("未知")))
}
/**
@@ -132,9 +131,7 @@ class StartAutoPilotStatusView @JvmOverloads constructor(
FSMStateCode.ExistError -> {
fSMStatusLayout?.onClick {
CallerHmiManager.showFSMExceptionStatusWindow(ArrayList<String>().also {
it += status.desc
})
CallerHmiManager.showFSMExceptionStatusWindow(status.descList)
}
fSMStatusLayout?.setImageDrawable(
ContextCompat.getDrawable(
@@ -233,7 +230,6 @@ class StartAutoPilotStatusView @JvmOverloads constructor(
}
}
override fun onAttachedToWindow() {
super.onAttachedToWindow()
StatusManager.addListener(TAG, this)
@@ -256,10 +252,6 @@ class StartAutoPilotStatusView @JvmOverloads constructor(
handleFSM(status)
}
is SpeedStatus -> {
// TODO
}
else -> {
handleWithoutFSM(status)
}

View File

@@ -54,7 +54,7 @@ class FSMStatusDetailView @JvmOverloads constructor(
}
}
fun setFsmErrorStatus(msgArray: ArrayList<String>) {
fun setFsmErrorStatus(msgArray: List<String>) {
tvTitle?.text = "FSM异常"
runCatching {
val c = Color.parseColor("#FF4E41")
@@ -93,7 +93,7 @@ class FSMStatusDetailView @JvmOverloads constructor(
removeFsmMsgItemView()
}
private fun addFsmMsgItemView(msgArray: ArrayList<String>, isError: Boolean) {
private fun addFsmMsgItemView(msgArray: List<String>, isError: Boolean) {
if (llFsmMsgContainerLayout == null) {
Logger.e(TAG, "addFsmMsmItemView llFsmMsgContainerLayout is null")
return
@@ -145,14 +145,7 @@ class FSMStatusDetailView @JvmOverloads constructor(
}
FSMStateCode.ExistError -> {
// TODO 修改成多条
setFsmErrorStatus(ArrayList<String>().also {
it += status.desc
it += status.desc
it += status.desc
it += status.desc
it += status.desc
})
setFsmErrorStatus(status.descList)
}
}
}

View File

@@ -25,7 +25,7 @@ class FSMStatusDetailWindowManager private constructor() {
}
fun showExceptionStatus(
context: Context, errorMsg: ArrayList<String>
context: Context, errorMsg: List<String>
) {
if (mFSMStatusDetailView == null) {
mFSMStatusDetailView = FSMStatusDetailView(context)

View File

@@ -0,0 +1,497 @@
package com.mogo.eagle.core.function.hmi.bone.tab
import android.annotation.SuppressLint
import android.content.Context
import android.os.Bundle
import android.os.Handler
import android.os.Looper
import android.text.Editable
import android.text.TextWatcher
import com.iflytek.cloud.ErrorCode
import com.iflytek.cloud.InitListener
import com.iflytek.cloud.RecognizerListener
import com.iflytek.cloud.RecognizerResult
import com.iflytek.cloud.SpeechError
import com.iflytek.cloud.SpeechRecognizer
import android.util.AttributeSet
import android.util.Log
import android.view.LayoutInflater
import android.view.View
import android.view.animation.Animation
import android.view.animation.ScaleAnimation
import android.widget.EditText
import androidx.constraintlayout.widget.ConstraintLayout
import androidx.core.content.ContextCompat
import androidx.recyclerview.widget.LinearLayoutManager
import com.amap.api.services.core.LatLonPoint
import com.amap.api.services.geocoder.GeocodeResult
import com.amap.api.services.geocoder.GeocodeSearch
import com.amap.api.services.geocoder.RegeocodeQuery
import com.amap.api.services.geocoder.RegeocodeResult
import com.mogo.commons.storage.SharedPrefsMgr
import com.mogo.eagle.core.data.app.AppConfigInfo
import com.mogo.eagle.core.data.deva.report.CategoryInfo
import com.mogo.eagle.core.data.deva.report.PadAddProblemReq
import com.mogo.eagle.core.data.deva.report.PadProblemInfo
import com.mogo.eagle.core.function.api.devatools.IMoGoDevaToolsListener
import com.mogo.eagle.core.function.api.order.IOrderListener
import com.mogo.eagle.core.function.call.autopilot.CallerChassisLocationWGS84ListenerManager
import com.mogo.eagle.core.function.call.devatools.CallerDevaToolsListenerManager
import com.mogo.eagle.core.function.call.devatools.CallerDevaToolsManager
import com.mogo.eagle.core.function.call.order.CallerOrderListenerManager
import com.mogo.eagle.core.function.hmi.R
import com.mogo.eagle.core.utilcode.util.JsonParser
import com.mogo.eagle.core.utilcode.util.ThreadUtils
import com.mogo.eagle.core.utilcode.util.TimeUtils
import com.mogo.eagle.core.utilcode.util.TimeUtils.millis2String
import com.mogo.eagle.core.utilcode.util.ToastUtils
import com.mogo.tts.base.SpeechUtils
import com.zhjt.mogo_core_function_devatools.badcase.consts.BadCaseConfig
import com.zhjt.mogo_core_function_devatools.workorder.adapter.OrderReasonAdapter
import kotlinx.android.synthetic.main.view_fault_reason.view.etNoteInput
import kotlinx.android.synthetic.main.view_fault_reason.view.faultReasonGroup
import kotlinx.android.synthetic.main.view_fault_reason.view.ivNoteAudio
import kotlinx.android.synthetic.main.view_fault_reason.view.ivTimeAdd
import kotlinx.android.synthetic.main.view_fault_reason.view.ivTimeReduce
import kotlinx.android.synthetic.main.view_fault_reason.view.rvFaultList
import kotlinx.android.synthetic.main.view_fault_reason.view.tvFaultCancel
import kotlinx.android.synthetic.main.view_fault_reason.view.tvFaultReason
import kotlinx.android.synthetic.main.view_fault_reason.view.tvFaultReport
import kotlinx.android.synthetic.main.view_fault_reason.view.tvFaultTime
import kotlinx.android.synthetic.main.view_fault_reason.view.tvFaultType
import kotlinx.android.synthetic.main.view_fault_reason.view.tvOccurrenceTime
import kotlinx.android.synthetic.main.view_fault_reason.view.tvUploadSuccess
/**
* 故障原因编辑视图
*/
class FaultReasonView @JvmOverloads constructor(
context: Context,
attrs: AttributeSet? = null,
defStyleAttr: Int = 0
) : ConstraintLayout(context, attrs, defStyleAttr), IMoGoDevaToolsListener, IOrderListener {
private val TAG = "FaultReasonView"
// 语音听写对象
private var mIat: SpeechRecognizer? = null
// 用HashMap存储听写结果
private val mIatResults: HashMap<String, String> = LinkedHashMap()
var ret = 0 // 函数调用返回值
private var audioStatus = false
private var workOrderOccurrenceTime = System.currentTimeMillis() //故障发生时间
private var clickListener: ClickListener? = null
private lateinit var orderReasonAdapter: OrderReasonAdapter
private var address: String = "" //故障地点
private var faultCodeList = ArrayList<String>() //故障码列表
private var level1Id: Int = 0 //一级分类ID
private var level2Id: Int = 0 //二级分类ID
private var level3Id: Int = 0 //三级分类ID
private var level1Name: String = ""
private var level2Name: String = ""
private var level3Name: String = ""
private var reportNote: String = "" //上报描述
private val reportType: Int = 1 //上报方式0小程序 1司机屏 2云端上报
private var source: Int = 0 //操作源0:默认,一级分类 1:类型二级分类2:原因,三级分类
private var hasLevel2: Boolean = false //是否有二级分类
private var hasLevel3: Boolean = false //是否有三级分类
private var typeList: List<CategoryInfo> ?= null //故障类型列表
private var reasonList: List<CategoryInfo> ?= null //故障原因列表
private var faultTypeSelectStatus: Boolean = false //故障类型选择状态
private var faultReasonSelectStatus: Boolean = false //故障原因选择状态
private val type = 1 //故障类接口请求Type值为1
init {
LayoutInflater.from(context).inflate(R.layout.view_fault_reason, this, true)
initView()
initEvent()
}
private fun initView(){
// 初始化识别无UI识别对象
// 使用SpeechRecognizer对象可根据回调消息自定义界面
mIat = SpeechRecognizer.createRecognizer(context, mInitListener)
val linearLayoutManager = LinearLayoutManager(context)
linearLayoutManager.orientation = LinearLayoutManager.VERTICAL
rvFaultList.layoutManager = linearLayoutManager
orderReasonAdapter = OrderReasonAdapter()
orderReasonAdapter.setListener(object: OrderReasonAdapter.ReasonSelectListener{
override fun onSelectReason(reason: CategoryInfo, mSource: Int) {
if(mSource == 1){
//类型
tvFaultType.text = reason.name
//选择了故障类型
tvFaultType.performClick()
if(level2Id != 0 && level2Id == reason.id){
//故障类型选择没有变化
reasonList?.let { orderReasonAdapter.setData(it,2) }
}else{
//故障类型发生了变化
level2Id = reason.id
level2Name = reason.name
source = 2
//获取故障三级分类即故障原因
CallerDevaToolsManager.getCategories(BadCaseConfig.tenantId,3,level2Id,type,0)
tvFaultReason.text = ""
level3Id = 0
level3Name = ""
}
}else{
//原因
tvFaultReason.text = reason.name
tvFaultReason.performClick()
level3Id = reason.id
level3Name = reason.name
}
}
})
rvFaultList.adapter = orderReasonAdapter
}
@SuppressLint("SetTextI18n")
private fun initEvent(){
CallerDevaToolsListenerManager.addListener(TAG, this)
CallerOrderListenerManager.addListener(TAG,this)
val iconDown = ContextCompat.getDrawable(context, R.drawable.icon_fault_expand)
iconDown?.setBounds(0, 0, iconDown.minimumWidth, iconDown.minimumHeight)
val iconUp = ContextCompat.getDrawable(context, R.drawable.icon_fault_retract)
iconUp?.setBounds(0, 0, iconUp.minimumWidth, iconUp.minimumHeight)
//获取一级分类
CallerDevaToolsManager.getCategories(BadCaseConfig.tenantId,1,0,type,0)
//弹窗展示时间
tvFaultTime.text = millis2String(System.currentTimeMillis(), TimeUtils.getHourMinSecondFormat())
//故障类型选择
tvFaultType.setOnClickListener {
if(!hasLevel2){
ToastUtils.showShort("运营后台没有配置故障类型")
return@setOnClickListener
}
if(faultTypeSelectStatus){
//关闭
faultTypeSelectStatus = false
tvFaultType.setCompoundDrawables(null, null, iconDown, null)
//隐藏列表
rvFaultList.visibility = View.GONE
}else{
//如果故障原因此时为打开状态,则关闭
if(faultReasonSelectStatus){
tvFaultReason.performClick()
}
//打开
faultTypeSelectStatus = true
tvFaultType.setCompoundDrawables(null, null, iconUp, null)
//展示列表
rvFaultList.visibility = View.VISIBLE
(rvFaultList.layoutParams as ConstraintLayout.LayoutParams).topToBottom = R.id.tvFaultType
source = 1
if(typeList.isNullOrEmpty()){
//获取故障二级分类即故障类型
CallerDevaToolsManager.getCategories(BadCaseConfig.tenantId,2,level1Id,type,0)
}else{
orderReasonAdapter.setData(typeList!!,source)
}
}
}
//故障原因选择
tvFaultReason.setOnClickListener {
if(tvFaultType.text.isEmpty()){
ToastUtils.showShort("请先选择故障类型")
return@setOnClickListener
}
if(faultReasonSelectStatus){
//关闭
faultReasonSelectStatus = false
tvFaultReason.setCompoundDrawables(null, null, iconDown, null)
//隐藏列表
rvFaultList.visibility = View.GONE
}else{
//打开
faultReasonSelectStatus = true
tvFaultReason.setCompoundDrawables(null, null, iconUp, null)
//展示列表
rvFaultList.visibility = View.VISIBLE
(rvFaultList.layoutParams as ConstraintLayout.LayoutParams).topToBottom = R.id.tvFaultReason
}
}
//发生时间
tvOccurrenceTime.text = millis2String(workOrderOccurrenceTime, TimeUtils.getHourMinFormat())
ivTimeReduce.setOnClickListener {
workOrderOccurrenceTime -= 60000
tvOccurrenceTime.text = millis2String(workOrderOccurrenceTime, TimeUtils.getHourMinFormat())
}
ivTimeAdd.setOnClickListener {
if(workOrderOccurrenceTime + 60000 > System.currentTimeMillis()){
ToastUtils.showShort("发生时间应在当前时间之前")
return@setOnClickListener
}
workOrderOccurrenceTime += 60000
tvOccurrenceTime.text = millis2String(workOrderOccurrenceTime, TimeUtils.getHourMinFormat())
}
//补充描述
etNoteInput.onFocusChangeListener = OnFocusChangeListener { v, hasFocus ->
val edit = v as EditText
if(hasFocus){
edit.hint = ""
}else{
edit.hint = "手动输入"
}
}
etNoteInput.addTextChangedListener(object: TextWatcher {
override fun beforeTextChanged(s: CharSequence?, start: Int, count: Int, after: Int) {
}
override fun onTextChanged(s: CharSequence?, start: Int, before: Int, count: Int) {
}
override fun afterTextChanged(s: Editable?) {
}
})
//问题描述录音
ivNoteAudio.setOnClickListener {
audioStatus = !audioStatus
if(audioStatus){
ivNoteAudio.setImageDrawable(ContextCompat.getDrawable(
context,
R.drawable.icon_reason_audio_pressed
))
}else{
ivNoteAudio.setImageDrawable(ContextCompat.getDrawable(
context,
R.drawable.icon_reason_audio_normal
))
}
setAudio(audioStatus)
}
//上报
tvFaultReport.setOnClickListener{
if(level2Name.isEmpty()){
ToastUtils.showShort("请完整填写再上报")
return@setOnClickListener
}
if(hasLevel3 && level3Name.isEmpty()){
ToastUtils.showShort("请完整填写再上报")
return@setOnClickListener
}
reportNote = etNoteInput.text.toString()
//故障码列表赋值
BadCaseConfig.newFMInfoMsg?.fmInfoList?.forEach {
faultCodeList.add(it.faultId)
}
val geocodeSearch = GeocodeSearch(context)
geocodeSearch.setOnGeocodeSearchListener(object: GeocodeSearch.OnGeocodeSearchListener {
override fun onRegeocodeSearched(regeocodeResult: RegeocodeResult?, p1: Int) {
regeocodeResult?.regeocodeAddress?.formatAddress?.let {
address = it
}
val padProblemList= ArrayList<PadProblemInfo>()
val note = if(reportNote.isEmpty()){
"$level1Name-$level2Name-$level3Name"
}else{
"$level1Name-$level2Name-$level3Name($reportNote)"
}
val padProblemInfo = PadProblemInfo(address,faultCodeList,millis2String(workOrderOccurrenceTime),level1Id,
level2Id,level3Id,BadCaseConfig.lineName,note,reportType,
SharedPrefsMgr.getInstance().getString("och_account",""))
padProblemList.add(padProblemInfo)
val padAddProblemReq = PadAddProblemReq(padProblemList, AppConfigInfo.plateNumber)
CallerDevaToolsManager.problemPadAdd(padAddProblemReq)
}
override fun onGeocodeSearched(p0: GeocodeResult?, p1: Int) {
}
})
val latLon = LatLonPoint(CallerChassisLocationWGS84ListenerManager.getChassisLocationWGS84().latitude, CallerChassisLocationWGS84ListenerManager.getChassisLocationWGS84().longitude)
val q = RegeocodeQuery(latLon,200f,GeocodeSearch.AMAP)
geocodeSearch.getFromLocationAsyn(q)
}
//取消
tvFaultCancel.setOnClickListener {
this@FaultReasonView.visibility = View.GONE
}
}
private fun setAudio(status: Boolean){
if(status){
//开始录音
mIat?.let {
//清空之前的内容
mIatResults.clear()
SpeechUtils.setParam(it)
// 不显示听写对话框
ret = it.startListening(mRecognizerListener)
if (ret != ErrorCode.SUCCESS) {
ToastUtils.showShort("听写失败,错误码:$ret,请点击网址https://www.xfyun.cn/document/error-code查询解决方案")
}
}
//开始录音,展示放大缩小动效
val scaleAnimation = ScaleAnimation(
1.0f, 0.8f, 1.0f, 0.8f,
Animation.RELATIVE_TO_SELF, 0.5f,
Animation.RELATIVE_TO_SELF, 0.5f)
scaleAnimation.duration = 1000
scaleAnimation.repeatCount = -1
ivNoteAudio.startAnimation(scaleAnimation)
}else{
//停止语音听写
mIat?.stopListening()
//结束动画
ivNoteAudio.clearAnimation()
}
}
/**
* 初始化监听器。
*/
private val mInitListener = InitListener { code ->
if (code != ErrorCode.SUCCESS) {
ToastUtils.showShort("讯飞语音听写初始化失败,错误码:$code")
}
}
/**
* 听写监听器。
*/
private val mRecognizerListener: RecognizerListener = object : RecognizerListener{
override fun onVolumeChanged(p0: Int, p1: ByteArray?) {
//showTip("当前正在说话,音量大小 = " + volume + " 返回音频数据 = " + data.length);
}
override fun onBeginOfSpeech() {
// 此回调表示sdk内部录音机已经准备好了用户可以开始语音输入
}
override fun onEndOfSpeech() {
// 此回调表示:检测到了语音的尾端点,已经进入识别过程,不再接受语音输入
}
override fun onResult(results: RecognizerResult?, isLast: Boolean) {
results?.let {
printResult(it)
}
}
override fun onError(p0: SpeechError?) {
// Tips
// 错误码10118(您没有说话),可能是录音机权限被禁,需要提示用户打开应用的录音权限。
}
override fun onEvent(p0: Int, p1: Int, p2: Int, p3: Bundle?) {
// 以下代码用于获取与云端的会话id当业务出错时将会话id提供给技术支持人员可用于查询会话日志定位出错原因
// 若使用本地能力会话id为null
// if (SpeechEvent.EVENT_SESSION_ID == eventType) {
// String sid = obj.getString(SpeechEvent.KEY_EVENT_SESSION_ID);
// Log.d(TAG, "session id =" + sid);
// }
}
}
/**
* 显示结果
*/
@SuppressLint("SetTextI18n")
private fun printResult(results: RecognizerResult) {
val text: String = JsonParser.parseIatResult(results.resultString)
Log.i(TAG, "语音内容=$text")
if(text.isNotEmpty()){
if(etNoteInput.text.toString().isEmpty()){
etNoteInput.setText(text)
etNoteInput.setSelection(text.length)
}else{
val startStr = etNoteInput.text.toString().substring(0,etNoteInput.selectionStart)
val endStr = etNoteInput.text.toString().substring(etNoteInput.selectionEnd,etNoteInput.text.toString().length)
etNoteInput.setText(startStr+text+endStr)
etNoteInput.setSelection(startStr.length+text.length)
}
}
}
fun setClickListener(clickListener: ClickListener) {
this.clickListener = clickListener
}
interface ClickListener {
fun closeWindow()
}
/**
* 故障上报成功
*/
override fun problemPadAddSuccess() {
super.problemPadAddSuccess()
//显示上报成功页面,短暂停留关闭弹窗
ThreadUtils.runOnUiThread {
//结束动画
ivNoteAudio.clearAnimation()
rvFaultList.visibility = View.GONE
tvUploadSuccess.visibility = View.VISIBLE
faultReasonGroup.visibility = View.GONE
val successHandler = Handler(Looper.getMainLooper())
successHandler.postDelayed({
this@FaultReasonView.visibility = View.GONE
},1500)
}
}
override fun problemPadAddError(msg: String) {
super.problemPadAddError(msg)
ToastUtils.showShort("故障原因上报失败$msg")
}
override fun getCategoriesSuccess(list: List<CategoryInfo>) {
super.getCategoriesSuccess(list)
ThreadUtils.runOnUiThread {
if(list.isNotEmpty()){
if(source == 0){
level1Id = list[0].id
level1Name = list[0].name
source = 1
//获取故障二级分类即故障类型
CallerDevaToolsManager.getCategories(BadCaseConfig.tenantId,2,level1Id,type,0)
}else{
if(source == 1){
typeList = list
hasLevel2 = true
}else{
reasonList = list
hasLevel3 = true
}
orderReasonAdapter.setData(list,source)
}
}else{
if(source == 2){
hasLevel3 = false
}else{
hasLevel2 = false
ToastUtils.showShort("故障类型列表为空")
}
}
}
}
override fun getCategoriesError(msg: String) {
super.getCategoriesError(msg)
ToastUtils.showShort("故障列表获取失败:$msg")
}
}

View File

@@ -0,0 +1,261 @@
package com.mogo.eagle.core.function.hmi.bone.tab
import android.content.Context
import android.os.CountDownTimer
import android.os.Handler
import android.os.Looper
import android.os.SystemClock
import android.util.AttributeSet
import android.view.LayoutInflater
import android.view.View
import androidx.constraintlayout.widget.ConstraintLayout
import com.amap.api.services.core.LatLonPoint
import com.amap.api.services.geocoder.GeocodeResult
import com.amap.api.services.geocoder.GeocodeSearch
import com.amap.api.services.geocoder.RegeocodeQuery
import com.amap.api.services.geocoder.RegeocodeResult
import com.mogo.commons.env.ProjectUtils
import com.mogo.commons.storage.SharedPrefsMgr
import com.mogo.eagle.core.data.app.AppConfigInfo
import com.mogo.eagle.core.data.deva.report.CategoryInfo
import com.mogo.eagle.core.data.deva.report.PadAddProblemReq
import com.mogo.eagle.core.data.deva.report.PadProblemInfo
import com.mogo.eagle.core.function.api.devatools.IMoGoDevaToolsListener
import com.mogo.eagle.core.function.call.autopilot.CallerAutoPilotControlManager
import com.mogo.eagle.core.function.call.autopilot.CallerChassisLocationWGS84ListenerManager
import com.mogo.eagle.core.function.call.devatools.CallerDevaToolsListenerManager
import com.mogo.eagle.core.function.call.devatools.CallerDevaToolsManager
import com.mogo.eagle.core.function.hmi.R
import com.mogo.eagle.core.utilcode.util.ThreadUtils
import com.mogo.eagle.core.utilcode.util.TimeUtils.millis2String
import com.mogo.eagle.core.utilcode.util.ToastUtils
import com.zhjt.mogo_core_function_devatools.badcase.consts.BadCaseConfig
import kotlinx.android.synthetic.main.view_report_type.view.ivOneClickReport
import kotlinx.android.synthetic.main.view_report_type.view.oneClickGroup
import kotlinx.android.synthetic.main.view_report_type.view.reportTypeGroup
import kotlinx.android.synthetic.main.view_report_type.view.tvOneClickReportTitle
import kotlinx.android.synthetic.main.view_report_type.view.tvReportSuccess
import kotlinx.android.synthetic.main.view_report_type.view.tvReportTypeFault
import kotlinx.android.synthetic.main.view_report_type.view.tvReportTypeTakeOver
import kotlin.math.absoluteValue
import kotlin.math.round
import kotlin.random.Random
/**
* 上报类型选择,包括一键上报及上报类型选择:故障类、接管类
* 一键上报和类型选择互斥,当点击弹出上报类型选择时,一键上报隐藏
*/
class ReportTypeView @JvmOverloads constructor(
context: Context,
attrs: AttributeSet? = null,
defStyleAttr: Int = 0
) : ConstraintLayout(context, attrs, defStyleAttr), IMoGoDevaToolsListener {
private val TAG = "ReportTypeView"
private var isOneClickType: Boolean = false //是否是一键上报类型
private var hasReportOperate: Boolean = false //是否点击了一键上报按钮
private var oneClickTimer: CountDownTimer?= null
private var clickListener: ClickListener? = null
private var address: String = "" //故障地点
private var faultCodeList = ArrayList<String>() //故障码列表
private var level1Id: Int = 0 //一级分类ID
private var level2Id: Int = 0 //二级分类ID
private var level3Id: Int = 0 //三级分类ID
private var level1Name: String = ""
private var level2Name: String = ""
private var level3Name: String = ""
private val reportType: Int = 1 //上报方式0小程序 1司机屏 2云端上报
private var level: Int = 1
private var canOneReport: Boolean = false //是否可以一键上报
init {
LayoutInflater.from(context).inflate(R.layout.view_report_type, this, true)
initView()
}
private fun initView(){
CallerDevaToolsListenerManager.addListener(TAG, this)
if(isOneClickType){
showOneCLickReportView()
}else{
showTypeSelectView()
}
//一键上报
ivOneClickReport.setOnClickListener {
if(!canOneReport){
ToastUtils.showShort("故障描述获取失败不能上报")
return@setOnClickListener
}
hasReportOperate = true
BadCaseConfig.newFMInfoMsg?.fmInfoList?.forEach {
faultCodeList.add(it.faultId)
}
val geocodeSearch = GeocodeSearch(context)
geocodeSearch.setOnGeocodeSearchListener(object: GeocodeSearch.OnGeocodeSearchListener {
override fun onRegeocodeSearched(regeocodeResult: RegeocodeResult?, p1: Int) {
regeocodeResult?.regeocodeAddress?.formatAddress?.let {
address = it
}
val padProblemList= ArrayList<PadProblemInfo>()
val padProblemInfo = PadProblemInfo(address,faultCodeList,millis2String(System.currentTimeMillis()),level1Id,
level2Id,level3Id,BadCaseConfig.lineName,"${level1Name}-${level2Name}-${level3Name}",reportType,
SharedPrefsMgr.getInstance().getString("och_account",""))
padProblemList.add(padProblemInfo)
val padAddProblemReq = PadAddProblemReq(padProblemList, AppConfigInfo.plateNumber)
CallerDevaToolsManager.problemPadAdd(padAddProblemReq)
}
override fun onGeocodeSearched(p0: GeocodeResult?, p1: Int) {
}
})
val latLon = LatLonPoint(CallerChassisLocationWGS84ListenerManager.getChassisLocationWGS84().latitude, CallerChassisLocationWGS84ListenerManager.getChassisLocationWGS84().longitude)
val q = RegeocodeQuery(latLon,200f, GeocodeSearch.AMAP)
geocodeSearch.getFromLocationAsyn(q)
}
//故障类
tvReportTypeFault.setOnClickListener {
//TODO 更改!
if(!ProjectUtils.isSaas()){
clickListener?.openFaultReasonView()
}else{
//展示工单上报弹窗
clickListener?.openWorkOrderView()
}
this@ReportTypeView.visibility = View.GONE
}
//主动录包
tvReportTypeTakeOver.setOnClickListener {
val response = CallerAutoPilotControlManager.recordPackage(
BadCaseConfig.type, Random(SystemClock.elapsedRealtime()).nextInt().absoluteValue,
BadCaseConfig.totalDuration, BadCaseConfig.previousDuration)
if(response){
//已发起录包
oneClickGroup.visibility = View.GONE
reportTypeGroup.visibility = View.GONE
tvReportSuccess.visibility = View.VISIBLE
tvReportSuccess.text = resources.getString(R.string.record_success)
val successHandler = Handler(Looper.getMainLooper())
successHandler.postDelayed({
this@ReportTypeView.visibility = View.GONE
},1500)
}else{
ToastUtils.showShort("主动录包命令下发失败")
this@ReportTypeView.visibility = View.GONE
}
}
}
/**
* 展示一键上报视图
*/
private fun showOneCLickReportView(){
oneClickGroup.visibility = View.VISIBLE
reportTypeGroup.visibility = View.GONE
tvReportSuccess.visibility = View.GONE
tvOneClickReportTitle.text = String.format(resources.getString(R.string.identified_vehicle_malfunction),5)
oneClickTimer = object : CountDownTimer(5000, 1000) {
override fun onTick(count: Long) {
ThreadUtils.runOnUiThread {
tvOneClickReportTitle.text = String.format(resources.getString(R.string.identified_vehicle_malfunction),round((count.toDouble()/1000)).toInt())
}
}
override fun onFinish() {
//如果有页面操作,则不自动关闭窗口
if(!hasReportOperate){
ThreadUtils.runOnUiThread {
this@ReportTypeView.visibility = View.GONE
}
}
}
}
oneClickTimer?.start()
}
/**
* 展示类型选择视图
*/
fun showTypeSelectView(){
oneClickGroup.visibility = View.GONE
reportTypeGroup.visibility = View.VISIBLE
tvReportSuccess.visibility = View.GONE
}
/**
* 故障上报成功
*/
override fun problemPadAddSuccess() {
//显示上报成功页面,短暂停留关闭弹窗
ThreadUtils.runOnUiThread {
oneClickGroup.visibility = View.GONE
reportTypeGroup.visibility = View.GONE
tvReportSuccess.visibility = View.VISIBLE
tvReportSuccess.text = resources.getString(R.string.report_success)
val successHandler = Handler(Looper.getMainLooper())
successHandler.postDelayed({
this.visibility = View.GONE
},1500)
}
}
override fun problemPadAddError(msg: String) {
super.problemPadAddError(msg)
ToastUtils.showShort("故障原因上报失败$msg")
ThreadUtils.runOnUiThread {
this.visibility = View.GONE
}
}
override fun getCategoriesSuccess(list: List<CategoryInfo>) {
super.getCategoriesSuccess(list)
if(list.isEmpty()){
ToastUtils.showShort("一键上报故障描述后台未配置")
canOneReport = false
}else{
when (level) {
1 -> {
level1Id = list[0].id
level1Name = list[0].name
level = 2
//请求二级一键上报配置
CallerDevaToolsManager.getCategories(BadCaseConfig.tenantId,level,level1Id,4,1)
}
2 -> {
level2Id = list[0].id
level2Name = list[0].name
level = 3
//请求三级一键上报配置
CallerDevaToolsManager.getCategories(BadCaseConfig.tenantId,level,level2Id,4,1)
}
else -> {
level3Id = list[0].id
level3Name = list[0].name
canOneReport = true
}
}
}
}
override fun getCategoriesError(msg: String) {
super.getCategoriesError(msg)
ToastUtils.showShort("一键上报故障描述获取失败$msg")
canOneReport = false
}
interface ClickListener {
fun openFaultReasonView()
fun openWorkOrderView()
}
fun setClickListener(clickListener: ClickListener) {
this.clickListener = clickListener
}
}

View File

@@ -0,0 +1,312 @@
package com.mogo.eagle.core.function.hmi.bone.tab
import android.annotation.SuppressLint
import android.content.Context
import android.os.Bundle
import android.text.Editable
import android.text.TextWatcher
import android.util.AttributeSet
import android.util.Log
import android.view.LayoutInflater
import android.view.View
import android.view.animation.Animation
import android.view.animation.ScaleAnimation
import android.widget.EditText
import androidx.constraintlayout.widget.ConstraintLayout
import com.iflytek.cloud.ErrorCode
import com.iflytek.cloud.InitListener
import com.iflytek.cloud.RecognizerListener
import com.iflytek.cloud.RecognizerResult
import com.iflytek.cloud.SpeechError
import com.iflytek.cloud.SpeechRecognizer
import com.mogo.commons.storage.SharedPrefsMgr
import com.mogo.eagle.core.data.app.AppConfigInfo
import com.mogo.eagle.core.data.deva.report.FaultDetailInfo
import com.mogo.eagle.core.data.deva.report.FaultInfo
import com.mogo.eagle.core.data.deva.report.WorkOrderReportInfo
import com.mogo.eagle.core.data.msgbox.FMInfoMsg
import com.mogo.eagle.core.function.api.devatools.IMoGoDevaToolsListener
import com.mogo.eagle.core.function.call.autopilot.CallerChassisLocationWGS84ListenerManager
import com.mogo.eagle.core.function.call.devatools.CallerDevaToolsListenerManager
import com.mogo.eagle.core.function.call.devatools.CallerDevaToolsManager
import com.mogo.eagle.core.function.call.msgbox.CallerMsgBoxManager
import com.mogo.eagle.core.function.hmi.R
import com.mogo.eagle.core.utilcode.util.JsonParser
import com.mogo.eagle.core.utilcode.util.ThreadUtils
import com.mogo.eagle.core.utilcode.util.TimeUtils
import com.mogo.eagle.core.utilcode.util.TimeUtils.millis2String
import com.mogo.eagle.core.utilcode.util.ToastUtils
import com.mogo.tts.base.SpeechUtils
import com.zhjt.mogo_core_function_devatools.badcase.consts.BadCaseConfig
import kotlinx.android.synthetic.main.view_work_order.view.et_describe_input
import kotlinx.android.synthetic.main.view_work_order.view.iv_describe_audio
import kotlinx.android.synthetic.main.view_work_order.view.iv_time_add
import kotlinx.android.synthetic.main.view_work_order.view.iv_time_reduce
import kotlinx.android.synthetic.main.view_work_order.view.tv_occurrence_time
import kotlinx.android.synthetic.main.view_work_order.view.tv_work_order_cancel
import kotlinx.android.synthetic.main.view_work_order.view.tv_work_order_report
import kotlinx.android.synthetic.main.view_work_order.view.tv_work_order_time
import kotlinx.android.synthetic.main.view_work_order.view.wrap_radio_group
import kotlinx.coroutines.DelicateCoroutinesApi
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.GlobalScope
import kotlinx.coroutines.launch
/**
* 工单上报视图
*/
class WorkOrderView @JvmOverloads constructor(
context: Context,
attrs: AttributeSet? = null,
defStyleAttr: Int = 0
) : ConstraintLayout(context, attrs, defStyleAttr), IMoGoDevaToolsListener {
private val TAG = "WorkOrderView"
// 语音听写对象
private var mIat: SpeechRecognizer? = null
// 用HashMap存储听写结果
private val mIatResults: HashMap<String, String> = LinkedHashMap()
private var workOrderType = "" //工单问题类型
private var workOrderOccurrenceTime = System.currentTimeMillis() //故障发生时间
var ret = 0 // 函数调用返回值
private var audioStatus = false
init {
LayoutInflater.from(context).inflate(R.layout.view_work_order, this, true)
initView()
initEvent()
}
private fun initView(){
// 初始化识别无UI识别对象
// 使用SpeechRecognizer对象可根据回调消息自定义界面
mIat = SpeechRecognizer.createRecognizer(context, mInitListener)
}
@OptIn(DelicateCoroutinesApi::class)
@SuppressLint("SetTextI18n")
private fun initEvent(){
CallerDevaToolsListenerManager.addListener(TAG, this)
//弹窗展示时间
tv_work_order_time.text = resources.getString(R.string.work_order_time) +
millis2String(System.currentTimeMillis(), TimeUtils.getHourMinSecondFormat())
wrap_radio_group.setOnCheckedChangeListener{_, checkedId ->
when(checkedId){
R.id.rb_type_software->{
workOrderType = "软件"
}
R.id.rb_type_kit->{
workOrderType = "套件"
}
R.id.rb_type_vehicle->{
workOrderType = "车辆"
}
R.id.rb_type_capacity->{
workOrderType = "运力"
}
R.id.rb_type_environment->{
workOrderType = "环境"
}
R.id.rb_type_other->{
workOrderType = "其他"
}
}
}
//发生时间
tv_occurrence_time.text = millis2String(workOrderOccurrenceTime, TimeUtils.getHourMinFormat())
iv_time_reduce.setOnClickListener {
workOrderOccurrenceTime -= 60000
tv_occurrence_time.text = millis2String(workOrderOccurrenceTime, TimeUtils.getHourMinFormat())
}
iv_time_add.setOnClickListener {
if(workOrderOccurrenceTime + 60000 > System.currentTimeMillis()){
ToastUtils.showShort("发生时间应在当前时间之前")
return@setOnClickListener
}
workOrderOccurrenceTime += 60000
tv_occurrence_time.text = millis2String(workOrderOccurrenceTime, TimeUtils.getHourMinFormat())
}
et_describe_input.onFocusChangeListener = OnFocusChangeListener { v, hasFocus ->
val edit = v as EditText
if(hasFocus){
edit.hint = ""
}else{
edit.hint = "手动输入"
}
}
et_describe_input.addTextChangedListener(object: TextWatcher {
override fun beforeTextChanged(s: CharSequence?, start: Int, count: Int, after: Int) {
}
override fun onTextChanged(s: CharSequence?, start: Int, before: Int, count: Int) {
}
override fun afterTextChanged(s: Editable?) {
}
})
//问题描述录音
iv_describe_audio.setOnClickListener {
audioStatus = !audioStatus
setAudio(audioStatus)
}
//上报
tv_work_order_report.setOnClickListener {
//工单问题类型必选,没有选择,进行提示
if(workOrderType.isEmpty()){
ToastUtils.showShort("请选择问题类型")
return@setOnClickListener
}
if(et_describe_input.text.toString().isEmpty()){
ToastUtils.showShort("请填写问题描述")
return@setOnClickListener
}
GlobalScope.launch(Dispatchers.IO){
val msgBoxList = CallerMsgBoxManager.queryFMInfoList(context,
workOrderOccurrenceTime-120000,workOrderOccurrenceTime+120000)
val faultList = ArrayList<FaultInfo>()
msgBoxList?.forEach { msgBoxBean ->
val fmInfoMsg = msgBoxBean.bean as FMInfoMsg
fmInfoMsg.fmInfoList?.forEach { fault ->
val faultBean = FaultInfo(false,fault.faultId,fault.faultName,
fault.faultTime.toString(), FaultDetailInfo(fault.faultDesc)
)
faultList.add(faultBean)
}
}
val workOrderReportInfo = WorkOrderReportInfo(workOrderType,workOrderOccurrenceTime.toString(),
et_describe_input.text.toString(), CallerChassisLocationWGS84ListenerManager.getChassisLocationWGS84().longitude.toString(),
CallerChassisLocationWGS84ListenerManager.getChassisLocationWGS84().latitude.toString(),
AppConfigInfo.plateNumber, SharedPrefsMgr.getInstance().getString("och_account","") ,
BadCaseConfig.dockerVersion ?:"",faultList)
CallerDevaToolsManager.workOrderReport(workOrderReportInfo)
}
}
//取消
tv_work_order_cancel.setOnClickListener {
this@WorkOrderView.visibility = View.GONE
}
}
private fun setAudio(status: Boolean){
if(status){
//开始录音
mIat?.let {
//清空之前的内容
mIatResults.clear()
SpeechUtils.setParam(it)
// 不显示听写对话框
ret = it.startListening(mRecognizerListener)
if (ret != ErrorCode.SUCCESS) {
ToastUtils.showShort("听写失败,错误码:$ret,请点击网址https://www.xfyun.cn/document/error-code查询解决方案")
}
}
//开始录音,展示放大缩小动效
val scaleAnimation = ScaleAnimation(
1.0f, 0.8f, 1.0f, 0.8f,
Animation.RELATIVE_TO_SELF, 0.5f, Animation.RELATIVE_TO_SELF, 0.5f
)
scaleAnimation.duration = 1000
scaleAnimation.repeatCount = -1
iv_describe_audio.startAnimation(scaleAnimation)
}else{
//停止语音听写
mIat?.stopListening()
//结束动画
iv_describe_audio.clearAnimation()
}
}
/**
* 初始化监听器。
*/
private val mInitListener = InitListener { code ->
if (code != ErrorCode.SUCCESS) {
ToastUtils.showShort("讯飞语音听写初始化失败,错误码:$code")
}
}
/**
* 听写监听器。
*/
private val mRecognizerListener: RecognizerListener = object : RecognizerListener {
override fun onVolumeChanged(p0: Int, p1: ByteArray?) {
//showTip("当前正在说话,音量大小 = " + volume + " 返回音频数据 = " + data.length);
}
override fun onBeginOfSpeech() {
// 此回调表示sdk内部录音机已经准备好了用户可以开始语音输入
}
override fun onEndOfSpeech() {
// 此回调表示:检测到了语音的尾端点,已经进入识别过程,不再接受语音输入
}
override fun onResult(results: RecognizerResult?, isLast: Boolean) {
results?.let {
printResult(it)
}
}
override fun onError(p0: SpeechError?) {
// Tips
// 错误码10118(您没有说话),可能是录音机权限被禁,需要提示用户打开应用的录音权限。
}
override fun onEvent(p0: Int, p1: Int, p2: Int, p3: Bundle?) {
// 以下代码用于获取与云端的会话id当业务出错时将会话id提供给技术支持人员可用于查询会话日志定位出错原因
// 若使用本地能力会话id为null
// if (SpeechEvent.EVENT_SESSION_ID == eventType) {
// String sid = obj.getString(SpeechEvent.KEY_EVENT_SESSION_ID);
// Log.d(TAG, "session id =" + sid);
// }
}
}
/**
* 显示结果
*/
@SuppressLint("SetTextI18n")
private fun printResult(results: RecognizerResult) {
val text: String = JsonParser.parseIatResult(results.resultString)
Log.i(TAG, "语音内容=$text")
if(text.isNotEmpty()){
if(et_describe_input.text.toString().isEmpty()){
et_describe_input.setText(text)
et_describe_input.setSelection(text.length)
}else{
val startStr = et_describe_input.text.toString().substring(0,et_describe_input.selectionStart)
val endStr = et_describe_input.text.toString().substring(et_describe_input.selectionEnd,et_describe_input.text.toString().length)
et_describe_input.setText(startStr+text+endStr)
et_describe_input.setSelection(startStr.length+text.length)
}
}
}
override fun workOrderReportSuccess() {
ToastUtils.showShort("工单上报成功")
ThreadUtils.runOnUiThread {
this@WorkOrderView.visibility = View.GONE
}
}
override fun workOrderReportError() {
ToastUtils.showShort("工单上报失败")
}
}

View File

@@ -13,6 +13,7 @@ import com.mogo.eagle.core.function.api.och.toolkit.IToolKitItemClickListener
import com.mogo.eagle.core.function.api.och.toolkit.ToolKitCustomItemAddParam
import com.mogo.eagle.core.function.api.och.toolkit.ToolKitDefaultItemAddParam
import com.mogo.eagle.core.function.call.devatools.CallerDevaToolsManager
import com.mogo.eagle.core.function.call.hmi.CallerHmiManager
import com.mogo.eagle.core.function.hmi.R
import com.mogo.eagle.core.function.hmi.bone.toolkit.custom.ToolDriverRomaView
import com.mogo.eagle.core.function.hmi.bone.toolkit.custom.ToolRestartSystemView
@@ -161,7 +162,8 @@ object ToolKitDataManager : IToolKitItemClickListener {
ToolTypeEnum.OPERATION_PANEL.name -> {
ctx?.also {
SopView.sopView.toggle(it)
// SopView.sopView.toggle(it)
CallerHmiManager.toggleOperatePanel(true)
}
}

View File

@@ -11,6 +11,8 @@ import android.view.animation.AccelerateDecelerateInterpolator
import androidx.constraintlayout.widget.ConstraintLayout
import androidx.constraintlayout.widget.ConstraintSet
import com.mogo.eagle.core.data.map.MogoLatLng
import com.mogo.eagle.core.function.api.order.IOrderListener
import com.mogo.eagle.core.function.call.order.CallerOrderListenerManager
import com.mogo.eagle.core.function.hmi.R
import com.mogo.eagle.core.function.hmi.util.ConstraintUtil
import com.mogo.eagle.core.utilcode.mogo.view.OnPreventFastClickListener
@@ -20,13 +22,15 @@ import kotlinx.android.synthetic.main.view_map_container.view.mapBizView
import kotlinx.android.synthetic.main.view_map_container.view.overMapView
import kotlinx.android.synthetic.main.view_map_container.view.parentLayout
import kotlinx.android.synthetic.main.view_map_container.view.shadowView
import kotlinx.android.synthetic.main.view_map_container.view.visualAngleToggle
class MapContainerLayout @JvmOverloads constructor(
context: Context,
attrs: AttributeSet? = null,
defStyleAttr: Int = 0
) : ConstraintLayout(context, attrs, defStyleAttr), IMogoMapListener {
) : ConstraintLayout(context, attrs, defStyleAttr), IMogoMapListener, IOrderListener {
@Volatile
private var isScaled = false
private var isPlayingAnim = false
private var constraintUtil: ConstraintUtil? = null
@@ -71,6 +75,7 @@ class MapContainerLayout @JvmOverloads constructor(
override fun onAttachedToWindow() {
super.onAttachedToWindow()
MogoMapListenerHandler.mogoMapListenerHandler.registerHostMapListener("${TAG}${this.hashCode()}",this)
CallerOrderListenerManager.addListener("${TAG}${this.hashCode()}", this)
}
override fun onDetachedFromWindow() {
@@ -90,6 +95,15 @@ class MapContainerLayout @JvmOverloads constructor(
super.onMapClick(latLng)
}
override fun onUpdateOrderStatus(inOrder: Boolean) {
super.onUpdateOrderStatus(inOrder)
if (!inOrder) {// 订单结束
if (isScaled) {// 行程总览地图
overMapView.clearAllMarkersAndPolyline()
}
}
}
private fun swapViewsWithAnim() {
if (isPlayingAnim) return
if (constraintUtil == null) {
@@ -124,6 +138,11 @@ class MapContainerLayout @JvmOverloads constructor(
overMapView.swapSettings()
updateShadowBg(isScaled)
isScaled = !isScaled
if (isScaled) {
visualAngleToggle?.takeIf { it.visibility == View.VISIBLE }?.visibility = View.GONE
} else {
visualAngleToggle?.takeIf { it.visibility != View.VISIBLE }?.visibility = View.VISIBLE
}
}
override fun onTransitionCancel(transition: Transition?) {

View File

@@ -2,14 +2,15 @@ package com.mogo.eagle.core.function.hmi.ui
import android.content.Context
import android.text.TextUtils
import android.transition.Slide
import android.util.Log
import android.view.Gravity
import android.view.View
import android.view.ViewGroup
import android.view.WindowManager
import android.view.ViewStub
import androidx.lifecycle.ProcessLifecycleOwner
import androidx.lifecycle.lifecycleScope
import androidx.transition.Slide
import androidx.transition.TransitionManager
import com.alibaba.android.arouter.facade.annotation.Route
import com.mogo.commons.module.status.MogoStatusManager
import com.mogo.commons.voice.AIAssist
@@ -36,6 +37,7 @@ import com.mogo.eagle.core.function.api.och.toolkit.ToolKitDefaultItemAddParam
import com.mogo.eagle.core.function.call.hmi.CallerHmiViewControlListenerManager
import com.mogo.eagle.core.function.call.v2x.CallerTrafficLightListenerManager
import com.mogo.eagle.core.function.call.v2x.CallerTurnLightListenerManager
import com.mogo.eagle.core.function.hmi.R
import com.mogo.eagle.core.function.hmi.bone.status.fsm.FSMStatusDetailWindowManager
import com.mogo.eagle.core.function.hmi.bone.toolkit.ToolKitDataManager
import com.mogo.eagle.core.function.hmi.ui.camera.RoadVideoDialog
@@ -66,8 +68,6 @@ import com.zhjt.service_biz.BizConfig
import kotlinx.coroutines.Job
import kotlinx.coroutines.delay
import kotlinx.coroutines.launch
import me.jessyan.autosize.utils.AutoSizeUtils
import java.lang.ref.WeakReference
import java.util.concurrent.atomic.AtomicBoolean
import java.util.concurrent.atomic.AtomicReference
@@ -95,8 +95,6 @@ class MoGoHmiProvider : IMoGoHmiProvider {
private val xiaozhi by lazy { XiaoZhiStateManager() }
private val operatePanel by lazy { AtomicReference<WeakReference<MoGoPopWindow>>(null) }
override fun init(context: Context?) {
this.context = context
}
@@ -355,7 +353,7 @@ class MoGoHmiProvider : IMoGoHmiProvider {
/**
* 展示 FSM 异常状态弹框
*/
override fun showFSMExceptionStatusWindow(errorMsg: ArrayList<String>) {
override fun showFSMExceptionStatusWindow(errorMsg: List<String>) {
context?.let { FSMStatusDetailWindowManager.fsmStatusDetailWindowManager.showExceptionStatus(it, errorMsg)}
}
@@ -451,26 +449,22 @@ class MoGoHmiProvider : IMoGoHmiProvider {
return
}
if (show) {
if (operatePanel.get()?.get()?.isShowing() == true) {
return
var target = activity.findViewById<View>(R.id.id_operate_panel)
if (target == null) {
val vs = activity.findViewById<ViewStub>(R.id.vs_operate_panel) ?: throw AssertionError()
target = vs.inflate()
}
if (target != null && target.visibility != View.VISIBLE) {
TransitionManager.beginDelayedTransition(target.parent as ViewGroup, Slide(Gravity.START).also { it.duration = 150; it.addTarget(target) })
target.visibility = View.VISIBLE
target.post { target.bringToFront() }
}
MoGoPopWindow.Builder()
.attachToActivity(activity)
.gravityInActivity(Gravity.START or Gravity.TOP)
.contentView(OperatePanelLayout(activity))
.width(AutoSizeUtils.dp2px(activity, 1000.0f))
.height(WindowManager.LayoutParams.MATCH_PARENT)
.transition(Slide(Gravity.START), Slide(Gravity.START))
.onDismissed {
operatePanel.set(null)
}
.build()
.also {
operatePanel.set(WeakReference(it))
}
.show()
} else {
operatePanel.get()?.get()?.hide()
val operatePanelView = activity.findViewById<View>(R.id.id_operate_panel)
if (operatePanelView != null && operatePanelView.visibility == View.VISIBLE) {
TransitionManager.beginDelayedTransition(operatePanelView.parent as ViewGroup, Slide(Gravity.START).also { it.duration = 150; it.addTarget(operatePanelView) })
operatePanelView.visibility = View.GONE
}
}
}

View File

@@ -0,0 +1,69 @@
package com.mogo.eagle.core.function.hmi.ui.operate.preferences
import android.content.Context
import android.util.AttributeSet
import androidx.core.content.ContextCompat
import androidx.preference.Preference
import androidx.preference.PreferenceViewHolder
import com.mogo.eagle.core.function.hmi.R
import com.mogo.eagle.core.utilcode.kotlin.onClick
class PreferenceWithMoFang: Preference {
constructor(context: Context, attrs: AttributeSet?, defStyleAttr: Int, defStyleRes: Int) : super(context, attrs, defStyleAttr, defStyleRes)
constructor(context: Context, attrs: AttributeSet?, defStyleAttr: Int) : super(context, attrs, defStyleAttr)
constructor(context: Context, attrs: AttributeSet?) : super(context, attrs)
constructor(context: Context) : super(context)
companion object {
const val KEY_CURRENT_CONNECT_STATUS = "key_mofang_connect_status"
}
enum class MoFangConnectStatus {
CONNECT_START,
CONNECTED,
CONNECTING
}
private var status: MoFangConnectStatus? = null
override fun setDefaultValue(defaultValue: Any?) {
super.setDefaultValue(defaultValue)
status = MoFangConnectStatus.values().find { it.ordinal == defaultValue }
notifyChanged()
}
fun updateStatus(status: MoFangConnectStatus) {
this.status = status
notifyChanged()
}
override fun onBindViewHolder(holder: PreferenceViewHolder) {
super.onBindViewHolder(holder)
val stats = this.status ?: return
val btConnect = holder.findViewById(R.id.bt_mofang)
btConnect.setOnClickListener(null)
when(stats) {
MoFangConnectStatus.CONNECT_START -> {
btConnect.isEnabled = true
btConnect.background = ContextCompat.getDrawable(holder.itemView.context, R.drawable.icon_operate_panel_mofang_connect_start)
btConnect.onClick {
extras.putInt(KEY_CURRENT_CONNECT_STATUS, stats.ordinal)
onPreferenceClickListener?.onPreferenceClick(this)
}
}
MoFangConnectStatus.CONNECTED -> {
btConnect.isEnabled = true
btConnect.background = ContextCompat.getDrawable(holder.itemView.context, R.drawable.icon_operate_panel_mofang_disconnect)
btConnect.onClick {
extras.putInt(KEY_CURRENT_CONNECT_STATUS, stats.ordinal)
onPreferenceClickListener?.onPreferenceClick(this)
}
}
MoFangConnectStatus.CONNECTING -> {
btConnect.isEnabled = false
btConnect.background = ContextCompat.getDrawable(holder.itemView.context, R.drawable.icon_operate_panel_mofang_connect_doing)
}
}
}
}

View File

@@ -0,0 +1,95 @@
package com.mogo.eagle.core.function.hmi.ui.operate.preferences
import android.content.Context
import android.util.AttributeSet
import android.widget.TextView
import androidx.preference.Preference
import androidx.preference.PreferenceViewHolder
import com.mogo.eagle.core.function.hmi.R
import com.mogo.eagle.core.utilcode.kotlin.onClick
import com.mogo.eagle.core.utilcode.util.ToastUtils
import kotlin.math.max
class PreferenceWithSpeedSetting : Preference {
companion object {
const val KEY_BUNDLE_CURRENT_VALUE = "key_bundle_current_val"
}
constructor(context: Context, attrs: AttributeSet?, defStyleAttr: Int, defStyleRes: Int) : super(context, attrs, defStyleAttr, defStyleRes)
constructor(context: Context, attrs: AttributeSet?, defStyleAttr: Int) : super(context, attrs, defStyleAttr)
constructor(context: Context, attrs: AttributeSet?) : super(context, attrs)
constructor(context: Context) : super(context)
private var mDefaultValueSet: Any? = null
override fun setDefaultValue(defaultValue: Any?) {
super.setDefaultValue(defaultValue)
mDefaultValueSet = defaultValue
notifyChanged()
}
override fun onBindViewHolder(holder: PreferenceViewHolder) {
super.onBindViewHolder(holder)
val defaultSet = mDefaultValueSet ?: return
if (defaultSet !is Set<*> || defaultSet.size != 4) {
throw AssertionError()
}
val min = (defaultSet.elementAt(0) as String).toFloat()
val max = (defaultSet.elementAt(1) as String).toFloat()
var cur = (defaultSet.elementAt(2) as String).toFloat()
val step = (defaultSet.elementAt(3) as String).toFloat()
if (min > max) {
throw AssertionError()
}
if (min > cur) {
throw AssertionError()
}
if (cur > max) {
throw AssertionError()
}
val ll = holder.findViewById(R.id.ll_speed)
val btnOk = holder.findViewById(R.id.bt_ok)
val speedLimit = holder.findViewById(R.id.tv_speed_limit) as? TextView
if (speedLimit?.tag != null && speedLimit.tag is Float) {
cur = max(cur, speedLimit.tag as Float)
}
speedLimit?.text = cur.toString()
val minus = holder.findViewById(R.id.iv_speed_minus)
minus.setOnClickListener(null)
minus.onClick {
val minusAfter = cur - step
if (minusAfter < min) {
ToastUtils.showShort("阈值最小可为${min}m/s")
return@onClick
}
cur = minusAfter
btnOk.isEnabled = true
ll.isSelected = true
speedLimit?.tag = minusAfter
speedLimit?.text = minusAfter.toString()
}
val add = holder.findViewById(R.id.iv_speed_add)
add.setOnClickListener(null)
add.onClick {
val addAfter = cur + step
if (addAfter > max) {
ToastUtils.showShort("阈值最大可为${max}m/s")
return@onClick
}
cur = addAfter
ll.isSelected = true
btnOk.isEnabled = true
speedLimit?.tag = addAfter
speedLimit?.text = addAfter.toString()
}
btnOk.isEnabled = false
btnOk.setOnClickListener(null)
btnOk.onClick {
onPreferenceClickListener?.also {
extras.putFloat(KEY_BUNDLE_CURRENT_VALUE, cur)
it.onPreferenceClick(this)
}
}
}
}

View File

@@ -0,0 +1,103 @@
package com.mogo.eagle.core.function.hmi.ui.operate.preferences
import android.content.Context
import android.util.AttributeSet
import android.util.Log
import android.widget.CompoundButton
import android.widget.RadioButton
import android.widget.RadioGroup
import androidx.preference.Preference
import androidx.preference.PreferenceViewHolder
import com.mogo.eagle.core.function.hmi.R
class PreferenceWithUnmanInterval: Preference, RadioGroup.OnCheckedChangeListener {
companion object {
const val KEY_BUNDLE_CURRENT_INTERVAL = "key_bundle_unman_interval"
private const val TAG = "PreferenceWithUnmanInterval"
}
constructor(context: Context, attrs: AttributeSet?, defStyleAttr: Int, defStyleRes: Int) : super(context, attrs, defStyleAttr, defStyleRes)
constructor(context: Context, attrs: AttributeSet?, defStyleAttr: Int) : super(context, attrs, defStyleAttr)
constructor(context: Context, attrs: AttributeSet?) : super(context, attrs)
constructor(context: Context) : super(context)
enum class Interval {
FIVE_SECOND,
FIFTEEN_SECOND,
THIRTY_SECOND,
FORTY_FIVE_SECOND,
NEVER
}
private var interval: Interval? = null
override fun setDefaultValue(defaultValue: Any?) {
super.setDefaultValue(defaultValue)
Log.d(TAG, "--- setDefaultValue 1 ---:defaultValue -> $defaultValue")
if (defaultValue is Int) {
interval = when(defaultValue) {
5 -> Interval.FIVE_SECOND
15 -> Interval.FIFTEEN_SECOND
30 -> Interval.THIRTY_SECOND
45 -> Interval.FORTY_FIVE_SECOND
else -> Interval.NEVER
}
}
}
override fun onBindViewHolder(holder: PreferenceViewHolder) {
super.onBindViewHolder(holder)
Log.d(TAG, "--- onBindViewHolder 1 ---:interval -> $interval")
val temp = interval?: return
Log.d(TAG, "--- onBindViewHolder 2 --- ")
val five = holder.findViewById(R.id.rb_5s) as? RadioButton
val fifteen = holder.findViewById(R.id.rb_15s) as? RadioButton
val thirty = holder.findViewById(R.id.rb_30s) as? RadioButton
val forty_five = holder.findViewById(R.id.rb_45s) as? RadioButton
val never = holder.findViewById(R.id.rb_never) as? RadioButton
when(temp) {
Interval.FIVE_SECOND -> five?.isChecked = true
Interval.FIFTEEN_SECOND -> fifteen?.isChecked = true
Interval.THIRTY_SECOND -> thirty?.isChecked = true
Interval.FORTY_FIVE_SECOND -> forty_five?.isChecked = true
Interval.NEVER -> never?.isChecked = true
}
(holder.findViewById(R.id.rg_root) as? RadioGroup)?.also {
it.setOnCheckedChangeListener(this)
}
}
override fun onCheckedChanged(group: RadioGroup?, checkedId: Int) {
Log.d(TAG, "--- onCheckedChanged --- ")
when(checkedId) {
R.id.rb_5s -> {
Log.d(TAG, "--- onCheckedChanged 5s--- ")
extras.putInt(KEY_BUNDLE_CURRENT_INTERVAL, Interval.FIVE_SECOND.ordinal)
onPreferenceClickListener?.onPreferenceClick(this)
}
R.id.rb_15s -> {
Log.d(TAG, "--- onCheckedChanged 15s--- ")
extras.putInt(KEY_BUNDLE_CURRENT_INTERVAL, Interval.FIFTEEN_SECOND.ordinal)
onPreferenceClickListener?.onPreferenceClick(this)
}
R.id.rb_30s -> {
Log.d(TAG, "--- onCheckedChanged 30s--- ")
extras.putInt(KEY_BUNDLE_CURRENT_INTERVAL, Interval.THIRTY_SECOND.ordinal)
onPreferenceClickListener?.onPreferenceClick(this)
}
R.id.rb_45s -> {
Log.d(TAG, "--- onCheckedChanged 45s--- ")
extras.putInt(KEY_BUNDLE_CURRENT_INTERVAL, Interval.FORTY_FIVE_SECOND.ordinal)
onPreferenceClickListener?.onPreferenceClick(this)
}
R.id.rb_never -> {
Log.d(TAG, "--- onCheckedChanged never--- ")
extras.putInt(KEY_BUNDLE_CURRENT_INTERVAL, Interval.NEVER.ordinal)
onPreferenceClickListener?.onPreferenceClick(this)
}
}
}
}

View File

@@ -0,0 +1,56 @@
package com.mogo.eagle.core.function.hmi.ui.operate.preferences
import android.content.Context
import android.text.TextUtils
import android.util.AttributeSet
import android.widget.EditText
import androidx.core.widget.doOnTextChanged
import androidx.preference.Preference
import androidx.preference.PreferenceViewHolder
import com.mogo.eagle.core.function.hmi.R
import com.mogo.eagle.core.utilcode.kotlin.onClick
class PreferenceWithWelcomeWords: Preference {
companion object {
const val KEY_BUNDLE_CURRENT_EDIT_TEXT_VALUE = "key_bundle_current_edit_text"
}
constructor(context: Context, attrs: AttributeSet?, defStyleAttr: Int, defStyleRes: Int) : super(context, attrs, defStyleAttr, defStyleRes)
constructor(context: Context, attrs: AttributeSet?, defStyleAttr: Int) : super(context, attrs, defStyleAttr)
constructor(context: Context, attrs: AttributeSet?) : super(context, attrs)
constructor(context: Context) : super(context)
private var mCurrentWelcomeWords: String? = null
override fun setDefaultValue(defaultValue: Any?) {
super.setDefaultValue(defaultValue)
if (defaultValue is String) {
mCurrentWelcomeWords = defaultValue
notifyChanged()
}
}
override fun onBindViewHolder(holder: PreferenceViewHolder) {
super.onBindViewHolder(holder)
val currentWelcomeWords = mCurrentWelcomeWords
val et = holder.findViewById(R.id.et_welcome_words) as? EditText
val btn_ok = holder.findViewById(R.id.bt_ok)
btn_ok.isEnabled = false
et?.doOnTextChanged { text, _, _, _ ->
if (!TextUtils.isEmpty(text)) {
btn_ok?.isEnabled = true
} else {
btn_ok?.isEnabled = false
}
}
if (!TextUtils.isEmpty(currentWelcomeWords)) {
et?.setText(currentWelcomeWords)
}
btn_ok.onClick {
extras.putString(KEY_BUNDLE_CURRENT_EDIT_TEXT_VALUE, et?.text.toString())
onPreferenceClickListener?.onPreferenceClick(this)
}
}
}

View File

@@ -143,21 +143,21 @@ internal class SOPSettingView @JvmOverloads constructor(
*/
private fun v2xSetting() {
//V2X总开关
scV2XSwitch.isChecked = FunctionBuildConfig.v2xMainSwitch
scV2XSwitch.isChecked = FunctionBuildConfig.v2xTotalSwitch
scV2XSwitch.setOnCheckedChangeListener { _, isChecked ->
FunctionBuildConfig.v2xMainSwitch = isChecked
FunctionBuildConfig.v2xTotalSwitch = isChecked
hmiAction("SOP V2X总开关, ", isChecked)
clickEventAnalytics("V2X总开关",isChecked)
if (isChecked) {
//V2N总开关
scV2NSwitch.isChecked = FunctionBuildConfig.v2nMainSwitch
hmiAction("SOP V2N总开关, ", FunctionBuildConfig.v2nMainSwitch)
scV2NSwitch.isChecked = FunctionBuildConfig.v2nTotalSwitch
hmiAction("SOP V2N总开关, ", FunctionBuildConfig.v2nTotalSwitch)
//V2I总开关
scV2ISwitch.isChecked = HmiBuildConfig.isShowObuV2iView
hmiAction("SOP V2I总开关, ", HmiBuildConfig.isShowObuV2iView)
scV2ISwitch.isChecked = HmiBuildConfig.v2iTotalSwitch
hmiAction("SOP V2I总开关, ", HmiBuildConfig.v2iTotalSwitch)
//V2V总开关
scObuV2vView.isChecked = HmiBuildConfig.isShowObuV2vView
hmiAction("SOP V2V总开关, ", HmiBuildConfig.isShowObuV2vView)
scObuV2vView.isChecked = HmiBuildConfig.v2vTotalSwitch
hmiAction("SOP V2V总开关, ", HmiBuildConfig.v2vTotalSwitch)
//obu总开关
scObu.isChecked = obuConnectStatus
hmiAction("SOP obu总开关, ", obuConnectStatus)
@@ -187,24 +187,24 @@ internal class SOPSettingView @JvmOverloads constructor(
}
//V2N总开关
scV2NSwitch.isChecked = FunctionBuildConfig.v2nMainSwitch
scV2NSwitch.isChecked = FunctionBuildConfig.v2nTotalSwitch
//根据V2N状态设置子开关是否可以点击
//V2N新链路
scNewV2NData.isEnabled = FunctionBuildConfig.v2nMainSwitch
scNewV2NData.isEnabled = FunctionBuildConfig.v2nTotalSwitch
//V2N场景进PNC
scV2nPnc.isEnabled = FunctionBuildConfig.v2nMainSwitch
scV2nPnc.isEnabled = FunctionBuildConfig.v2nTotalSwitch
//绿波通行(默认关闭)
scGreenWaveSop.isEnabled = FunctionBuildConfig.v2nMainSwitch
scGreenWaveSop.isEnabled = FunctionBuildConfig.v2nTotalSwitch
scV2NSwitch.setOnCheckedChangeListener { compoundButton, isChecked ->
clickEventAnalytics("V2N总开关",isChecked)
if (isChecked) {
//V2N新链路
scNewV2NData.isChecked = FunctionBuildConfig.isNewV2NData
hmiAction("SOP 是否是V2N新链路(云->工控机->App)", FunctionBuildConfig.isNewV2NData)
scNewV2NData.isChecked = FunctionBuildConfig.v2nNewLinked
hmiAction("SOP 是否是V2N新链路(云->工控机->App)", FunctionBuildConfig.v2nNewLinked)
//V2N场景进PNC
scV2nPnc.isChecked = FunctionBuildConfig.isV2NPnc
hmiAction("SOP V2N场景进PNC, ", FunctionBuildConfig.isV2NPnc)
CallerAutoPilotControlManager.sendV2nToPncCmd(FunctionBuildConfig.isV2NPnc)
scV2nPnc.isChecked = FunctionBuildConfig.v2nNewLinkedToPNC
hmiAction("SOP V2N场景进PNC, ", FunctionBuildConfig.v2nNewLinkedToPNC)
CallerAutoPilotControlManager.sendV2nToPncCmd(FunctionBuildConfig.v2nNewLinkedToPNC)
//绿波通行
scGreenWaveSop.isChecked = HmiBuildConfig.isShowGreenWaveView
hmiAction("SOP obu绿波通行, ", HmiBuildConfig.isShowGreenWaveView)
@@ -234,37 +234,37 @@ internal class SOPSettingView @JvmOverloads constructor(
if (!compoundButton.isPressed) {
return@setOnCheckedChangeListener
}
FunctionBuildConfig.v2nMainSwitch = isChecked
FunctionBuildConfig.v2nTotalSwitch = isChecked
val map = HashMap<String, Boolean>().also {
it["f1"] = isChecked
it["f2"] = FunctionBuildConfig.isNewV2NData
it["f2"] = FunctionBuildConfig.v2nNewLinked
}
CallerTelematicManager.sendMsgToAllClients(TelematicConstant.V2N_NEW_LINK_SWITCH, GsonUtils.toJson(map).toByteArray())
}
//V2I总开关
scV2ISwitch.isChecked = HmiBuildConfig.isShowObuV2iView //是否展示obu的v2i
scV2ISwitch.isChecked = HmiBuildConfig.v2iTotalSwitch //是否展示obu的v2i
//根据V2I状态设置子开关是否可以点击
scV2iPnc.isEnabled = HmiBuildConfig.isShowObuV2iView
scRunRedLightSop.isEnabled = HmiBuildConfig.isShowObuV2iView
scObuWeaknessTrafficSop.isEnabled = HmiBuildConfig.isShowObuV2iView
scV2iPnc.isEnabled = HmiBuildConfig.v2iTotalSwitch
scRunRedLightSop.isEnabled = HmiBuildConfig.v2iTotalSwitch
scObuWeaknessTrafficSop.isEnabled = HmiBuildConfig.v2iTotalSwitch
scV2ISwitch.setOnCheckedChangeListener { compoundButton, isChecked ->
clickEventAnalytics("V2I总开关",isChecked)
if (isChecked) {
//V2I场景进PNC
scV2iPnc.isChecked = FunctionBuildConfig.isV2IPnc
hmiAction("SOP V2I场景进PNC, ", FunctionBuildConfig.isV2IPnc)
CallerAutoPilotControlManager.sendV2iToPncCmd(FunctionBuildConfig.isV2IPnc)
scV2iPnc.isChecked = FunctionBuildConfig.v2iToPNC
hmiAction("SOP V2I场景进PNC, ", FunctionBuildConfig.v2iToPNC)
CallerAutoPilotControlManager.sendV2iToPncCmd(FunctionBuildConfig.v2iToPNC)
//闯红灯预警
scRunRedLightSop.isChecked = HmiBuildConfig.isShowRunRedLightView
hmiAction("SOP obu闯红灯预警, ", HmiBuildConfig.isShowRunRedLightView)
scRunRedLightSop.isChecked = HmiBuildConfig.v2iRedLightWarning
hmiAction("SOP obu闯红灯预警, ", HmiBuildConfig.v2iRedLightWarning)
CallerTelematicManager.sendMsgToAllClients(
TelematicConstant.OBU_RUNREDLIGHT_WARNING,
"1".toByteArray()
)
//路侧弱势交通参与者
scObuWeaknessTrafficSop.isChecked = HmiBuildConfig.isShowObuWeaknessTrafficView
hmiAction("SOP obu弱势交通控制, ", HmiBuildConfig.isShowObuWeaknessTrafficView)
scObuWeaknessTrafficSop.isChecked = HmiBuildConfig.v2iWeaknessTraffic
hmiAction("SOP obu弱势交通控制, ", HmiBuildConfig.v2iWeaknessTraffic)
} else {
//V2I场景进PNC
scV2iPnc.isChecked = false
@@ -287,28 +287,28 @@ internal class SOPSettingView @JvmOverloads constructor(
if (!compoundButton.isPressed) {
return@setOnCheckedChangeListener
}
HmiBuildConfig.isShowObuV2iView = isChecked
HmiBuildConfig.v2iTotalSwitch = isChecked
}
//V2N新链路
scNewV2NData.isChecked = FunctionBuildConfig.isNewV2NData
scNewV2NData.isChecked = FunctionBuildConfig.v2nNewLinked
scNewV2NData.setOnCheckedChangeListener { compoundButton, isChecked ->
if (!compoundButton.isPressed) {
return@setOnCheckedChangeListener
}
clickEventAnalytics("V2N新链路",isChecked)
hmiAction("SOP 是否是V2N新链路(云->工控机->App)", isChecked)
FunctionBuildConfig.isNewV2NData = isChecked
FunctionBuildConfig.v2nNewLinked = isChecked
val map = HashMap<String, Boolean>().also {
it["f1"] = FunctionBuildConfig.v2nMainSwitch
it["f1"] = FunctionBuildConfig.v2nTotalSwitch
it["f2"] = isChecked
}
CallerTelematicManager.sendMsgToAllClients(TelematicConstant.V2N_NEW_LINK_SWITCH, GsonUtils.toJson(map).toByteArray())
}
//V2N场景进PNC
scV2nPnc.isChecked = FunctionBuildConfig.isV2NPnc
scV2nPnc.isChecked = FunctionBuildConfig.v2nNewLinkedToPNC
scV2nPnc.setOnCheckedChangeListener { compoundButton, isChecked ->
if (!compoundButton.isPressed) {
return@setOnCheckedChangeListener
@@ -316,7 +316,7 @@ internal class SOPSettingView @JvmOverloads constructor(
clickEventAnalytics("V2N场景进PNC",isChecked)
hmiAction("SOP V2N场景进PNC, ", isChecked)
CallerAutoPilotControlManager.sendV2nToPncCmd(isChecked)
FunctionBuildConfig.isV2NPnc = isChecked
FunctionBuildConfig.v2nNewLinkedToPNC = isChecked
}
//绿波通行(默认关闭)
@@ -342,7 +342,7 @@ internal class SOPSettingView @JvmOverloads constructor(
}
//V2I场景进PNC
scV2iPnc.isChecked = FunctionBuildConfig.isV2IPnc
scV2iPnc.isChecked = FunctionBuildConfig.v2iToPNC
scV2iPnc.setOnCheckedChangeListener { compoundButton, isChecked ->
if (!compoundButton.isPressed) {
return@setOnCheckedChangeListener
@@ -350,19 +350,19 @@ internal class SOPSettingView @JvmOverloads constructor(
clickEventAnalytics("V2I场景进PNC",isChecked)
hmiAction("SOP V2I场景进PNC, ", isChecked)
CallerAutoPilotControlManager.sendV2iToPncCmd(isChecked)
FunctionBuildConfig.isV2IPnc = isChecked
FunctionBuildConfig.v2iToPNC = isChecked
}
//闯红灯预警(默认关闭)
scRunRedLightSop.isChecked = HmiBuildConfig.isShowRunRedLightView
scRunRedLightSop.isChecked = HmiBuildConfig.v2iRedLightWarning
scRunRedLightSop.setOnCheckedChangeListener { compoundButton, isChecked ->
if (!compoundButton.isPressed) {
return@setOnCheckedChangeListener
}
clickEventAnalytics("闯红灯预警",isChecked)
hmiAction("SOP obu闯红灯预警, ", isChecked)
HmiBuildConfig.isShowRunRedLightView = isChecked
if (HmiBuildConfig.isShowRunRedLightView) {
HmiBuildConfig.v2iRedLightWarning = isChecked
if (HmiBuildConfig.v2iRedLightWarning) {
CallerTelematicManager.sendMsgToAllClients(
TelematicConstant.OBU_RUNREDLIGHT_WARNING,
"1".toByteArray()
@@ -376,25 +376,25 @@ internal class SOPSettingView @JvmOverloads constructor(
}
//路侧弱势交通参与者(默认开启)
scObuWeaknessTrafficSop.isChecked = HmiBuildConfig.isShowObuWeaknessTrafficView
scObuWeaknessTrafficSop.isChecked = HmiBuildConfig.v2iWeaknessTraffic
scObuWeaknessTrafficSop.setOnCheckedChangeListener { compoundButton, isChecked ->
if (!compoundButton.isPressed) {
return@setOnCheckedChangeListener
}
clickEventAnalytics("路侧弱势交通参与者",isChecked)
hmiAction("SOP obu弱势交通控制, ", isChecked)
HmiBuildConfig.isShowObuWeaknessTrafficView = isChecked
HmiBuildConfig.v2iWeaknessTraffic = isChecked
}
//V2V总开关(默认关闭)
scObuV2vView.isChecked = HmiBuildConfig.isShowObuV2vView
scObuV2vView.isChecked = HmiBuildConfig.v2vTotalSwitch
scObuV2vView.setOnCheckedChangeListener { compoundButton, isChecked ->
if (!compoundButton.isPressed) {
return@setOnCheckedChangeListener
}
clickEventAnalytics("V2V总开关",isChecked)
hmiAction("SOP obuV2V开关, ", isChecked)
HmiBuildConfig.isShowObuV2vView = isChecked
HmiBuildConfig.v2vTotalSwitch = isChecked
}
//obu总开关
@@ -599,7 +599,7 @@ internal class SOPSettingView @JvmOverloads constructor(
scExamControl.isChecked = FunctionBuildConfig.isShowExamWindow
scExamControl.setOnCheckedChangeListener { _, isChecked ->
FunctionBuildConfig.isShowExamWindow = isChecked
CallerDevaToolsManager.showExamControlWindow(this,isChecked)
CallerDevaToolsManager.showExamControlWindow(isChecked)
hmiAction("SOP 考试功能面板, ", isChecked)
clickEventAnalytics("考试功能面板",isChecked)
}

View File

@@ -34,29 +34,24 @@ class StatusSummaryAdapter(private val ctx: Context, var data: ArrayList<StatusS
fun bind(entity: StatusSummaryEntity) {
when(entity.type) {
0 -> {
ivFuncView.setImageResource(R.drawable.driver_server)
ivFuncView.setImageResource(if (entity.isException) R.drawable.icon_over_driver_start_error else R.drawable.icon_over_driver_start_ok)
}
1 -> {
ivFuncView.setImageResource(R.drawable.gps)
ivFuncView.setImageResource(if (entity.isException) R.drawable.icon_over_gps_error else R.drawable.icon_over_gps_ok)
}
2 -> {
ivFuncView.setImageResource(R.drawable.cloud_socket)
ivFuncView.setImageResource(if (entity.isException) R.drawable.icon_over_socket_error else R.drawable.icon_over_socket_ok)
}
3 -> {
ivFuncView.setImageResource(R.drawable.tracing)
ivFuncView.setImageResource(if (entity.isException) R.drawable.icon_over_route_error else R.drawable.icon_over_route_ok)
}
4 -> {
ivFuncView.setImageResource(R.drawable.controller)
ivFuncView.setImageResource(if (entity.isException) R.drawable.icon_over_ipc_error else R.drawable.icon_over_ipc_ok)
}
5 -> {
ivFuncView.setImageResource(R.drawable.ssl_check)
ivFuncView.setImageResource(if (entity.isException) R.drawable.icon_over_auth_error else R.drawable.icon_over_auth_ok)
}
}
if (entity.isException) {
tvStatusDesc.setTextColor(Color.parseColor("#FF4444"))
} else {
tvStatusDesc.setTextColor(Color.parseColor("#FFFFFF"))
}
tvStatusDesc.text = entity.desc
}
}

View File

@@ -32,21 +32,12 @@ import com.mogo.eagle.core.utilcode.kotlin.PX
import com.mogo.eagle.core.utilcode.rv.divider.CommonDividerItemDecoration
import com.mogo.eagle.core.utilcode.util.UiThreadHandler
import com.zhjt.mogo.adas.data.AdasConstants
import me.jessyan.autosize.utils.AutoSizeUtils
/**
* 状态汇总View控件
*/
class StatusSummaryView @JvmOverloads constructor(
context: Context,
attrs: AttributeSet? = null,
defStyleAttr: Int = 0
) : FrameLayout(
context,
attrs,
defStyleAttr
), IConnectStatusListener, IMogoStatusChangedListener,
IMoGoDevaToolsListener, IMoGoAutopilotStatusListener, IMoGoAutopilotCarConfigListener,
IMoGoCloudListener {
class StatusSummaryView @JvmOverloads constructor(context: Context, attrs: AttributeSet? = null, defStyleAttr: Int = 0) : FrameLayout(context, attrs, defStyleAttr), IConnectStatusListener, IMogoStatusChangedListener, IMoGoDevaToolsListener, IMoGoAutopilotStatusListener, IMoGoAutopilotCarConfigListener, IMoGoCloudListener {
companion object {
private const val TAG = "SummaryStatusView"
}
@@ -61,13 +52,7 @@ class StatusSummaryView @JvmOverloads constructor(
it.add(StatusSummaryEntity(2))
it.add(StatusSummaryEntity(3))
it.add(StatusSummaryEntity(4, "域控未连接", true))
it.add(
StatusSummaryEntity(
5,
CallerAutopilotCarConfigListenerManager.getCertFileResult(),
CallerCloudCertManager.getRootCrtF().isNullOrEmpty()
)
)
it.add(StatusSummaryEntity(5, CallerAutopilotCarConfigListenerManager.getCertFileResult(), CallerCloudCertManager.getRootCrtF().isNullOrEmpty()))
}
}
@@ -78,12 +63,9 @@ class StatusSummaryView @JvmOverloads constructor(
override fun onAttachedToWindow() {
super.onAttachedToWindow()
CallerDevaToolsListenerManager.addListener(TAG, this)
// 司机屏Server服务是否开启的状态
CallerTelematicStatusListenerManager.addListener(TAG, this)
// 云socket连接状态
MogoStatusManager.getInstance()
.registerStatusChangedListener(TAG, StatusDescriptor.CLOUD_SOCKET, this)
CallerDevaToolsListenerManager.addListener(TAG, this) // 司机屏Server服务是否开启的状态
CallerTelematicStatusListenerManager.addListener(TAG, this) // 云socket连接状态
MogoStatusManager.getInstance().registerStatusChangedListener(TAG, StatusDescriptor.CLOUD_SOCKET, this)
CallerAutoPilotStatusListenerManager.addListener(TAG, this)
CallerAutopilotCarConfigListenerManager.addListener(TAG, this)
CallerCloudListenerManager.addListener(TAG, this)
@@ -99,12 +81,7 @@ class StatusSummaryView @JvmOverloads constructor(
removeDuration = 0
}
it.layoutManager = LinearLayoutManager(context, LinearLayoutManager.VERTICAL, false)
it.addItemDecoration(
CommonDividerItemDecoration.Builder()
.spanCountTBCare(false)
.horizontalInnerSpace(10.PX)
.build()
)
it.addItemDecoration(CommonDividerItemDecoration.Builder().spanCountTBCare(false).verticalInnerSpace(AutoSizeUtils.dp2px(context, 20.0f)).build())
StatusSummaryAdapter(context, data).apply {
adapter = this
it.adapter = this
@@ -121,13 +98,10 @@ class StatusSummaryView @JvmOverloads constructor(
}
override fun onDetachedFromWindow() {
super.onDetachedFromWindow()
// 司机屏Server服务是否开启的状态
super.onDetachedFromWindow() // 司机屏Server服务是否开启的状态
CallerTelematicStatusListenerManager.removeListener(TAG)
CallerDevaToolsListenerManager.removeListener(TAG)
// 云socket连接状态
MogoStatusManager.getInstance()
.unregisterStatusChangedListener(TAG, StatusDescriptor.CLOUD_SOCKET, this)
CallerDevaToolsListenerManager.removeListener(TAG) // 云socket连接状态
MogoStatusManager.getInstance().unregisterStatusChangedListener(TAG, StatusDescriptor.CLOUD_SOCKET, this)
CallerAutoPilotStatusListenerManager.removeListener(TAG)
CallerAutopilotCarConfigListenerManager.removeListener(TAG)
CallerCloudListenerManager.removeListener(TAG)
@@ -171,8 +145,7 @@ class StatusSummaryView @JvmOverloads constructor(
}
override fun tracingStatus(status: Boolean) {
super.tracingStatus(status)
// 发送事件前限制了频率
super.tracingStatus(status) // 发送事件前限制了频率
UiThreadHandler.post({
if (data.size < 4) return@post
data[3].desc = "寻迹算路${if (status) "正常" else "异常"}"
@@ -181,10 +154,7 @@ class StatusSummaryView @JvmOverloads constructor(
}, UiThreadHandler.MODE.QUEUE)
}
override fun onAutopilotIpcConnectStatusChanged(
status: AdasConstants.IpcConnectionStatus,
reason: String?
) {
override fun onAutopilotIpcConnectStatusChanged(status: AdasConstants.IpcConnectionStatus, reason: String?) {
super.onAutopilotIpcConnectStatusChanged(status, reason)
var pair: Pair<String, Boolean>? = null
when (status) {
@@ -238,8 +208,8 @@ class StatusSummaryView @JvmOverloads constructor(
override fun authCrtFile(device: String, root: String) {
super.authCrtFile(device, root)
UiThreadHandler.post ({
if(CallerAutopilotCarConfigListenerManager.getCertFileResult()!= "未开启认证"){
UiThreadHandler.post({
if (CallerAutopilotCarConfigListenerManager.getCertFileResult() != "未开启认证") {
return@post
}
if (data.size < 6) return@post
@@ -251,7 +221,7 @@ class StatusSummaryView @JvmOverloads constructor(
override fun authCrtError(errorMsg: String) {
super.authCrtError(errorMsg)
UiThreadHandler.post ({
UiThreadHandler.post({
if (data.size < 6) return@post
data[5].desc = "本机证书下载异常:$errorMsg"
data[5].isException = true
@@ -262,14 +232,10 @@ class StatusSummaryView @JvmOverloads constructor(
override fun onCertificationResult(msg: String) {
super.onCertificationResult(msg)
hmiAction("证书验证状态", msg, true)
if (!SharedPrefsMgr.getInstance().getBoolean(
"${MoGoConfig.AUTOPILOT_CERTIFICATION}-${DebugConfig.getNetMode()}",
MoGoConfig.AUTOPILOT_CERTIFICATION_DEFAULT_VALUE
)
) {
if (!SharedPrefsMgr.getInstance().getBoolean("${MoGoConfig.AUTOPILOT_CERTIFICATION}-${DebugConfig.getNetMode()}", MoGoConfig.AUTOPILOT_CERTIFICATION_DEFAULT_VALUE)) {
return
}
UiThreadHandler.post ({
UiThreadHandler.post({
if (data.size < 6) return@post
data[5].desc = msg
data[5].isException = !msg.contains("成功校验")

View File

@@ -15,7 +15,6 @@ import com.mogo.eagle.core.function.angle.scenes.Default
import com.mogo.eagle.core.function.angle.scenes.LongSight
import com.mogo.eagle.core.function.api.map.angle.IMoGoVisualAngleChangeProvider
import com.mogo.eagle.core.function.api.map.angle.Scene
import com.mogo.eagle.core.function.call.hmi.CallerHmiManager
import com.mogo.eagle.core.function.call.map.CallerVisualAngleManager
import com.mogo.eagle.core.function.hmi.R
import com.mogo.eagle.core.utilcode.kotlin.scope
@@ -85,8 +84,6 @@ class VisualAngleToggleView : FrameLayout, IMoGoVisualAngleChangeProvider.OnMoGo
override fun onAnimationEnd(animation: Animator, isReverse: Boolean) {
super.onAnimationEnd(animation, isReverse)
iv_toggle_block?.isEnabled = true
//TODO renwj
CallerHmiManager.toggleOperatePanel(false)
}
})
animator.interpolator = AccelerateDecelerateInterpolator()
@@ -114,8 +111,6 @@ class VisualAngleToggleView : FrameLayout, IMoGoVisualAngleChangeProvider.OnMoGo
override fun onAnimationEnd(animation: Animator, isReverse: Boolean) {
iv_toggle_block?.isEnabled = true
//TODO renwj
CallerHmiManager.toggleOperatePanel(true)
}
})
animator.interpolator = AccelerateDecelerateInterpolator()

View File

@@ -0,0 +1,120 @@
package com.mogo.eagle.core.function.hmi.ui.widget;
import android.content.Context;
import android.util.AttributeSet;
import android.view.View;
import android.widget.RadioGroup;
public class WrapRadioGroup extends RadioGroup {
public WrapRadioGroup(Context context) {
super(context);
}
public WrapRadioGroup(Context context, AttributeSet attrs) {
super(context, attrs);
}
@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
int widthSize = MeasureSpec.getSize(widthMeasureSpec);
int widthMode = MeasureSpec.getMode(widthMeasureSpec);
int heightSize = MeasureSpec.getSize(heightMeasureSpec);
int heightMode = MeasureSpec.getMode(heightMeasureSpec);
//调用ViewGroup的方法测量子view
measureChildren(widthMeasureSpec, heightMeasureSpec);
//最大的宽
int maxWidth = 0;
//累计的高
int totalHeight = 0;
//当前这一行的累计行宽
int lineWidth = 0;
//当前这行的最大行高
int maxLineHeight = 0;
//用于记录换行前的行宽和行高
int oldHeight;
int oldWidth;
int count = getChildCount();
//假设 widthMode和heightMode都是AT_MOST
for (int i = 0; i < count; i++) {
View child = getChildAt(i);
MarginLayoutParams params = (MarginLayoutParams) child.getLayoutParams();
//得到这一行的最高
oldHeight = maxLineHeight;
//当前最大宽度
oldWidth = maxWidth;
int deltaX = child.getMeasuredWidth() + params.leftMargin + params.rightMargin;
if (lineWidth + deltaX + getPaddingLeft() + getPaddingRight() > widthSize) {//如果折行,height增加
//和目前最大的宽度比较,得到最宽。不能加上当前的child的宽,所以用的是oldWidth
maxWidth = Math.max(lineWidth, oldWidth);
//重置宽度
lineWidth = deltaX;
//累加高度
totalHeight += oldHeight;
//重置行高,当前这个View属于下一行因此当前最大行高为这个child的高度加上margin
maxLineHeight = child.getMeasuredHeight() + params.topMargin + params.bottomMargin;
// Log.v(TAG, "maxHeight:" + totalHeight + "---" + "maxWidth:" + maxWidth);
} else {
//不换行,累加宽度
lineWidth += deltaX;
//不换行,计算行最高
int deltaY = child.getMeasuredHeight() + params.topMargin + params.bottomMargin;
maxLineHeight = Math.max(maxLineHeight, deltaY);
}
if (i == count - 1) {
//前面没有加上下一行的搞,如果是最后一行,还要再叠加上最后一行的最高的值
totalHeight += maxLineHeight;
//计算最后一行和前面的最宽的一行比较
maxWidth = Math.max(lineWidth, oldWidth);
}
}
//加上当前容器的padding值
maxWidth += getPaddingLeft() + getPaddingRight();
totalHeight += getPaddingTop() + getPaddingBottom();
setMeasuredDimension(widthMode == MeasureSpec.EXACTLY ? widthSize : maxWidth,
heightMode == MeasureSpec.EXACTLY ? heightSize : totalHeight);
}
@Override
protected void onLayout(boolean changed, int l, int t, int r, int b) {
int count = getChildCount();
//pre为前面所有的child的相加后的位置
int preLeft = getPaddingLeft();
int preTop = getPaddingTop();
//记录每一行的最高值
int maxHeight = 0;
for (int i = 0; i < count; i++) {
View child = getChildAt(i);
MarginLayoutParams params = (MarginLayoutParams) child.getLayoutParams();
//r-l为当前容器的宽度。如果子view的累积宽度大于容器宽度就换行。
if (preLeft + params.leftMargin + child.getMeasuredWidth() + params.rightMargin + getPaddingRight() > (r - l)) {
//重置
preLeft = getPaddingLeft();
//要选择child的height最大的作为设置
preTop = preTop + maxHeight;
maxHeight = getChildAt(i).getMeasuredHeight() + params.topMargin + params.bottomMargin;
} else { //不换行,计算最大高度
maxHeight = Math.max(maxHeight, child.getMeasuredHeight() + params.topMargin + params.bottomMargin);
}
//left坐标
int left = preLeft + params.leftMargin;
//top坐标
int top = preTop + params.topMargin;
int right = left + child.getMeasuredWidth();
int bottom = top + child.getMeasuredHeight();
//为子view布局
child.layout(left, top, right, bottom);
//计算布局结束后preLeft的值
preLeft += params.leftMargin + child.getMeasuredWidth() + params.rightMargin;
}
}
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.6 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 38 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 192 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 537 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 346 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 727 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.0 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.4 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.0 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 472 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 24 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.7 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 17 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 32 KiB

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