Merge branch 'dev_robotaxi-d_250117_6.10.0' into dev_robotaxi-d_241210_6.10.0_yyk

This commit is contained in:
yangyakun
2025-02-06 09:41:45 +08:00
23 changed files with 649 additions and 77 deletions

View File

@@ -205,7 +205,7 @@ class DevaToolsProvider : IDevaToolsProvider, IAppStateListener {
// apmEnvProvider.init(if(DebugConfig.isDebug()) "0" else "1", "${ DebugConfig.getNetMode() }", mDockerVersion ?: "")
BadCaseManager.init(mContext!!)
ColdStartManager.init(mContext!!)
// OTAUpgradeManager.init(mContext!!)
OTAUpgradeManager.init(mContext!!)
if (DebugConfig.isDebug()) {
SdtManager.init(mContext!!, true, DetectResultImpl())
}

View File

@@ -156,6 +156,10 @@ internal object BadCaseManager : LifecycleEventObserver, IMoGoAutopilotRecordLis
BadCaseConfig.setStartTime(currentDay)
//删除前一天的接管记录
CallerTakeOverManager.deleteAllRecord(context)
//遍历是否有非当日的文件并删除
RecordBitmapUtils.deleteExpiredFile(currentDay,"FrontCamera")
RecordBitmapUtils.deleteExpiredFile(currentDay,"RearCamera")
RecordBitmapUtils.deleteExpiredFile(currentDay,"MapScreen")
}
}
@@ -417,7 +421,6 @@ internal object BadCaseManager : LifecycleEventObserver, IMoGoAutopilotRecordLis
override fun onAutopilotRecordResult(recordPanel: RecordPanelOuterClass.RecordPanel) {
super.onAutopilotRecordResult(recordPanel)
CallerLogger.d("$M_DEVA$TAG", "recordKey=${recordPanel.key},stat=${recordPanel.stat},type=${recordPanel.type}")
CallerLogger.i(TestTag,"onAutopilotRecordResult receive recordKey=${recordPanel.key},stat=${recordPanel.stat},type=${recordPanel.type},lineName=${BadCaseConfig.lineName}")
if(BadCaseConfig.notDisplayBagWindow){
//此时点击主动录包按钮,不能展示上报弹窗,需要在此处做主动录包弹窗中的一些逻辑
//开始录制
@@ -441,22 +444,18 @@ internal object BadCaseManager : LifecycleEventObserver, IMoGoAutopilotRecordLis
CallerLogger.i(TestTag,"onAutopilotRecordResult contains recordKey=${recordPanel.key},stat=${recordPanel.stat},type=${recordPanel.type},lineName=${BadCaseConfig.lineName}")
//目前type == 3包括接管被动录包和其他一些故障录包
if(recordPanel.type == 3){
CallerLogger.i(TestTag,"onAutopilotRecordResult 符合type=3 recordKey=${recordPanel.key},stat=${recordPanel.stat},type=${recordPanel.type},lineName=${BadCaseConfig.lineName}")
//录包成功
if(recordPanel.stat == 100 || recordPanel.stat == 101){
CallerLogger.i(TestTag,"onAutopilotRecordResult 录包成功 recordKey=${recordPanel.key},stat=${recordPanel.stat},type=${recordPanel.type},lineName=${BadCaseConfig.lineName}")
val activity = AppStateManager.currentActivity()
if (activity !is AppCompatActivity) {
return
}
CallerLogger.i(TestTag,"activity符合条件")
val geocodeSearch = GeocodeSearch(activity)
geocodeSearch.setOnGeocodeSearchListener(object: GeocodeSearch.OnGeocodeSearchListener {
override fun onRegeocodeSearched(regeocodeResult: RegeocodeResult?, p1: Int) {
regeocodeResult?.regeocodeAddress?.formatAddress?.let {
address = it
}
CallerLogger.i(TestTag,"onRegeocodeSearched address=${address}")
val takeOverRecordInfo = TakeOverRecordInfo(System.currentTimeMillis(),
address,level1Id,level2Id,level3Id,
level1Name, level2Name, level3Name,
@@ -477,12 +476,12 @@ internal object BadCaseManager : LifecycleEventObserver, IMoGoAutopilotRecordLis
val q = RegeocodeQuery(latLon,200f,GeocodeSearch.AMAP)
geocodeSearch.getFromLocationAsyn(q)
takeOverBagId = recordPanel.key
// //触发域控前后120度摄像头截图和高精地图截图
// CallerAutoPilotControlManager.sendCaptureImgReqOnTakeOver(recordPanel.key)
// //高精地图屏幕截图
// CallerMapScreenListenerManager.addListener(TAG,this)
// //开启高精地图截图
// CallerMapUIServiceManager.getMapUIController()?.getMapScreenShot()
//触发域控前后120度摄像头截图和高精地图截图
CallerAutoPilotControlManager.sendCaptureImgReqOnTakeOver(recordPanel.key)
//高精地图屏幕截图
CallerMapScreenListenerManager.addListener(TAG,this)
//开启高精地图截图
CallerMapUIServiceManager.getMapUIController()?.getMapScreenShot()
}
}
}

View File

@@ -36,9 +36,11 @@ object RecordBitmapUtils {
/**
* 删除过期文件夹
* @param currentDay 要删除的文件日期
* @param deleteFile 要删除的文件目录
*/
fun deleteExpiredFile(currentDay: String){
val checkFileName = Environment.getExternalStorageDirectory().absolutePath + File.separator+ "MapScreen"
fun deleteExpiredFile(currentDay: String,deleteFile: String){
val checkFileName = Environment.getExternalStorageDirectory().absolutePath + File.separator+ deleteFile
val checkFileFolder = File(checkFileName)
if(checkFileFolder.exists()){
checkFileFolder.listFiles()?.forEach {dir->

View File

@@ -3,7 +3,9 @@ package com.zhjt.mogo_core_function_devatools.workorder
import android.annotation.SuppressLint
import android.app.Activity
import android.graphics.PixelFormat
import android.net.Uri
import android.os.Bundle
import android.os.Environment
import android.text.Editable
import android.text.TextWatcher
import android.util.DisplayMetrics
@@ -41,13 +43,15 @@ import com.mogo.eagle.core.utilcode.util.BarUtils
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.getMdFormat
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.R
import com.zhjt.mogo_core_function_devatools.badcase.consts.BadCaseConfig
import com.zhjt.mogo_core_function_devatools.workorder.adapter.OrderReasonAdapter
import kotlin.math.absoluteValue
import java.io.File
/**
* 接管原因编辑窗口
@@ -63,11 +67,7 @@ class TakeOverReasonWindow constructor(activity: Activity) : View.OnTouchListene
private var mWindowParams: WindowManager.LayoutParams? = null
private var mWindowManager: WindowManager? = null
private lateinit var mFloatLayout: View
private var mInViewX = 0f
private var mInViewY = 0f
private var mInScreenX = 0f
private var mInScreenY = 0f
private var takeOverSceneWindow: TakeOverSceneWindow ?= null
// 语音听写对象
private var mIat: SpeechRecognizer? = null
@@ -84,6 +84,9 @@ class TakeOverReasonWindow constructor(activity: Activity) : View.OnTouchListene
private lateinit var tvTakeOverReason: AppCompatTextView
private lateinit var etNoteInput: AppCompatEditText
private lateinit var ivNoteAudio: ImageView
private lateinit var ivFrontCamera: ImageView
private lateinit var ivRearCamera: ImageView
private lateinit var ivMapScreen: ImageView
private lateinit var tvTakeOverSave: TextView
private lateinit var tvTakeOverCancel: TextView
private lateinit var rvTakeOverList: RecyclerView
@@ -132,7 +135,7 @@ class TakeOverReasonWindow constructor(activity: Activity) : View.OnTouchListene
it.flags = WindowManager.LayoutParams.FLAG_NOT_TOUCH_MODAL
it.gravity = Gravity.START or Gravity.TOP
it.width = 902
it.height = 1530
it.height = 1535
it.alpha = 1.0f
}
}
@@ -143,6 +146,9 @@ class TakeOverReasonWindow constructor(activity: Activity) : View.OnTouchListene
tvTakeOverReason = mFloatLayout.findViewById(R.id.tvTakeOverReason)
etNoteInput = mFloatLayout.findViewById(R.id.etNoteInput)
ivNoteAudio = mFloatLayout.findViewById(R.id.ivNoteAudio)
ivFrontCamera = mFloatLayout.findViewById(R.id.ivFrontCamera)
ivRearCamera = mFloatLayout.findViewById(R.id.ivRearCamera)
ivMapScreen = mFloatLayout.findViewById(R.id.ivMapScreen)
tvTakeOverSave = mFloatLayout.findViewById(R.id.tvTakeOverSave)
tvTakeOverCancel = mFloatLayout.findViewById(R.id.tvTakeOverCancel)
rvTakeOverList = mFloatLayout.findViewById(R.id.rvTakeOverList)
@@ -316,6 +322,13 @@ class TakeOverReasonWindow constructor(activity: Activity) : View.OnTouchListene
}
}
private fun showSceneWindow(frontCameraUri: Uri,rearCameraUri: Uri,mapScreenUri: Uri,currentItem: Int){
if(takeOverSceneWindow == null){
takeOverSceneWindow = TakeOverSceneWindow(mActivity)
}
takeOverSceneWindow?.showFloatWindow(frontCameraUri,rearCameraUri,mapScreenUri,currentItem)
}
private fun setAudio(status: Boolean){
if(status){
//开始录音
@@ -417,25 +430,6 @@ class TakeOverReasonWindow constructor(activity: Activity) : View.OnTouchListene
@SuppressLint("ClickableViewAccessibility")
override fun onTouch(v: View?, motionEvent: MotionEvent?): Boolean {
// when (motionEvent?.action) {
// MotionEvent.ACTION_DOWN -> {
// // 获取相对View的坐标即以此View左上角为原点
// mInViewX = motionEvent.x
// mInViewY = motionEvent.y
// // 获取相对屏幕的坐标,即以屏幕左上角为原点
// mInScreenX = motionEvent.rawX
// mInScreenY = motionEvent.rawY
// }
// MotionEvent.ACTION_MOVE -> {
// // 更新浮动窗口位置参数
// mInScreenX = motionEvent.rawX
// mInScreenY = motionEvent.rawY
// mWindowParams!!.x = (mInScreenX - mInViewX).toInt()
// mWindowParams!!.y = (mInScreenY - mInViewY).toInt()
// // 手指移动的时候更新小悬浮窗的位置
// mWindowManager!!.updateViewLayout(mFloatLayout, mWindowParams)
// }
// }
return true
}
@@ -457,6 +451,40 @@ class TakeOverReasonWindow constructor(activity: Activity) : View.OnTouchListene
tvTakeOverTime.text = mActivity.resources.getString(R.string.take_over_time) +
millis2String(mTakeOverRecordInfo.faultStartTime, TimeUtils.getHourMinSecondFormat())
}
//展示前向摄像头
val frontCameraPath: String = ((Environment.getExternalStorageDirectory()
.absolutePath + File.separator) +
"FrontCamera" + File.separator + millis2String(System.currentTimeMillis(), getMdFormat())
+ File.separator + mTakeOverRecordInfo.bagId) + ".png"
val frontCameraUri = Uri.parse(frontCameraPath)
ivFrontCamera.setImageURI(frontCameraUri)
//展示后向摄像头
val rearCameraPath: String = ((Environment.getExternalStorageDirectory()
.absolutePath + File.separator) +
"RearCamera" + File.separator + millis2String(System.currentTimeMillis(), getMdFormat())
+ File.separator + mTakeOverRecordInfo.bagId) + ".png"
val rearCameraUri = Uri.parse(rearCameraPath)
ivRearCamera.setImageURI(rearCameraUri)
//展示高精地图截图
val mapScreenPath: String = ((Environment.getExternalStorageDirectory()
.absolutePath + File.separator) +
"MapScreen" + File.separator + millis2String(System.currentTimeMillis(), getMdFormat())
+ File.separator + mTakeOverRecordInfo.bagId) + ".png"
val mapScreenUri = Uri.parse(mapScreenPath)
ivMapScreen.setImageURI(mapScreenUri)
//前向120°摄像头
ivFrontCamera.setOnClickListener {
showSceneWindow(frontCameraUri,rearCameraUri,mapScreenUri,0)
}
//后向120°摄像头
ivRearCamera.setOnClickListener {
showSceneWindow(frontCameraUri,rearCameraUri,mapScreenUri,1)
}
//高精地图截图
ivMapScreen.setOnClickListener {
showSceneWindow(frontCameraUri,rearCameraUri,mapScreenUri,2)
}
setWindowShowStatus(true)
}

View File

@@ -0,0 +1,113 @@
package com.zhjt.mogo_core_function_devatools.workorder
import android.annotation.SuppressLint
import android.app.Activity
import android.graphics.PixelFormat
import android.net.Uri
import android.util.DisplayMetrics
import android.view.Gravity
import android.view.LayoutInflater
import android.view.View
import android.view.WindowManager
import android.widget.ImageView
import androidx.viewpager.widget.ViewPager
import com.mogo.eagle.core.utilcode.util.BarUtils
import com.mogo.eagle.core.utilcode.util.ToastUtils
import com.zhjt.mogo_core_function_devatools.R
import com.zhjt.mogo_core_function_devatools.workorder.adapter.TakeOverSceneAdapter
/**
* 场景图像查看窗口
*/
class TakeOverSceneWindow constructor(activity: Activity) {
companion object{
const val TAG = "TakeOverSceneWindow"
}
private var mActivity: Activity = activity
private var mWindowParams: WindowManager.LayoutParams? = null
private var mWindowManager: WindowManager? = null
private lateinit var mFloatLayout: View
private lateinit var vpSceneImage: ViewPager
private lateinit var ivSceneClose: ImageView
private lateinit var ivScenePrevious: ImageView
private lateinit var ivSceneNext: ImageView
private val takeOverSceneAdapter = TakeOverSceneAdapter()
private var currentIndex = 0
init {
initFloatWindow()
}
private fun initFloatWindow(){
mFloatLayout = LayoutInflater.from(mActivity).inflate(R.layout.view_take_over_scene, null) as View
initView()
initEvent()
mWindowParams = WindowManager.LayoutParams()
mWindowManager = mActivity.windowManager
mWindowParams?.let {
it.format = PixelFormat.RGBA_8888
it.flags = WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE
it.gravity = Gravity.START or Gravity.TOP
it.width = WindowManager.LayoutParams.MATCH_PARENT
it.height = 1535
it.alpha = 1.0f
}
}
private fun initView(){
vpSceneImage = mFloatLayout.findViewById(R.id.vpSceneImage)
ivSceneClose = mFloatLayout.findViewById(R.id.ivSceneClose)
ivScenePrevious = mFloatLayout.findViewById(R.id.ivScenePrevious)
ivSceneNext = mFloatLayout.findViewById(R.id.ivSceneNext)
}
private fun initEvent(){
vpSceneImage.adapter =takeOverSceneAdapter
//关闭弹窗
ivSceneClose.setOnClickListener {
hideFloatWindow()
}
//前一个场景
ivScenePrevious.setOnClickListener {
if(currentIndex == 0){
ToastUtils.showShort("没有上一个场景了")
}else{
currentIndex = (currentIndex-1).coerceAtLeast(0)
vpSceneImage.currentItem = currentIndex
}
}
//后一个场景
ivSceneNext.setOnClickListener {
if(currentIndex < 2){
currentIndex = (currentIndex + 1).coerceAtMost(2)
vpSceneImage.currentItem = currentIndex
}else{
ToastUtils.showShort("没有下一个场景了")
}
}
}
@SuppressLint("SetTextI18n")
fun showFloatWindow(frontCameraUri: Uri, rearCameraUri: Uri, mapScreenUri: Uri, currentItem: Int) {
if (mFloatLayout.parent == null) {
val metrics = DisplayMetrics()
// 默认固定位置,靠屏幕右边缘的中间
mWindowManager!!.defaultDisplay.getMetrics(metrics)
mWindowParams!!.x = 0
mWindowParams!!.y = metrics.heightPixels - BarUtils.getStatusBarHeight()
mWindowManager!!.addView(mFloatLayout, mWindowParams)
takeOverSceneAdapter.setSceneUri(frontCameraUri, rearCameraUri, mapScreenUri)
currentIndex = currentItem
vpSceneImage.currentItem = currentItem
}
}
fun hideFloatWindow() {
if (mFloatLayout.parent != null){
mWindowManager!!.removeView(mFloatLayout)
}
}
}

View File

@@ -0,0 +1,69 @@
package com.zhjt.mogo_core_function_devatools.workorder.adapter
import android.net.Uri
import android.os.Environment
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import android.widget.ImageView
import android.widget.TextView
import androidx.viewpager.widget.PagerAdapter
import com.mogo.eagle.core.utilcode.util.TimeUtils.getMdFormat
import com.mogo.eagle.core.utilcode.util.TimeUtils.millis2String
import com.zhjt.mogo_core_function_devatools.R
import java.io.File
class TakeOverSceneAdapter: PagerAdapter() {
private lateinit var mFrontCameraUri: Uri
private lateinit var mRearCameraUri: Uri
private lateinit var mMapScreenUri: Uri
fun setSceneUri(frontCameraUri: Uri,rearCameraUri: Uri,mapScreenUri: Uri){
mFrontCameraUri = frontCameraUri
mRearCameraUri = rearCameraUri
mMapScreenUri = mapScreenUri
}
// 获取要滑动的控件的数量
override fun getCount(): Int {
return 3
}
// 来判断显示的是否是同一张图片,这里我们将两个参数相比较返回即可
override fun isViewFromObject(view: View, `object`: Any): Boolean {
return view == `object`
}
// 当要显示的图片可以进行缓存的时候,会调用这个方法进行显示图片的初始化,
// 我们将要显示的ImageView加入到ViewGroup中然后作为返回值返回即可
override fun instantiateItem(container: ViewGroup, position: Int): Any {
val inflater = LayoutInflater.from(container.context)
val view = inflater.inflate(R.layout.layout_scene_pager,container,false)
val sceneName: TextView = view.findViewById(R.id.tvSceneName)
val ivSceneImage: ImageView = view.findViewById(R.id.ivSceneImage)
when (position) {
0 -> {
sceneName.text = container.resources.getString(R.string.take_over_front_camera)
ivSceneImage.setImageURI(mFrontCameraUri)
}
1 -> {
sceneName.text = container.resources.getString(R.string.take_over_rear_camera)
ivSceneImage.setImageURI(mRearCameraUri)
}
else -> {
sceneName.text = container.resources.getString(R.string.take_over_map_screen)
ivSceneImage.setImageURI(mMapScreenUri)
}
}
container.addView(view)
return view
}
// PagerAdapter只缓存三张要显示的图片如果滑动的图片超出了缓存的范围就会调用这个方法将图片销毁
override fun destroyItem(container: ViewGroup, position: Int, `object`: Any) {
container.removeView(`object` as View)
}
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 8.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 8.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 8.1 KiB

View File

@@ -0,0 +1,10 @@
<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android">
<gradient
android:startColor="#00000000"
android:centerColor="#80000000"
android:endColor="#00000000"
android:angle="0"
android:gradientRadius="@dimen/dp_8"
/>
</shape>

View File

@@ -0,0 +1,26 @@
<?xml version="1.0" encoding="utf-8"?>
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent">
<ImageView
android:id="@+id/ivSceneImage"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:contentDescription="@string/take_over_scene_image"
android:scaleType="fitXY"
/>
<TextView
android:id="@+id/tvSceneName"
android:layout_width="@dimen/dp_754"
android:layout_height="@dimen/dp_98"
android:layout_gravity="center_horizontal"
android:layout_marginTop="@dimen/dp_64"
android:textSize="@dimen/sp_48"
android:textColor="@color/white"
android:gravity="center"
android:background="@drawable/bg_scene_name"
/>
</FrameLayout>

View File

@@ -145,6 +145,111 @@
android:contentDescription="@string/take_over_note_audio"
/>
<TextView
android:id="@+id/tvTakeOverSceneImageTitle"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/take_over_scene_image"
android:textSize="@dimen/sp_38"
android:textColor="@color/white"
app:layout_constraintTop_toBottomOf="@id/etNoteInput"
app:layout_constraintLeft_toLeftOf="@id/etNoteInput"
android:layout_marginTop="@dimen/dp_36"
/>
<ScrollView
android:layout_width="@dimen/dp_779"
android:layout_height="@dimen/dp_0"
app:layout_constraintTop_toBottomOf="@id/tvTakeOverSceneImageTitle"
app:layout_constraintLeft_toLeftOf="@id/tvTakeOverSceneImageTitle"
app:layout_constraintBottom_toBottomOf="parent"
android:layout_marginTop="@dimen/dp_13"
>
<androidx.constraintlayout.widget.ConstraintLayout
android:layout_width="match_parent"
android:layout_height="wrap_content">
<ImageView
android:id="@+id/ivFrontCamera"
android:layout_width="@dimen/dp_779"
android:layout_height="@dimen/dp_422"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent"
android:contentDescription="@string/take_over_front_camera"
android:scaleType="fitXY"
/>
<TextView
android:layout_width="@dimen/dp_779"
android:layout_height="@dimen/dp_72"
app:layout_constraintLeft_toLeftOf="@id/ivFrontCamera"
app:layout_constraintRight_toRightOf="@id/ivFrontCamera"
app:layout_constraintBottom_toBottomOf="@id/ivFrontCamera"
android:background="#66000000"
android:text="@string/take_over_front_camera"
android:textColor="@color/white"
android:textSize="@dimen/sp_30"
android:gravity="center"
/>
<ImageView
android:id="@+id/ivRearCamera"
android:layout_width="@dimen/dp_779"
android:layout_height="@dimen/dp_422"
app:layout_constraintTop_toBottomOf="@id/ivFrontCamera"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent"
android:contentDescription="@string/take_over_rear_camera"
android:layout_marginTop="@dimen/dp_13"
android:scaleType="fitXY"
/>
<TextView
android:layout_width="@dimen/dp_779"
android:layout_height="@dimen/dp_72"
app:layout_constraintLeft_toLeftOf="@id/ivRearCamera"
app:layout_constraintRight_toRightOf="@id/ivRearCamera"
app:layout_constraintBottom_toBottomOf="@id/ivRearCamera"
android:background="#66000000"
android:text="@string/take_over_rear_camera"
android:textColor="@color/white"
android:textSize="@dimen/sp_30"
android:gravity="center"
/>
<ImageView
android:id="@+id/ivMapScreen"
android:layout_width="@dimen/dp_779"
android:layout_height="@dimen/dp_422"
app:layout_constraintTop_toBottomOf="@id/ivRearCamera"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent"
android:contentDescription="@string/take_over_map_screen"
android:layout_marginTop="@dimen/dp_13"
android:layout_marginBottom="@dimen/dp_160"
android:scaleType="fitXY"
/>
<TextView
android:layout_width="@dimen/dp_779"
android:layout_height="@dimen/dp_72"
app:layout_constraintLeft_toLeftOf="@id/ivMapScreen"
app:layout_constraintRight_toRightOf="@id/ivMapScreen"
app:layout_constraintBottom_toBottomOf="@id/ivMapScreen"
android:background="#66000000"
android:text="@string/take_over_map_screen"
android:textColor="@color/white"
android:textSize="@dimen/sp_30"
android:gravity="center"
/>
</androidx.constraintlayout.widget.ConstraintLayout>
</ScrollView>
<TextView
android:id="@+id/tvTakeOverSave"
android:layout_width="@dimen/dp_380"

View File

@@ -0,0 +1,49 @@
<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
xmlns:app="http://schemas.android.com/apk/res-auto">
<androidx.viewpager.widget.ViewPager
android:id="@+id/vpSceneImage"
android:layout_width="match_parent"
android:layout_height="match_parent"
/>
<ImageView
android:id="@+id/ivSceneClose"
android:layout_width="@dimen/dp_170"
android:layout_height="@dimen/dp_170"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent"
android:src="@drawable/icon_scene_close"
android:contentDescription="@string/take_over_close_scene"
android:layout_marginBottom="@dimen/dp_110"
/>
<ImageView
android:id="@+id/ivScenePrevious"
android:layout_width="@dimen/dp_170"
android:layout_height="@dimen/dp_170"
app:layout_constraintTop_toTopOf="@id/ivSceneClose"
app:layout_constraintBottom_toBottomOf="@id/ivSceneClose"
app:layout_constraintRight_toLeftOf="@id/ivSceneClose"
android:src="@drawable/icon_scene_left"
android:layout_marginRight="@dimen/dp_108"
android:contentDescription="@string/take_over_previous_scene"
/>
<ImageView
android:id="@+id/ivSceneNext"
android:layout_width="@dimen/dp_170"
android:layout_height="@dimen/dp_170"
app:layout_constraintTop_toTopOf="@id/ivSceneClose"
app:layout_constraintBottom_toBottomOf="@id/ivSceneClose"
app:layout_constraintLeft_toRightOf="@id/ivSceneClose"
android:src="@drawable/icon_scene_right"
android:layout_marginLeft="@dimen/dp_108"
android:contentDescription="@string/take_over_next_scene"
/>
</androidx.constraintlayout.widget.ConstraintLayout>

View File

@@ -66,6 +66,13 @@
<string name="fault_note_supplement">(选填)</string>
<string name="take_over_note_input">手动输入</string>
<string name="take_over_note_audio">补充描述语音输入</string>
<string name="take_over_scene_image">场景图像</string>
<string name="take_over_front_camera">前向120°摄像头</string>
<string name="take_over_rear_camera">后向120°摄像头</string>
<string name="take_over_map_screen">高精地图截图</string>
<string name="take_over_previous_scene">上一个场景</string>
<string name="take_over_close_scene">关闭场景</string>
<string name="take_over_next_scene">下一个场景</string>
<string name="fault_report">上报</string>
<string name="take_over_save">保存</string>
<string name="take_over_cancel">取消</string>