[8.0.0]RoadV2N事件进MogoMind

This commit is contained in:
xuxinchao
2025-04-28 15:37:05 +08:00
parent fe6278bfa4
commit b38fabdb63
8 changed files with 272 additions and 18 deletions

View File

@@ -55,6 +55,7 @@ class AiView @JvmOverloads constructor(
private var viewModel:AIViewModel?=null
private var pncActionsModel:PNCActionsViewModel ?= null
private var roadV2NEventModel:RoadV2NEventViewModel ?= null
private var aiAnimator: BigFrameAnimatorContainer?=null
private var aiAnimatorBg: BigFrameAnimatorContainer?=null
@@ -236,6 +237,10 @@ class AiView @JvmOverloads constructor(
ViewModelProvider(it)[PNCActionsViewModel::class.java]
}
pncActionsModel?.init()
roadV2NEventModel = findViewTreeViewModelStoreOwner()?.let{
ViewModelProvider(it)[RoadV2NEventViewModel::class.java]
}
roadV2NEventModel?.init()
}
private fun startListInfo(){

View File

@@ -0,0 +1,73 @@
package com.mogo.och.unmanned.passenger.ui.aiview
import androidx.lifecycle.ProcessLifecycleOwner
import androidx.lifecycle.ViewModel
import androidx.lifecycle.lifecycleScope
import com.mogo.commons.utils.MogoAnalyticUtils
import com.mogo.eagle.core.data.v2x.RoadV2NEventWindowBean
import com.mogo.eagle.core.function.api.hmi.v2n.IRoadV2NEventWindowListener
import com.mogo.eagle.core.function.call.autopilot.CallerAutoPilotStatusListenerManager
import com.mogo.eagle.core.function.call.hmi.CallerHmiViewControlListenerManager
import com.mogo.eagle.core.function.call.hmi.CallerRoadV2NEventWindowListenerManager
import com.mogo.eagle.core.function.hmi.ui.utils.HmiActionLog
import com.mogo.eagle.core.utilcode.mogo.logger.CallerLogger
import com.mogo.och.unmanned.passenger.ui.aiview.bean.AIMessage
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.launch
class RoadV2NEventViewModel: ViewModel(), IRoadV2NEventWindowListener {
companion object{
const val TAG = "RoadV2NEventViewModel"
const val ANALYTICS_KEY = "hmi_road_event_window_view"
fun trackEvent(msg: String) {
ProcessLifecycleOwner.get().lifecycleScope.launch(Dispatchers.IO) {
val map: MutableMap<String, Any> = HashMap()
map["msg"] = msg
MogoAnalyticUtils.track(
ANALYTICS_KEY,
map
)
HmiActionLog.hmiAction(TAG, msg)
}
CallerLogger.i(TAG, msg)
}
}
fun init(){
CallerRoadV2NEventWindowListenerManager.addListener(TAG, this)
}
override fun show(dataBean: RoadV2NEventWindowBean) {
trackEvent("show --> $dataBean")
val canShowV2NEventWindowView = CallerHmiViewControlListenerManager.getMainPageVisible()
if (!canShowV2NEventWindowView) {
trackEvent("show --> 当前不在高精地图页面,跳过")
return
}
val lineId = CallerAutoPilotStatusListenerManager.getLineId()
if (lineId <= 0) {
trackEvent("show --> 当前无订单,跳过")
return
}
val event = AIMessage.RoadV2NEvent(
dataBean.eventId,
dataBean.hintStr,
dataBean.ttsStr,
dataBean.eventType,
dataBean.timestamp,
dataBean.iconResId,
dataBean.isNeedTTS,
dataBean.contentImageUrl,
dataBean.cameraIp,
dataBean.lon,
dataBean.lat
)
AIMessageManager.post(event)
}
override fun dismiss(eventId: String) {
}
}

View File

@@ -21,6 +21,7 @@ class AIMessageAdapter : ListAdapter<AIMessage, MessageViewHolder>(MessageDiffCa
return when (viewType) {
AIMessage.TYPE_QA -> QAViewHolder(inflater.inflate(R.layout.item_ai_msg_qa, parent, false))
AIMessage.TYPE_PNC_ACTION -> PNCActionViewHolder(inflater.inflate(R.layout.item_ai_pnc_action,parent,false))
AIMessage.TYPE_ROAD_V2N -> RoadV2NEventViewHolder(inflater.inflate(R.layout.item_ai_road_v2n_event,parent,false))
else -> throw IllegalArgumentException("Invalid view type")
}
}
@@ -34,6 +35,7 @@ class AIMessageAdapter : ListAdapter<AIMessage, MessageViewHolder>(MessageDiffCa
is AIMessage.Speed -> AIMessage.TYPE_SPEED
is AIMessage.Warning -> AIMessage.TYPE_WARNING
is AIMessage.PNCAction -> AIMessage.TYPE_PNC_ACTION
is AIMessage.RoadV2NEvent -> AIMessage.TYPE_ROAD_V2N
else -> AIMessage.TYPE_EVENT
}
}

