[2.14.0]BadCase三期-录包管理

This commit is contained in:
xuxinchao
2023-02-07 20:15:48 +08:00
parent 044050a4e6
commit 87543b9696
24 changed files with 812 additions and 82 deletions

View File

@@ -6,40 +6,26 @@ import android.content.Context
import android.view.View
import android.view.WindowManager
import androidx.fragment.app.FragmentActivity
import androidx.lifecycle.*
import androidx.lifecycle.Lifecycle.Event
import androidx.lifecycle.Lifecycle.Event.ON_CREATE
import androidx.lifecycle.Lifecycle.Event.ON_DESTROY
import androidx.lifecycle.LifecycleCoroutineScope
import androidx.lifecycle.LifecycleEventObserver
import androidx.lifecycle.LifecycleOwner
import androidx.lifecycle.lifecycleScope
import com.mogo.cloud.passport.MoGoAiCloudClientConfig
import com.mogo.eagle.core.data.msgbox.MsgBoxBean
import com.mogo.eagle.core.data.msgbox.RecordBagMsg
import com.mogo.eagle.core.function.call.autopilot.CallerAutopilotVehicleStateListenerManager
import com.mogo.eagle.core.utilcode.kotlin.PX
import com.mogo.eagle.core.utilcode.kotlin.lifecycleOwner
import com.mogo.eagle.core.utilcode.kotlin.onClick
import com.mogo.eagle.core.utilcode.mogo.logger.CallerLogger
import com.mogo.eagle.core.utilcode.mogo.logger.scene.SceneConstant.Companion.M_DEVA
import com.mogo.eagle.core.utilcode.reminder.Reminder
import com.mogo.eagle.core.utilcode.reminder.api.IReminder
import com.mogo.eagle.core.utilcode.reminder.api.IReminder.IGlobalStateChangeListener
import com.mogo.eagle.core.utilcode.util.*
import com.zhjt.mogo_core_function_devatools.badcase.biz.*
import com.zhjt.mogo_core_function_devatools.badcase.consts.BadCaseConfig
import com.zhjt.mogo_core_function_devatools.badcase.repository.db.entity.AutoPilotRecord
import com.zhjt.mogo_core_function_devatools.badcase.repository.net.api.entity.BadCaseResponse.Reason
import com.zhjt.mogo_core_function_devatools.ext.enqueuePop
import com.zhjt.mogo_core_function_devatools.ext.toast
import kotlinx.coroutines.*
import kotlinx.coroutines.ExperimentalCoroutinesApi
import kotlinx.coroutines.Job
import kotlinx.coroutines.channels.Channel
import me.jessyan.autosize.utils.AutoSizeUtils
import record_cache.RecordPanelOuterClass
import java.lang.ref.WeakReference
import java.util.concurrent.TimeUnit
internal object BadCaseManager : LifecycleEventObserver {
internal object BadCaseManager : LifecycleEventObserver{
const val TAG = "BadCase"
@@ -109,7 +95,7 @@ internal object BadCaseManager : LifecycleEventObserver {
hideFloat = null
}
})
context.enqueuePop(badCaseManagerView,AutoSizeUtils.dp2px(context,960f), WindowManager.LayoutParams.MATCH_PARENT, key = "BadCaseConfigView").also {
context.enqueuePop(badCaseManagerView,AutoSizeUtils.dp2px(context,960f), WindowManager.LayoutParams.MATCH_PARENT, key = "BadCaseManagerView").also {
hideFloat = it
}
}

View File

@@ -1,15 +1,34 @@
package com.zhjt.mogo_core_function_devatools.badcase.biz
import android.app.Activity
import android.content.Context
import android.graphics.Color
import android.graphics.drawable.ColorDrawable
import android.os.Handler
import android.util.AttributeSet
import android.util.Log
import android.view.LayoutInflater
import android.view.View
import androidx.constraintlayout.widget.ConstraintLayout
import androidx.recyclerview.widget.LinearLayoutManager
import bag_manager.BagManagerOuterClass
import com.mogo.eagle.core.data.badcase.BagDescriptionEntity
import com.mogo.eagle.core.data.badcase.BagInfoEntity
import com.mogo.eagle.core.data.badcase.BagManagerEntity
import com.mogo.eagle.core.data.badcase.SubBagEntity
import com.mogo.eagle.core.function.api.autopilot.IMoGoAutopilotRecordListener
import com.mogo.eagle.core.function.call.autopilot.CallerAutoPilotManager
import com.mogo.eagle.core.function.call.autopilot.CallerAutopilotRecordListenerManager
import com.mogo.eagle.core.utilcode.util.ToastUtils
import com.mogo.eagle.core.utilcode.util.UiThreadHandler
import com.zhidao.loglib.download.DownloadManager
import com.zhjt.mogo_core_function_devatools.R
import com.zhjt.mogo_core_function_devatools.badcase.biz.adapter.BagManagerListAdapter
import com.zhjt.mogo_core_function_devatools.badcase.consts.BadCaseConfig.bagManagerList
import com.zhjt.mogo_core_function_devatools.badcase.record.Audition
import kotlinx.android.synthetic.main.layout_badcase_manager.view.*
import java.util.*
/**
* @author XuXinChao
@@ -20,13 +39,25 @@ internal class BadCaseManagerView @JvmOverloads constructor(
context: Context,
attrs: AttributeSet? = null,
defStyleAttr: Int = 0
) : ConstraintLayout(context, attrs, defStyleAttr){
) : ConstraintLayout(context, attrs, defStyleAttr), IMoGoAutopilotRecordListener {
companion object {
const val TAG = "BadCaseManagerView"
}
private var bagManagerListAdapter: BagManagerListAdapter ?= null
private var bagManagerEntity: BagManagerEntity = BagManagerEntity()
private var clickListener: ClickListener? = null
private var bagUploadDialog: BagUploadDialog ?= null
private var spaceTotal: Long = 0 //总空间
private var spaceUsed: Long = 0 //已用空间
private var spaceFree: Long = 0 //可用空间
private var selectedBagNum = 0 //选中Bag包的数量
private var selectedBagSize: Long = 0 //选中Bag包的大小
private val audioSavePath = "/mnt/sdcard/mogo/"
init {
LayoutInflater.from(context).inflate(R.layout.layout_badcase_manager, this, true)
@@ -39,14 +70,198 @@ internal class BadCaseManagerView @JvmOverloads constructor(
ivManagerClose.setOnClickListener {
clickListener?.onClose()
}
//一键全选
tvSelectAll.setOnClickListener {
if(bagManagerEntity.bagsInfoResp.size>0){
selectedBagSize = 0
for(selectBagInfo in bagManagerEntity.bagsInfoResp){
selectBagInfo.selectStatus = true
selectedBagSize += selectBagInfo.totalSize
bagManagerList.add(selectBagInfo)
}
selectedBagNum = bagManagerEntity.bagsInfoResp.size
//显示选择包的个数和大小
tvSelectedBagSize.text = "已选${selectedBagNum}个包,共${selectedBagSize/(1000*1024*1024)}G"
tvSelectedBagSize.visibility = View.VISIBLE
bagManagerListAdapter?.setData(bagManagerEntity.bagsInfoResp)
}
}
//取消选中
tvCancelSelect.setOnClickListener {
if(bagManagerEntity.bagsInfoResp.size>0){
for(cancelBagInfo in bagManagerEntity.bagsInfoResp){
cancelBagInfo.selectStatus = false
bagManagerList.remove(cancelBagInfo)
}
selectedBagNum = 0
selectedBagSize = 0
tvSelectedBagSize.visibility = View.GONE
bagManagerListAdapter?.setData(bagManagerEntity.bagsInfoResp)
}
}
//上传Cos桶
tvUploadCloud.setOnClickListener {
if(bagManagerList.size>0){
bagManagerEntity.reqType = 3
bagManagerEntity.keyReq = bagManagerList[0].key
CallerAutoPilotManager.sendBagManagerCmd(bagManagerEntity)
bagUploadDialog = BagUploadDialog(context)
bagUploadDialog?.setListener { //删除选择
bagManagerList.clear()
if (bagManagerEntity.bagsInfoResp.size > 0) {
for (cancelBagInfo in bagManagerEntity.bagsInfoResp) {
cancelBagInfo.selectStatus = false
bagManagerList.remove(cancelBagInfo)
}
selectedBagNum = 0
selectedBagSize = 0
tvSelectedBagSize.visibility = View.GONE
bagManagerListAdapter?.setData(bagManagerEntity.bagsInfoResp)
}
}
bagUploadDialog?.setAllUpload(selectedBagNum,selectedBagSize)
bagUploadDialog?.show()
}else{
ToastUtils.showShort("请先选择要上传的Bag包")
}
}
//删除Bag包
tvDeleteSelect.setOnClickListener {
if(bagManagerList.size>0){
bagManagerEntity.reqType = 4
bagManagerEntity.keyReq = bagManagerList[0].key
CallerAutoPilotManager.sendBagManagerCmd(bagManagerEntity)
}else{
ToastUtils.showShort("请先选择要删除的Bag包")
}
}
bagManagerListAdapter = BagManagerListAdapter()
bagManagerListAdapter?.setListener(object :BagManagerListAdapter.BagClickListener{
override fun onClick(bagInfoEntity: BagInfoEntity, isChecked: Boolean) {
if(isChecked){
bagInfoEntity.selectStatus = true
bagManagerList.add(bagInfoEntity)
selectedBagNum++
selectedBagSize += bagInfoEntity.totalSize
tvSelectedBagSize.text = "已选${selectedBagNum}个包,共${selectedBagSize/(1000*1024*1024)}G"
tvSelectedBagSize.visibility = View.VISIBLE
}else{
bagInfoEntity.selectStatus = false
bagManagerList.remove(bagInfoEntity)
selectedBagNum--
selectedBagSize -= bagInfoEntity.totalSize
if(selectedBagNum == 0){
tvSelectedBagSize.visibility = View.GONE
}else{
tvSelectedBagSize.text = "已选${selectedBagNum}个包,共${selectedBagSize/(1000*1024*1024)}G"
tvSelectedBagSize.visibility = View.VISIBLE
}
}
}
override fun uploadBI(bagInfoEntity: BagInfoEntity) {
//展示上报弹窗
val initiativeBadCaseWindow = InitiativeBadCaseWindow(context as Activity)
initiativeBadCaseWindow.setClickListener(object: InitiativeBadCaseWindow.ClickListener{
override fun closeWindow() {
initiativeBadCaseWindow.hideFloatWindow()
}
})
initiativeBadCaseWindow.showReportBIWindow(bagInfoEntity)
}
override fun editDescription(key: Long, description: BagDescriptionEntity) {
//编辑Bag包描述信息
bagManagerEntity.reqType = 5
bagManagerEntity.keyReq = key
bagManagerEntity.descReq = description
CallerAutoPilotManager.sendBagManagerCmd(bagManagerEntity)
}
override fun bagAudio(key: Long, audioUrl: String) {
DownloadManager.getInstance().init(context)
val downUrl = audioUrl.replace("http://petchfile-1255510688.cos.ap-beijing.myqcloud.com/","")
DownloadManager.getInstance().download(downUrl,
audioSavePath,"${key}.wav")
//延迟播放
Handler().postDelayed({
//音频文件播放
Audition.getInstance().playOrStop("${audioSavePath}${key}.wav")
}, 1500)
}
})
val linearLayoutManager = LinearLayoutManager(context)
rvBagList.layoutManager = linearLayoutManager
rvBagList.adapter = bagManagerListAdapter
//音频文件播放
// Audition.getInstance().playOrStop("/mnt/sdcard/mogo/test.wav")
//音频下载
//
// 音频下载
// DownloadManager.getInstance().init(context)
// DownloadManager.getInstance().download("CarPad/mogopadlog/X20202111230C01YYW/2023-01-30/Audio_1675049657187_BadCase.wav",
// "/mnt/sdcard/mogo/","test13.wav")
val descriptionEntityOne = BagDescriptionEntity("包信息描述1",false,
"CarPad/mogopadlog/X20202111230C01YYW/2023-01-30/Audio_1675049657187_BadCase.wav",false)
val bagInfoEntityOne = BagInfoEntity()
bagInfoEntityOne.key = 12341
bagInfoEntityOne.totalSize = 1*1024*1024*1000
bagInfoEntityOne.timestamp = System.currentTimeMillis().toString()
bagInfoEntityOne.bagPath = ""
bagInfoEntityOne.mergeStat = false
bagInfoEntityOne.uploadStat = false
bagInfoEntityOne.description = descriptionEntityOne
val descriptionEntityTwo = BagDescriptionEntity("包信息描述2",true,
"CarPad/mogopadlog/X20202111230C01YYW/2023-01-30/Audio_1675049657187_BadCase.wav",true)
val bagInfoEntityTwo = BagInfoEntity()
bagInfoEntityTwo.key = 12342
bagInfoEntityTwo.totalSize = 2*1024*1024*1000
bagInfoEntityTwo.timestamp = System.currentTimeMillis().toString()
bagInfoEntityTwo.bagPath = ""
bagInfoEntityTwo.mergeStat = false
bagInfoEntityTwo.uploadStat = false
bagInfoEntityTwo.description = descriptionEntityTwo
val descriptionEntityThree = BagDescriptionEntity("包信息描述3",true,
"CarPad/mogopadlog/X20202111230C01YYW/2023-01-30/Audio_1675049657187_BadCase.wav",true)
val bagInfoEntityThree = BagInfoEntity()
bagInfoEntityThree.key = 12343
bagInfoEntityThree.totalSize = 1*1024*1024*1000
bagInfoEntityThree.timestamp = System.currentTimeMillis().toString()
bagInfoEntityThree.bagPath = ""
bagInfoEntityThree.mergeStat = false
bagInfoEntityThree.uploadStat = false
bagInfoEntityThree.description = descriptionEntityThree
val descriptionEntityFour = BagDescriptionEntity("包信息描述1",true,
"CarPad/mogopadlog/X20202111230C01YYW/2023-01-30/Audio_1675049657187_BadCase.wav",true)
val bagInfoEntityFour = BagInfoEntity()
bagInfoEntityFour.key = 12344
bagInfoEntityFour.totalSize = 10*1024*1024*1000L
bagInfoEntityFour.timestamp = System.currentTimeMillis().toString()
bagInfoEntityFour.bagPath = ""
bagInfoEntityFour.mergeStat = false
bagInfoEntityFour.uploadStat = false
bagInfoEntityFour.description = descriptionEntityFour
bagManagerEntity.bagsInfoResp.add(bagInfoEntityOne)
bagManagerEntity.bagsInfoResp.add(bagInfoEntityTwo)
bagManagerEntity.bagsInfoResp.add(bagInfoEntityThree)
bagManagerEntity.bagsInfoResp.add(bagInfoEntityFour)
bagManagerListAdapter?.setData(bagManagerEntity.bagsInfoResp)
}
fun setOnClickListener(clickListener: ClickListener) {
@@ -57,4 +272,146 @@ internal class BadCaseManagerView @JvmOverloads constructor(
fun onClose()
}
override fun onBagManagerResult(bagManager: BagManagerOuterClass.BagManager) {
super.onBagManagerResult(bagManager)
UiThreadHandler.post {
//获取空间使用信息
if(bagManager.reqType == 1){
//遍历各个主机的硬盘空间信息
if(bagManager.spaceInfoRespCount>0){
for(spaceInfo in bagManager.spaceInfoRespList){
spaceInfo.diskSpaceInfo?.let {
spaceTotal += it.total
spaceUsed += it.used
spaceFree += it.free
}
}
//展示空间使用情况
//已使用空间
tvUsedSpaceContent.text = "${(spaceUsed/(1000*1024*1024L))}G"
//可使用空间
tvFreeSpaceContent.text = "${(spaceFree/(1000*1024*1024L))}G"
//进度条展示空间
pbSpacePercent.progress = (spaceUsed*100/spaceTotal).toInt()
}
}
//遍历所有bag
else if(bagManager.reqType == 2){
if(bagManager.bagsInfoRespCount>0){
for(bagInfo in bagManager.bagsInfoRespList){
bagInfo?.let {
val descriptionEntity = BagDescriptionEntity(it.description.description,it.description.hasAudio,it.description.audioUrl,it.description.reportBI)
val bagInfoEntity = BagInfoEntity()
bagInfoEntity.key = it.key
bagInfoEntity.totalSize = it.totalSize
bagInfoEntity.timestamp = it.timestamp
bagInfoEntity.bagPath = it.bagPath
bagInfoEntity.mergeStat = it.mergeStat
bagInfoEntity.uploadStat = it.uploadStat
bagInfoEntity.description = descriptionEntity
for(subBag in it.subBagsList){
val subBagEntity = SubBagEntity(subBag.key,subBag.host,subBag.size)
bagInfoEntity.subBags.add(subBagEntity)
}
bagManagerEntity.bagsInfoResp.add(bagInfoEntity)
}
}
//更新List
bagManagerListAdapter?.setData(bagManagerEntity.bagsInfoResp)
}
// 开启定时查询速度
Timer().schedule(timerTaskRefresh, Date(), 60*1000)
}
//上传Cos
else if(bagManager.reqType == 3){
//此处应循环上传Cos
val uploadIterator = bagManagerEntity.bagsInfoResp.iterator()
while(uploadIterator.hasNext()){
val uploadBagInfo = uploadIterator.next()
if(uploadBagInfo.key == bagManager.keyReq){
bagManagerList.remove(uploadBagInfo)
if(bagManagerList.size>0){
var remainSize = 0L
for(bagInfo in bagManagerList){
remainSize += bagInfo.totalSize
}
bagUploadDialog?.updateRemainUpload(bagManagerList.size,remainSize)
//执行下一个上传Bag命令
bagManagerEntity.reqType = 3
bagManagerEntity.keyReq = bagManagerList[0].key
CallerAutoPilotManager.sendBagManagerCmd(bagManagerEntity)
}
}
}
}
//删除Bag
else if(bagManager.reqType == 4){
//收到此回调就删除对应key的Bag
val iterator = bagManagerEntity.bagsInfoResp.iterator()
while(iterator.hasNext()){
val deleteBagInfo = iterator.next()
if(deleteBagInfo.key == bagManager.keyReq){
iterator.remove()
// bagManagerEntity.bagsInfoResp.remove(deleteBagInfo)
bagManagerList.remove(deleteBagInfo)
//更新列表
bagManagerListAdapter?.setData(bagManagerEntity.bagsInfoResp)
if(bagManagerList.size>0){
//继续执行删除命令
bagManagerEntity.reqType = 4
bagManagerEntity.keyReq = bagManagerList[0].key
CallerAutoPilotManager.sendBagManagerCmd(bagManagerEntity)
}
}
}
}
//修改bag附加信息
else if(bagManager.reqType == 5){
//更新Bag包上报状态
for(bagInfo in bagManagerEntity.bagsInfoResp){
if(bagInfo.key == bagManager.keyReq){
bagInfo.description?.let {
it.reportBI = bagManager.descReq.reportBI
it.description = bagManager.descReq.description
it.hasAudio = bagManager.descReq.hasAudio
it.audioUrl = bagManager.descReq.audioUrl
}
//更新List
bagManagerListAdapter?.setData(bagManagerEntity.bagsInfoResp)
}
}
}
}
}
override fun onAttachedToWindow() {
super.onAttachedToWindow()
CallerAutopilotRecordListenerManager.addListener(TAG, this)
bagManagerEntity.reqType = 2
//遍历所有bag
CallerAutoPilotManager.sendBagManagerCmd(bagManagerEntity)
}
override fun onDetachedFromWindow() {
super.onDetachedFromWindow()
CallerAutopilotRecordListenerManager.removeListener(TAG)
try {
timerTaskRefresh.cancel()
} catch (e: Exception) {
e.printStackTrace()
}
}
private val timerTaskRefresh = object : TimerTask() {
override fun run() {
UiThreadHandler.post {
//获取空间使用信息,每隔1分钟获取一次
bagManagerEntity.reqType = 1
CallerAutoPilotManager.sendBagManagerCmd(bagManagerEntity)
}
}
}
}

View File

@@ -4,6 +4,7 @@ import android.app.Dialog;
import android.content.Context;
import android.os.Bundle;
import android.view.WindowManager;
import android.widget.ProgressBar;
import android.widget.TextView;
import androidx.annotation.NonNull;
@@ -20,6 +21,14 @@ public class BagUploadDialog extends Dialog {
private TextView tvCancelUpload;//取消上传
private TextView tvCancel;//取消
private TextView tvUploadDetail;//上传详情
private ProgressBar viewUploadProgress;//上传进度条
private int totalNum;
private Long totalSize;
private int remainNum;
private Long remainSize;
private BagUploadListener uploadListener;
public BagUploadDialog(@NonNull Context context) {
super(context, R.style.bad_case_dialog);
@@ -42,12 +51,16 @@ public class BagUploadDialog extends Dialog {
tvCancelUpload = findViewById(R.id.tvCancelUpload);
tvCancel = findViewById(R.id.tvCancel);
tvUploadDetail = findViewById(R.id.tvUploadDetail);
viewUploadProgress = findViewById(R.id.viewUploadProgress);
}
private void initEvent(){
//取消上传
tvCancelUpload.setOnClickListener(v -> {
if(uploadListener!=null){
uploadListener.cancelUpload();
}
dismiss();
});
//取消
tvCancel.setOnClickListener(v -> {
@@ -64,4 +77,28 @@ public class BagUploadDialog extends Dialog {
public void onDetachedFromWindow() {
super.onDetachedFromWindow();
}
public void setListener(BagUploadListener listener){
uploadListener = listener;
}
public void setAllUpload(int totalNum,Long totalSize){
this.totalNum = totalNum;
this.totalSize = totalSize;
}
public void updateRemainUpload(int remainNum,Long remainSize){
this.remainNum = remainNum;
this.remainSize = remainSize;
//更新进度条和进度文字
tvUploadDetail.setText("共计"+totalNum+"个包 ("+(totalSize/(1000*1024*1024L))+"G) 已上传"+(totalNum-remainNum)+"个包 ("
+((totalSize-remainSize)/(1000*1024*1024L))+"G) 剩余"+remainNum+"个包 ("+ (remainSize/(1000*1024*1024L))+"G)");
viewUploadProgress.setProgress((totalNum-remainNum)*100/totalNum);
}
interface BagUploadListener{
//取消上传
void cancelUpload();
}
}

View File

@@ -20,6 +20,7 @@ import com.zhjt.mogo_core_function_devatools.badcase.consts.BadCaseConfig;
import java.util.ArrayList;
import bag_manager.BagManagerOuterClass;
import mogo.telematics.pad.MessagePad;
import record_cache.RecordPanelOuterClass;
@@ -116,4 +117,8 @@ public class CaseListDialog extends Dialog implements IMoGoAutopilotRecordListen
caseListAdapter.notifyDataSetChanged();
});
}
@Override
public void onBagManagerResult(@NonNull BagManagerOuterClass.BagManager bagManager) {
}
}

View File

@@ -28,6 +28,7 @@ import com.zhjt.mogo_core_function_devatools.badcase.consts.BadCaseConfig;
import java.util.ArrayList;
import java.util.List;
import bag_manager.BagManagerOuterClass;
import mogo.telematics.pad.MessagePad;
import record_cache.RecordPanelOuterClass;
@@ -203,4 +204,8 @@ public class CaseTopicListDialog extends Dialog implements IMoGoAutopilotRecordL
@Override
public void onAutopilotRecordResult(@NonNull RecordPanelOuterClass.RecordPanel recordPanel) {
}
@Override
public void onBagManagerResult(@NonNull BagManagerOuterClass.BagManager bagManager) {
}
}

View File

@@ -13,6 +13,9 @@ import android.widget.ImageView
import android.widget.TextView
import com.mogo.cloud.passport.MoGoAiCloudClientConfig
import com.mogo.eagle.core.data.app.AppConfigInfo
import com.mogo.eagle.core.data.badcase.BagDescriptionEntity
import com.mogo.eagle.core.data.badcase.BagInfoEntity
import com.mogo.eagle.core.data.badcase.BagManagerEntity
import com.mogo.eagle.core.data.badcase.RecordCaseEntity
import com.mogo.eagle.core.function.api.autopilot.IMoGoAutopilotCarStateListener
import com.mogo.eagle.core.function.api.autopilot.IMoGoAutopilotRecordListener
@@ -89,6 +92,8 @@ class InitiativeBadCaseWindow constructor(activity: Activity) : View.OnTouchList
private var longitude: Double?=null
private var latitude: Double?=null
private var bagManagerEntity: BagManagerEntity = BagManagerEntity()
private var mInViewX = 0f
private var mInViewY = 0f
private var mDownInScreenX = 0f
@@ -285,7 +290,7 @@ class InitiativeBadCaseWindow constructor(activity: Activity) : View.OnTouchList
itx["filename"] = recordFileName?:"" //bag包文件地址
itx["filesize"] = "0" //bag包文件大小
itx["key"] = recordKey?:"" //key
itx["reason"] = uploadReason.toString()?:"" //采集原因
itx["reason"] = uploadReason.toString() //采集原因
itx["duration"] = BadCaseConfig.totalDuration.toString() //采集时长固定为20S
itx["startTime"] = System.currentTimeMillis().toString() //上报时间(时间戳格式)
itx["channel"] = "1" //渠道
@@ -301,6 +306,15 @@ class InitiativeBadCaseWindow constructor(activity: Activity) : View.OnTouchList
TipToast.shortTip("上报失败")
} else {
TipToast.shortTip("上报成功")
//将上报BI的结果同步给工控机记录保存
recordKey?.let {
val hasAudio = downloadUrl != null
val descReqEntity = BagDescriptionEntity(uploadReason.toString(),hasAudio,downloadUrl.toString(),true)
bagManagerEntity.reqType = 5
bagManagerEntity.keyReq = it.toLong()
bagManagerEntity.descReq = descReqEntity
CallerAutoPilotManager.sendBagManagerCmd(bagManagerEntity)
}
BadCaseConfig.windowNum--
clickListener?.closeWindow()
}
@@ -351,6 +365,22 @@ class InitiativeBadCaseWindow constructor(activity: Activity) : View.OnTouchList
}
}
fun showReportBIWindow(bagInfoEntity: BagInfoEntity){
if (mFloatLayout.parent == null) {
val metrics = DisplayMetrics()
// 默认固定位置,靠屏幕右边缘的中间
mWindowManager!!.defaultDisplay.getMetrics(metrics)
mWindowParams!!.x = metrics.widthPixels
mWindowParams!!.y = metrics.heightPixels - BarUtils.getStatusBarHeight()-950
mWindowManager!!.addView(mFloatLayout, mWindowParams)
//已经录包无需再次启动录包,只要将录包信息同步到弹窗
bagInfoEntity.let {
recordKey = it.key.toString()
recordFileName = it.bagPath
}
}
}
fun hideFloatWindow() {
//注销采集结果回调监听
CallerAutopilotRecordListenerManager.removeListener(this.hashCode().toString())

View File

@@ -16,10 +16,13 @@ import android.widget.TextView
import com.google.android.flexbox.FlexboxLayout
import com.mogo.cloud.passport.MoGoAiCloudClientConfig
import com.mogo.eagle.core.data.app.AppConfigInfo
import com.mogo.eagle.core.data.badcase.BagDescriptionEntity
import com.mogo.eagle.core.data.badcase.BagManagerEntity
import com.mogo.eagle.core.data.msgbox.MsgBoxBean
import com.mogo.eagle.core.data.msgbox.MsgCategory
import com.mogo.eagle.core.data.msgbox.RecordBagMsg
import com.mogo.eagle.core.function.api.autopilot.IMoGoAutopilotCarStateListener
import com.mogo.eagle.core.function.call.autopilot.CallerAutoPilotManager
import com.mogo.eagle.core.function.call.autopilot.CallerAutopilotCarStatusListenerManager
import com.mogo.eagle.core.function.call.msgbox.CallerMsgBoxManager
import com.mogo.eagle.core.utilcode.mogo.logger.CallerLogger
@@ -61,6 +64,8 @@ class PassiveBadCaseWindow constructor(activity: Activity) : View.OnTouchListene
private var audioStatus = false
private var audioFileName:String?=null //录音文件名称
private var bagManagerEntity: BagManagerEntity = BagManagerEntity()
private var uploadReason: String = String() //上报原因,标签
private var recordKey: String?=null //录制bag包key
private var recordFileName: String?=null //录制文件包名
@@ -265,6 +270,15 @@ class PassiveBadCaseWindow constructor(activity: Activity) : View.OnTouchListene
TipToast.shortTip("上报失败")
} else {
TipToast.shortTip("上报成功")
//将上报BI的结果同步给工控机记录保存
recordKey?.let {
val hasAudio = downloadUrl != null
val descReqEntity = BagDescriptionEntity(uploadReason,hasAudio,downloadUrl.toString(),true)
bagManagerEntity.reqType = 5
bagManagerEntity.keyReq = it.toLong()
bagManagerEntity.descReq = descReqEntity
CallerAutoPilotManager.sendBagManagerCmd(bagManagerEntity)
}
BadCaseConfig.windowNum--
clickListener?.closeWindow()
}

View File

@@ -1,5 +1,7 @@
package com.zhjt.mogo_core_function_devatools.badcase.biz.adapter
import android.text.Editable
import android.text.TextWatcher
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
@@ -7,7 +9,11 @@ import android.widget.CheckBox
import android.widget.EditText
import android.widget.ImageView
import android.widget.TextView
import androidx.core.widget.addTextChangedListener
import androidx.recyclerview.widget.RecyclerView
import com.mogo.eagle.core.data.badcase.BagDescriptionEntity
import com.mogo.eagle.core.data.badcase.BagInfoEntity
import com.mogo.eagle.core.utilcode.util.TimeUtils
import com.zhjt.mogo_core_function_devatools.R
import kotlinx.coroutines.NonDisposableHandle
import kotlinx.coroutines.NonDisposableHandle.parent
@@ -19,7 +25,13 @@ import kotlinx.coroutines.NonDisposableHandle.parent
*/
class BagManagerListAdapter: RecyclerView.Adapter<BagManagerListAdapter.BagManagerListHolder>() {
private var data:List<String> ?= null
private var data:List<BagInfoEntity> ?= null
private var bagClickListener: BagClickListener ?= null
fun setData(data: List<BagInfoEntity>?){
this.data = data
notifyDataSetChanged()
}
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): BagManagerListHolder {
val view = LayoutInflater.from(parent.context)
@@ -28,7 +40,84 @@ class BagManagerListAdapter: RecyclerView.Adapter<BagManagerListAdapter.BagManag
}
override fun onBindViewHolder(holder: BagManagerListHolder, position: Int) {
data?.let {
val bagInfoEntity = it[position]
// if(bagInfoEntity.description?.description.isNullOrEmpty()){
// holder.cbBagSelect.text = bagInfoEntity.key.toString()
// }else{
// holder.cbBagSelect.text = bagInfoEntity.description?.description
// }
holder.cbBagSelect.setOnCheckedChangeListener(null)
holder.cbBagSelect.isChecked = bagInfoEntity.selectStatus
holder.cbBagSelect.tag = bagInfoEntity
holder.cbBagSelect.setOnCheckedChangeListener { _, isChecked ->
bagClickListener?.onClick(bagInfoEntity,isChecked)
}
holder.etBagNameEdit.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?) {
bagInfoEntity.description?.let { desc->
val descriptionStr = s.toString()
if(desc.description != descriptionStr){
desc.description = descriptionStr
bagClickListener?.editDescription(bagInfoEntity.key,desc)
}
}
}
})
bagInfoEntity.description?.let { des->
if(des.reportBI){
//已上报
holder.tvBagReportStatus.text = "已上报"
holder.tvBagReportStatus.setBackgroundResource(R.drawable.bag_reported_button_bg)
}else{
//未上报
holder.tvBagReportStatus.text = "上报"
holder.tvBagReportStatus.setBackgroundResource(R.drawable.bag_report_button_bg)
holder.tvBagReportStatus.setOnClickListener {
bagClickListener?.uploadBI(bagInfoEntity)
}
}
if(des.description.isEmpty()){
holder.etBagNameEdit.setText(bagInfoEntity.key.toString())
}else{
holder.etBagNameEdit.setText(des.description)
}
}
if(bagInfoEntity.description?.hasAudio == true){
holder.ivBagAudio.visibility = View.VISIBLE
holder.ivBagAudio.setOnClickListener {
bagInfoEntity.description?.let { description->
bagClickListener?.bagAudio(bagInfoEntity.key,description.audioUrl)
}
}
}else{
holder.ivBagAudio.visibility = View.INVISIBLE
}
holder.tvBagSize.text = "${bagInfoEntity.totalSize/(1000*1024*1024)}G"
holder.tvBagTime.text =
it[position].timestamp?.let { it1 -> TimeUtils.millis2String(it1.toLong(),TimeUtils.getHourMinSecondFormat()) }
}
}
override fun getItemCount() = data?.size ?: 0
@@ -42,4 +131,19 @@ class BagManagerListAdapter: RecyclerView.Adapter<BagManagerListAdapter.BagManag
var tvBagSize: TextView = itemView.findViewById(R.id.tvBagSize)
}
fun setListener(listener: BagClickListener){
bagClickListener = listener
}
interface BagClickListener{
//选择Bag包
fun onClick(bagInfoEntity: BagInfoEntity,isChecked: Boolean)
//上报BI平台
fun uploadBI(bagInfoEntity: BagInfoEntity)
//编辑Bag包描述信息
fun editDescription(key: Long,description: BagDescriptionEntity)
//听录音
fun bagAudio(key: Long,audioUrl: String)
}
}