View File

@@ -1,16 +1,29 @@
package com.mogo.och.unmanned.passenger.ui.aiview.adapter
import android.animation.ObjectAnimator
import android.text.TextUtils
import android.util.Log
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import android.widget.FrameLayout
import android.widget.ImageView
import android.widget.LinearLayout
import android.widget.RelativeLayout
import android.widget.TextView
import androidx.constraintlayout.widget.ConstraintLayout
import androidx.core.content.ContextCompat
import androidx.core.graphics.toColorInt
import androidx.recyclerview.widget.RecyclerView
import com.bumptech.glide.Glide
import com.mogo.commons.voice.AIAssist
import com.mogo.eagle.core.data.v2x.RoadV2NEventType
import com.mogo.eagle.core.function.call.autopilot.CallerChassisLocationWGS84ListenerManager
import com.mogo.eagle.core.function.hmi.ui.v2n.RoadV2NEventLivePlayView
import com.mogo.eagle.core.utilcode.mogo.glide.GlideImageLoader
import com.mogo.eagle.core.utilcode.mogo.imageloader.MogoImageView
import com.mogo.eagle.core.utilcode.util.DateTimeUtils
import com.mogo.eagle.core.widget.RoundConstraintLayout
import com.mogo.och.common.module.wigets.OchRoundImageView
import com.mogo.och.unmanned.passenger.ui.aiview.bean.AIMessage
import com.mogo.och.unmanned.taxi.passenger.R
@@ -159,7 +172,7 @@ class QAViewHolder(val binding: View) : MessageViewHolder(binding) {
}
}
class PNCActionViewHolder(val binding: View) : MessageViewHolder(binding){
class PNCActionViewHolder(binding: View) : MessageViewHolder(binding){
private var tvPncAction: TextView = binding.findViewById(R.id.tvPncAction)
@@ -169,6 +182,60 @@ class PNCActionViewHolder(val binding: View) : MessageViewHolder(binding){
}
class RoadV2NEventViewHolder(binding: View) : MessageViewHolder(binding){
private var ivV2XImage: ImageView = binding.findViewById(R.id.ivV2XImage)
private var tvV2XHintContent: TextView = binding.findViewById(R.id.tvV2XHintContent)
private var containerImageAndLiveVideo: FrameLayout = binding.findViewById(R.id.containerImageAndLiveVideo)
private var livePlayView: RoadV2NEventLivePlayView = binding.findViewById(R.id.livePlayView)
private var contentImageView: MogoImageView = binding.findViewById(R.id.contentImageView)
private var tvV2XTimeStr: TextView = binding.findViewById(R.id.tvV2XTimeStr)
override fun bind(item: AIMessage, onItemClickListener: OnItemClickListener?) {
if(item is AIMessage.RoadV2NEvent){
ivV2XImage.setImageDrawable(ContextCompat.getDrawable(itemView.context, item.iconResId))
tvV2XHintContent.text = item.title
tvV2XTimeStr.text =
"更新时间:${DateTimeUtils.getTimeText(item.timeStamp, DateTimeUtils.HH_mm_ss)}"
if (item.isNeedTTS && !TextUtils.isEmpty(item.tts)) {
AIAssist.getInstance(itemView.context)
.speakTTSVoiceWithLevel(item.tts, AIAssist.NEW_LEVEL_2)
}
when (item.eventType) {
RoadV2NEventType.TEXT -> {
containerImageAndLiveVideo.visibility = View.GONE
contentImageView.visibility = View.GONE
livePlayView.visibility = View.GONE
}
RoadV2NEventType.IMAGE -> {
containerImageAndLiveVideo.visibility = View.VISIBLE
contentImageView.visibility = View.VISIBLE
livePlayView.visibility = View.GONE
GlideImageLoader.getInstance()
.displayImage(item.contentImageUrl, contentImageView)
}
RoadV2NEventType.LIVE_VIDEO -> {
containerImageAndLiveVideo.visibility = View.VISIBLE
contentImageView.visibility = View.GONE
livePlayView.visibility = View.VISIBLE
val cityCode =
CallerChassisLocationWGS84ListenerManager.getChassisLocationWGS84().cityCode
livePlayView.startRoadCameraLive(
item.id,
item.cameraIp, item.lon, item.lat, cityCode
)
}
}
}
}
}
fun interface OnItemClickListener {
fun onItemClick(item: AIMessage, position: Int)

View File

@@ -2,6 +2,7 @@ package com.mogo.och.unmanned.passenger.ui.aiview.bean
import android.os.CountDownTimer
import android.util.Log
import com.mogo.eagle.core.data.v2x.RoadV2NEventType
import kotlin.math.floor
@@ -21,6 +22,7 @@ sealed class AIMessage(
const val TYPE_SPEED = 4
const val TYPE_WARNING = 5
const val TYPE_PNC_ACTION = 6
const val TYPE_ROAD_V2N = 7
}
data class Scan(
@@ -132,4 +134,18 @@ sealed class AIMessage(
override val title: String
): AIMessage(id,title)
data class RoadV2NEvent(
override val id: String,
override val title: String,
override val tts: String = "", //TTS的文案
var eventType: RoadV2NEventType, //事件弹框类型
var timeStamp: Long = 0, //事件发生事件戳
var iconResId: Int, //事件icon res id
var isNeedTTS: Boolean = false, //事件文案是否需要同步tts
var contentImageUrl: String, // Image 类型时图片 url
var cameraIp: String, // 路侧camera ip,用于请求获取拉流地址
var lon: Double, //事件坐标-经度
var lat: Double, //事件坐标-纬度
):AIMessage(id,title,tts)
}

View File

@@ -0,0 +1,107 @@
<?xml version="1.0" encoding="utf-8"?>
<com.mogo.eagle.core.widget.RoundConstraintLayout 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:id="@+id/roundRoadV2NEventContainer"
android:layout_width="@dimen/dp_747"
android:layout_height="wrap_content"
android:background="@drawable/hmi_v2n_event_bg_passenger"
android:padding="@dimen/dp_37">
<androidx.constraintlayout.widget.ConstraintLayout
android:id="@+id/containerEventContent"
android:layout_width="match_parent"
android:layout_height="wrap_content"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintTop_toTopOf="parent">
<RelativeLayout
android:id="@+id/containerIconHint"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginLeft="@dimen/dp_50"
android:layout_marginTop="@dimen/dp_40"
android:layout_marginRight="@dimen/dp_50"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintTop_toTopOf="parent">
<!-- 这个icon实际切图时带了阴影实际上下左右margin需要根据实际情况减去-->
<ImageView
android:id="@+id/ivV2XImage"
android:layout_width="@dimen/dp_69"
android:layout_height="@dimen/dp_69"
android:layout_alignParentStart="true"
android:layout_centerVertical="true"
android:scaleType="fitXY"
tools:src="@drawable/icon_v2x_bus_station_passenger" />
<TextView
android:id="@+id/tvV2XHintContent"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginLeft="@dimen/dp_30"
android:layout_marginRight="@dimen/dp_10"
android:layout_toRightOf="@+id/ivV2XImage"
android:ellipsize="end"
android:gravity="start|top"
android:maxLines="1"
android:textColor="#131415"
android:textSize="@dimen/dp_32"
android:textStyle="bold"
tools:text="前方150米 道路施工 前方150米 道路施工 前方150米 道路施工" />
</RelativeLayout>
<FrameLayout
android:id="@+id/containerImageAndLiveVideo"
android:layout_width="@dimen/dp_498"
android:layout_height="@dimen/dp_298"
android:layout_marginLeft="@dimen/dp_51"
android:layout_marginTop="@dimen/dp_24"
android:layout_marginRight="@dimen/dp_51"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintTop_toBottomOf="@id/containerIconHint">
<com.mogo.eagle.core.function.hmi.ui.v2n.RoadV2NEventLivePlayView
android:id="@+id/livePlayView"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:visibility="visible"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintTop_toTopOf="parent" />
<com.mogo.eagle.core.utilcode.mogo.imageloader.MogoImageView
android:id="@+id/contentImageView"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:scaleType="fitXY"
android:visibility="visible"
app:miv_radius="@dimen/dp_16"
app:miv_shape="round"
tools:src="@drawable/bg_v2x_bus_station" />
</FrameLayout>
<TextView
android:id="@+id/tvV2XTimeStr"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginLeft="@dimen/dp_51"
android:layout_marginTop="@dimen/dp_20"
android:layout_marginRight="@dimen/dp_51"
android:layout_marginBottom="@dimen/dp_33"
android:ellipsize="end"
android:gravity="start"
android:maxLines="1"
android:textColor="#131415"
android:textSize="@dimen/dp_24"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintTop_toBottomOf="@id/containerImageAndLiveVideo"
tools:text="更新时间10:38:20" />
</androidx.constraintlayout.widget.ConstraintLayout>
</com.mogo.eagle.core.widget.RoundConstraintLayout>

View File

@@ -222,18 +222,6 @@
android:layout_width="match_parent"
android:layout_height="match_parent"/>
<!-- 事件弹框 -->
<com.mogo.eagle.core.function.hmi.ui.v2n.RoadV2NEventWindowView
android:id="@+id/roadV2NEventWindowView"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginBottom="-100dp"
app:layout_constraintBottom_toTopOf="@+id/bottom"
app:layout_constraintRight_toRightOf="parent"
android:visibility="gone"/>
<!--气泡态消息盒子-->
<com.mogo.eagle.core.function.hmi.ui.msgbox.PassengerMsgBoxBubbleView
android:id="@+id/pmbb_info"

View File

@@ -35,7 +35,6 @@ import com.mogo.eagle.core.function.call.msgbox.CallerMsgBoxManager.saveMsgBox
import com.mogo.eagle.core.utilcode.mogo.AppIdentityModeUtils
import com.mogo.eagle.core.utilcode.mogo.logger.CallerLogger
import com.mogo.eagle.core.utilcode.mogo.logger.Logger
import com.mogo.eagle.core.utilcode.util.AppStateManager
import com.mogo.eagle.core.utilcode.util.CoordinateTransform
import com.mogo.eagle.core.utilcode.util.CoordinateUtils
import com.mogo.eagle.core.utilcode.util.DrivingDirectionUtils
@@ -193,10 +192,7 @@ internal object V2NIdentifyDrawer : IEventDismissListener {
val contentType =
if (poiType == EventTypeEnumNew.TYPE_SOCKET_ROAD_SHIGONG.poiType) "道路施工" else "道路事故"
val content = "前方${distance.toInt()}米有$contentType"
val tts = "${
SkinResources.getInstance()
.getString(R.string.operation_platform_name)
}发现前方$contentType, 提醒您注意行人及来车"
val tts = "注意行人及来车"
V2XBizTrace.onAck(TAG, "绘制poi事件:$poiType")
saveMsgBox(
MsgBoxBean(