View File

@@ -1,5 +1,7 @@
package com.zhjt.mogo_core_function_devatools.badcase.consts
import com.mogo.eagle.core.data.badcase.BagInfoEntity
/**
* @author XuXinChao
* @description 录包配置参数
@@ -32,5 +34,8 @@ object BadCaseConfig {
//自定义Topic清单列表
@JvmField
var customTopicList: ArrayList<String> = ArrayList()
//Bag包管理列表
@JvmField
var bagManagerList: ArrayList<BagInfoEntity> = ArrayList()
}

View File

@@ -0,0 +1,18 @@
<?xml version="1.0" encoding="utf-8"?>
<shape
xmlns:android="http://schemas.android.com/apk/res/android"
android:shape="rectangle">
<!-- solid指定形状的填充色只有android:color一个属性 -->
<gradient
android:startColor="#3B4577"
android:endColor="#7CF6FF"
/>
<!-- padding设置内容区域离边界的间距 -->
<!-- corners设置圆角只适用于rectangle -->
<!-- <corners android:bottomRightRadius="20dp"-->
<!-- android:topRightRadius="20dp"/>-->
<corners android:radius="30px"
/>
</shape>

View File

@@ -0,0 +1,31 @@
<?xml version="1.0" encoding="utf-8"?>
<layer-list xmlns:android="http://schemas.android.com/apk/res/android">
<item android:id="@android:id/background">
<shape>
<corners
android:radius="30px"
/>
<solid android:color="#3B4577"/>
<stroke
android:color="#7CF6FF"
android:width="1.5px"
/>
</shape>
</item>
<item android:id="@android:id/secondaryProgress">
<scale android:scaleWidth="100%">
<shape>
<corners android:topRightRadius="30px"
android:bottomRightRadius="30px"/>
<solid android:color="#7CF6FF"/>
</shape>
</scale>
</item>
<item android:id="@android:id/progress">
<scale android:scaleWidth="100%"
android:drawable="@drawable/progress_bar_ct" />
</item>
</layer-list>

View File

@@ -0,0 +1,38 @@
<?xml version="1.0" encoding="utf-8"?>
<layer-list xmlns:android="http://schemas.android.com/apk/res/android">
<!-- 设置背景色 -->
<item android:id="@android:id/background">
<shape>
<corners android:radius="21px" />
<gradient
android:startColor="#3B4577"
android:endColor="#D71B0E"
/>
<stroke
android:color="#FF807C"
android:width="1.5px"
/>
</shape>
</item>
<!-- 设置进度条颜色 -->
<item android:id="@android:id/progress">
<clip>
<shape>
<corners
android:bottomLeftRadius="21px"
android:bottomRightRadius="21px"
android:topLeftRadius="21px"
android:topRightRadius="21px"
/>
<gradient
android:startColor="#06D1ED"
android:endColor="#06D1ED"
android:type="radial"
/>
</shape>
</clip>
</item>
</layer-list>

View File

@@ -66,7 +66,7 @@
android:gravity="center"
/>
<View
<ProgressBar
android:id="@+id/viewUploadProgress"
android:layout_width="791px"
android:layout_height="42px"
@@ -74,7 +74,10 @@
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintTop_toTopOf="parent"
android:layout_marginTop="275px"
android:background="#FFFFFFFF"
style="?android:attr/progressBarStyleHorizontal"
android:max="100"
android:progress="40"
android:progressDrawable="@drawable/progress_bar_drawable"
/>
<TextView

View File

@@ -66,7 +66,7 @@
android:gravity="center"
/>
<View
<ProgressBar
android:id="@+id/viewProgress"
android:layout_width="791px"
android:layout_height="42px"
@@ -74,7 +74,10 @@
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintTop_toTopOf="parent"
android:layout_marginTop="275px"
android:background="#FFFFFFFF"
style="?android:attr/progressBarStyleHorizontal"
android:max="100"
android:progress="0"
android:progressDrawable="@drawable/space_warning_progress_bg"
/>
<TextView

View File

@@ -2,12 +2,15 @@
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="wrap_content"
xmlns:app="http://schemas.android.com/apk/res-auto">
xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_marginTop="18dp"
android:layout_marginBottom="18dp"
>
<CheckBox
android:id="@+id/cbBagSelect"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_width="50dp"
android:layout_height="50dp"
android:button="@drawable/badcase_radio_button_style"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintBottom_toBottomOf="parent"
@@ -16,23 +19,32 @@
<EditText
android:id="@+id/etBagNameEdit"
android:layout_width="256dp"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:drawableEnd="@drawable/shape_size_check_false"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintLeft_toRightOf="@id/cbBagSelect"
app:layout_constraintRight_toLeftOf="@id/tvBagTime"
android:layout_marginStart="15dp"
android:layout_marginEnd="20dp"
android:background="@null"
android:drawableEnd="@drawable/icon_dev_status_un_fold"
android:textColor="#FFFFFFFF"
android:textSize="32dp"
android:maxLines="1"
android:ellipsize="end"
android:maxLength="9"
/>
<TextView
android:id="@+id/tvBagReportStatus"
android:layout_width="162dp"
android:layout_height="68dp"
android:background="@drawable/bag_report_button_bg"
android:background="@drawable/bag_reported_button_bg"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintRight_toRightOf="parent"
android:text="上报"
android:text="上报"
android:textColor="#FFFFFFFF"
android:textSize="28dp"
android:gravity="center"
@@ -40,12 +52,14 @@
<ImageView
android:id="@+id/ivBagAudio"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_width="44dp"
android:layout_height="44dp"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintRight_toLeftOf="@id/tvBagReportStatus"
android:src="@drawable/shape_size_check_false"
android:src="@drawable/icon_dev_status_un_fold"
android:visibility="invisible"
android:layout_marginEnd="20dp"
/>
<TextView
@@ -56,16 +70,18 @@
android:textSize="26dp"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintRight_toLeftOf="@id/ivBagAudio"
android:layout_marginEnd="20dp"
/>
<TextView
android:id="@+id/tvBagSize"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textColor="#FFFFFFFF"
android:textColor="#75FFFFFF"
android:textSize="26dp"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintRight_toLeftOf="@id/ivBagAudio"
app:layout_constraintLeft_toLeftOf="@id/tvBagTime"
/>
</androidx.constraintlayout.widget.ConstraintLayout>

View File

@@ -51,7 +51,7 @@
android:layout_marginTop="100dp"
android:progressDrawable="@drawable/space_percent_bg"
android:max="100"
android:progress="30"
android:progress="10"
/>
<View
@@ -77,7 +77,7 @@
/>
<TextView
android:id="@+id/tvUnusedSpaceContent"
android:id="@+id/tvFreeSpaceContent"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textColor="#FFFFFFFF"
@@ -88,13 +88,13 @@
/>
<View
android:id="@+id/viewUnusedSpace"
android:id="@+id/viewFreeSpace"
android:layout_width="23dp"
android:layout_height="23dp"
android:background="@drawable/unused_space_bg"
app:layout_constraintTop_toTopOf="@id/viewUsedSpace"
app:layout_constraintBottom_toBottomOf="@id/viewUsedSpace"
app:layout_constraintRight_toLeftOf="@id/tvUnusedSpaceContent"
app:layout_constraintRight_toLeftOf="@id/tvFreeSpaceContent"
android:layout_marginEnd="10dp"
/>
@@ -104,7 +104,7 @@
android:layout_height="80dp"
app:layout_constraintLeft_toLeftOf="@id/viewManagerTitleLine"
app:layout_constraintTop_toBottomOf="@id/viewUsedSpace"
android:layout_marginTop="30dp"
android:layout_marginTop="50dp"
android:background="@drawable/select_all_button_bg"
android:text="一键全选"
android:textColor="#FFFFFFFF"
@@ -119,7 +119,7 @@
app:layout_constraintTop_toTopOf="@id/tvSelectAll"
app:layout_constraintBottom_toBottomOf="@id/tvSelectAll"
app:layout_constraintLeft_toRightOf="@id/tvSelectAll"
android:layout_marginStart="20dp"
android:layout_marginStart="30dp"
android:background="@drawable/cancel_select_button_bg"
android:text="取消"
android:textColor="#FFFFFFFF"
@@ -144,7 +144,7 @@
android:layout_height="120dp"
app:layout_constraintLeft_toLeftOf="@id/pbSpacePercent"
app:layout_constraintBottom_toBottomOf="parent"
android:layout_marginBottom="50dp"
android:layout_marginBottom="120dp"
android:background="@drawable/upload_cloud_button_bg"
android:text="上云"
android:textColor="#FFFFFFFF"
@@ -174,6 +174,8 @@
app:layout_constraintRight_toRightOf="@id/pbSpacePercent"
app:layout_constraintTop_toBottomOf="@id/tvSelectAll"
app:layout_constraintBottom_toTopOf="@id/tvUploadCloud"
android:layout_marginTop="20dp"
android:layout_marginBottom="20dp"
/>
</merge>