[6.7.0][工具箱] feat: 修改工具箱里item 调试面板 / 运营面板 / 接管记录 / 杀死 APP / 上报 点击响应,增加 重启系统 / 一键停服的自定义按钮及逻辑;

This commit is contained in:
aibingbing
2024-09-20 19:31:02 +08:00
parent fc1e415f5c
commit b2176283d6
16 changed files with 769 additions and 18 deletions

View File

@@ -1,13 +1,27 @@
package com.mogo.eagle.core.function.hmi.bone.toolkit
import android.content.Context
import android.content.Intent
import android.os.Process
import android.view.View
import androidx.fragment.app.FragmentActivity
import com.mogo.commons.env.ProjectUtils
import com.mogo.eagle.core.data.config.FunctionBuildConfig
import com.mogo.eagle.core.function.api.och.IToolKitItemClickListener
import com.mogo.eagle.core.function.call.devatools.CallerDevaToolsManager
import com.mogo.eagle.core.function.hmi.R
import com.mogo.eagle.core.function.hmi.bone.toolkit.custom.ToolRestartSystemView
import com.mogo.eagle.core.function.hmi.bone.toolkit.custom.ToolStopServiceView
import com.mogo.eagle.core.function.hmi.ui.setting.SopView
import com.mogo.eagle.core.function.hmi.ui.setting.ToggleDebugView
import com.mogo.eagle.core.utilcode.mogo.AppIdentityModeUtils
import com.mogo.eagle.core.utilcode.util.ActivityUtils
import com.mogo.eagle.core.utilcode.util.NetworkUtils
import com.mogo.eagle.core.utilcode.util.ToastUtils
import com.zhjt.mogo_core_function_devatools.badcase.biz.AIDataCollectWindow
import com.zhjt.mogo_core_function_devatools.badcase.consts.BadCaseConfig
import java.util.concurrent.ConcurrentHashMap
import kotlin.system.exitProcess
object ToolKitDataManager : IToolKitItemClickListener {
const val TAG = "ToolKitDataManager"
@@ -19,7 +33,8 @@ object ToolKitDataManager : IToolKitItemClickListener {
TAKE_OVER_HISTORY, //接管记录
KILL_APP, //杀死 APP
RESTART_SYSTEM, //重启系统
STOP_SERVICE //停止服务
STOP_SERVICE, //停止服务
AI_REPORT //AI数据采集
}
private val listeners by lazy { ConcurrentHashMap<String, IToolKitItemClickListener>() }
@@ -37,9 +52,9 @@ object ToolKitDataManager : IToolKitItemClickListener {
listeners.remove(tag)
}
fun invokeItemClick(toolTag: String) {
fun invokeItemClick(toolTag: String, ctx: Context?) {
listeners.values.forEach { itx ->
itx.onItemClick(toolTag)
itx.onItemClick(toolTag, ctx)
}
}
@@ -57,21 +72,31 @@ object ToolKitDataManager : IToolKitItemClickListener {
ToolTypeEnum.OPERATION_PANEL.name,
getDefaultItemView(ctx, "运营面板", R.drawable.icon_toolkit_item_operation_panel)
)
it += ToolKitBean(
ToolTypeEnum.TAKE_OVER_HISTORY.name,
getDefaultItemView(ctx, "接管记录", R.drawable.icon_toolkit_item_take_over_history)
)
if (ProjectUtils.isSaas()) {
it += ToolKitBean(
ToolTypeEnum.TAKE_OVER_HISTORY.name,
getDefaultItemView(
ctx,
"接管记录",
R.drawable.icon_toolkit_item_take_over_history
)
)
}
it += ToolKitBean(
ToolTypeEnum.KILL_APP.name,
getDefaultItemView(ctx, "杀死APP", R.drawable.icon_toolkit_item_kill_app)
)
it += ToolKitBean(
ToolTypeEnum.RESTART_SYSTEM.name,
getDefaultItemView(ctx, "重启系统", R.drawable.icon_toolkit_item_restart_system)
getRestartSystemItemView(ctx)
)
it += ToolKitBean(
ToolTypeEnum.STOP_SERVICE.name,
getDefaultItemView(ctx, "停止服务", R.drawable.icon_toolkit_item_stop_service)
getStopServiceItemView(ctx)
)
it += ToolKitBean(
ToolTypeEnum.AI_REPORT.name,
getDefaultItemView(ctx, "上报", R.drawable.icon_toolkit_item_ai_report)
)
}
addListener(TAG, this)
@@ -94,10 +119,71 @@ object ToolKitDataManager : IToolKitItemClickListener {
}
}
override fun onItemClick(toolTag: String) {
ToastUtils.showShort(toolTag)
when (toolTag) {
/**
* 一件停服 自定义view
*/
private fun getStopServiceItemView(context: Context): View {
return ToolStopServiceView(context)
}
/**
* 重启系统 自定义view
*/
private fun getRestartSystemItemView(context: Context): View {
return ToolRestartSystemView(context)
}
override fun onItemClick(toolTag: String, ctx: Context?) {
//ToastUtils.showShort(toolTag)
when (toolTag) {
ToolTypeEnum.DEBUG_PANEL.name -> {
ctx?.also {
ToggleDebugView.toggleDebugView.toggle(it)
}
}
ToolTypeEnum.OPERATION_PANEL.name -> {
ctx?.also {
SopView.sopView.toggle(it)
}
}
ToolTypeEnum.TAKE_OVER_HISTORY.name -> {
ctx?.also {
CallerDevaToolsManager.showTakeOverRecordView(it)
}
}
ToolTypeEnum.KILL_APP.name -> {
Intent(Intent.ACTION_MAIN).apply {
addCategory(Intent.CATEGORY_HOME)
flags = Intent.FLAG_ACTIVITY_NEW_TASK
ActivityUtils.startActivity(this)
Process.killProcess(Process.myPid())
exitProcess(0)
}
}
ToolTypeEnum.AI_REPORT.name -> {
(ctx as? FragmentActivity)?.also {
if (NetworkUtils.isConnected()) {
if (BadCaseConfig.dockerVersion != null) {
val aiDataCollectWindow = AIDataCollectWindow(it)
aiDataCollectWindow.setClickListener(object :
AIDataCollectWindow.ClickListener {
override fun closeWindow() {
aiDataCollectWindow.hideFloatWindow()
}
})
aiDataCollectWindow.showFloatWindow()
} else {
ToastUtils.showShort("工控机连接状态异常")
}
} else {
ToastUtils.showShort("网络异常,请检查网络")
}
}
}
}
}
}

View File

@@ -6,6 +6,7 @@ import android.view.ViewGroup
import android.widget.FrameLayout
import androidx.recyclerview.widget.RecyclerView
import com.mogo.eagle.core.function.hmi.R
import com.mogo.eagle.core.utilcode.mogo.view.OnPreventFastClickListener
class ToolKitListAdapter(var items: List<ToolKitBean>) :
RecyclerView.Adapter<RecyclerView.ViewHolder>() {
@@ -31,9 +32,14 @@ class ToolKitListAdapter(var items: List<ToolKitBean>) :
(it.parent as ViewGroup).removeView(it)
}
holder.containerView.addView(it)
it.setOnClickListener {
ToolKitDataManager.invokeItemClick(data.toolTag)
}
it.setOnClickListener(object : OnPreventFastClickListener(500L) {
override fun onClickImpl(v: View?) {
ToolKitDataManager.invokeItemClick(
data.toolTag,
holder.itemView.context
)
}
})
}
}
}

View File

@@ -0,0 +1,103 @@
package com.mogo.eagle.core.function.hmi.bone.toolkit.custom
import android.content.Context
import android.util.AttributeSet
import android.view.LayoutInflater
import androidx.constraintlayout.widget.ConstraintLayout
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.function.hmi.R
import com.mogo.eagle.core.function.hmi.ui.tools.DockerRebootDialog
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.ThreadUtils
import com.mogo.eagle.core.utilcode.util.ToastUtils
import com.zhjt.mogo.adas.data.AdasConstants
import kotlinx.android.synthetic.main.view_tool_restart_system.view.containerView
class ToolRestartSystemView @JvmOverloads constructor(
context: Context,
attrs: AttributeSet? = null,
defStyleAttr: Int = 0
) : ConstraintLayout(context, attrs, defStyleAttr), IMoGoAutopilotStatusListener {
companion object {
const val TAG = "ToolRestartSystemView"
}
//重启系统对话框
private var dockerRebootDialog: DockerRebootDialog? = null
private var connectStatus: Boolean = false //与工控机的连接状态
init {
LayoutInflater.from(context).inflate(R.layout.view_tool_restart_system, this, true)
initView()
}
private fun initView() {
//重启系统
containerView.setOnClickListener {
showRebootDialog()
}
}
/**
* 展示系统重启确认窗
*/
private fun showRebootDialog() {
if (!connectStatus) {
ToastUtils.showShort("尚未连接工控机,无法重启系统")
return
}
//dialog
if (dockerRebootDialog == null) {
dockerRebootDialog = DockerRebootDialog(context)
dockerRebootDialog?.setClickListener(object : DockerRebootDialog.ClickListener {
override fun confirm() {
if (CallerAutoPilotStatusListenerManager.getState() == 2) {
//当前处于自动驾驶状态不可进行重启Toast提示
ToastUtils.showShort("请先退出自动驾驶状态")
} else {
//确认重启
CallerLogger.d("$M_HMI$TAG", "reboot confirm")
CallerAutoPilotControlManager.sendIpcReboot()
ToastUtils.showLong("重启命令已发送")
}
}
override fun cancel() {
//取消重启
CallerLogger.d("$M_HMI$TAG", "reboot cancel")
}
})
}
dockerRebootDialog?.showUpgradeDialog()
}
override fun onAttachedToWindow() {
super.onAttachedToWindow()
CallerAutoPilotStatusListenerManager.addListener(TAG, this)
}
override fun onDetachedFromWindow() {
super.onDetachedFromWindow()
CallerAutoPilotStatusListenerManager.removeListener(TAG)
}
override fun onAutopilotIpcConnectStatusChanged(
status: AdasConstants.IpcConnectionStatus,
reason: String?
) {
super.onAutopilotIpcConnectStatusChanged(status, reason)
ThreadUtils.runOnUiThread {
setViewStatus(status == AdasConstants.IpcConnectionStatus.CONNECTED)
}
}
private fun setViewStatus(connectInfo: Boolean) {
connectStatus = connectInfo
}
}

View File

@@ -0,0 +1,431 @@
package com.mogo.eagle.core.function.hmi.bone.toolkit.custom
import android.animation.ObjectAnimator
import android.animation.ValueAnimator
import android.content.Context
import android.util.AttributeSet
import android.view.LayoutInflater
import android.view.View
import android.view.animation.LinearInterpolator
import androidx.constraintlayout.widget.ConstraintLayout
import androidx.core.content.ContextCompat
import com.mogo.commons.voice.AIAssist
import com.mogo.eagle.core.data.app.AppConfigInfo
import com.mogo.eagle.core.data.enums.EventTypeEnumNew
import com.mogo.eagle.core.data.msgbox.MsgBoxBean
import com.mogo.eagle.core.data.msgbox.MsgBoxType
import com.mogo.eagle.core.data.msgbox.V2XMsg
import com.mogo.eagle.core.function.api.autopilot.IMoGoAutopilotStatusListener
import com.mogo.eagle.core.function.api.autopilot.IMoGoReceiveReceivedAckListener
import com.mogo.eagle.core.function.api.devatools.IPowerOffListener
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.CallerReceiveReceivedAckListenerManager
import com.mogo.eagle.core.function.call.devatools.CallerDevaToolsManager
import com.mogo.eagle.core.function.call.devatools.CallerPowerOffManager
import com.mogo.eagle.core.function.call.msgbox.CallerMsgBoxManager.saveMsgBox
import com.mogo.eagle.core.function.hmi.R
import com.mogo.eagle.core.function.hmi.ui.utils.HmiActionLog.Companion.hmiAction
import com.mogo.eagle.core.utilcode.mogo.logger.scene.SceneConstant.Companion.M_HMI
import com.mogo.eagle.core.utilcode.util.ParseVersionUtils
import com.mogo.eagle.core.utilcode.util.ThreadUtils
import com.mogo.eagle.core.utilcode.util.ToastUtils
import com.zhjt.mogo.adas.common.MessageType
import com.zhjt.mogo.adas.data.AdasConstants
import com.zhjt.mogo.adas.data.bean.ReceivedAck
import kotlinx.android.synthetic.main.view_tool_stop_service.view.tvCheckShutDown
import kotlinx.android.synthetic.main.view_tool_stop_service.view.tvCountDown
import kotlinx.android.synthetic.main.view_tool_stop_service.view.tvCountDownUnit
import kotlinx.android.synthetic.main.view_tool_stop_service.view.viewCheckShutDown
import kotlinx.android.synthetic.main.view_tool_stop_service.view.viewProgress
import kotlinx.android.synthetic.main.view_tool_stop_service.view.viewProgressBackground
class ToolStopServiceView @JvmOverloads constructor(
context: Context,
attrs: AttributeSet? = null,
defStyleAttr: Int = 0
) : ConstraintLayout(context, attrs, defStyleAttr), IMoGoAutopilotStatusListener,
IPowerOffListener, IMoGoReceiveReceivedAckListener {
companion object {
const val TAG = "ToolStopServiceView"
}
//重启系统对话框
private var connectStatus: Boolean = false //与工控机的连接状态
private var isExecutingPowerOff: Boolean = false //是否正在下发一键停服命令
private var isPowerOffCountDown: Boolean = false //一键停服是否处于1分钟倒计时
private var powerOffMsgId: Long = -1 //一键停服命令下发Id
private var progressAnimator: ObjectAnimator? = null //一键停服命令倒计时
/**
* 停止域控服务状态
* 0准备停服 1停服命令下发中 2停服命令下发成功 3停服命令下发失败
* 4停服命令下发超时 5停服中 6停服成功 7停服成功不可点击
*/
private var powerOffStatus: Int = 0
init {
LayoutInflater.from(context).inflate(R.layout.view_tool_stop_service, this, true)
initView()
}
private fun initView() {
//一键停服
viewCheckShutDown.setOnClickListener {
powerOff()
}
tvCheckShutDown.setOnClickListener {
powerOff()
}
CallerDevaToolsManager.getPowerOffStatus()?.let {
powerOffStatus = it
}
when (powerOffStatus) {
//准备停服
0 -> {
viewCheckShutDown.setImageDrawable(
ContextCompat.getDrawable(
context,
R.drawable.icon_toolkit_item_stop_service
)
)
viewCheckShutDown.isClickable = true
}
//停服命令下发中
1 -> {
isExecutingPowerOff = true
}
//停服命令下发成功
2 -> {
viewProgressBackground.visibility = View.VISIBLE
viewProgress.visibility = View.VISIBLE
tvCountDown.visibility = View.VISIBLE
tvCountDownUnit.visibility = View.VISIBLE
//开始旋转动画
if (progressAnimator == null) {
progressAnimator = ObjectAnimator.ofFloat(viewProgress, "rotation", 0f, 360f)
}
progressAnimator?.interpolator = LinearInterpolator()
progressAnimator?.repeatCount = ValueAnimator.INFINITE //无限循环
progressAnimator?.duration = 10000 //设置持续时间
progressAnimator?.startDelay = 0
progressAnimator?.start()
//一键停服倒计时中
isPowerOffCountDown = true
}
//停服命令下发失败
3 -> {
viewCheckShutDown.setImageDrawable(
ContextCompat.getDrawable(
context,
R.drawable.icon_toolkit_item_stop_service_fail
)
)
}
//停服命令下发超时
4 -> {
//将图标改为失败
viewCheckShutDown.setImageDrawable(
ContextCompat.getDrawable(
context,
R.drawable.icon_toolkit_item_stop_service_fail
)
)
}
//停服中
5 -> {
isPowerOffCountDown = true
viewCheckShutDown.setImageDrawable(
ContextCompat.getDrawable(
context,
R.drawable.icon_toolkit_item_stop_service_background
)
)
viewProgressBackground.visibility = View.VISIBLE
viewProgress.visibility = View.VISIBLE
tvCountDown.visibility = View.VISIBLE
tvCountDownUnit.visibility = View.VISIBLE
//开始旋转动画
if (progressAnimator == null) {
progressAnimator = ObjectAnimator.ofFloat(viewProgress, "rotation", 0f, 360f)
}
progressAnimator?.interpolator = LinearInterpolator()
progressAnimator?.repeatCount = ValueAnimator.INFINITE //无限循环
progressAnimator?.duration = 10000 //设置持续时间
progressAnimator?.startDelay = 0
progressAnimator?.start()
}
//停服成功
6 -> {
//停止一键停服进度属性动画
progressAnimator?.cancel()
//隐藏一键停服进度视图
viewProgressBackground.visibility = View.GONE
viewProgress.visibility = View.GONE
tvCountDown.visibility = View.GONE
tvCountDownUnit.visibility = View.GONE
//一键停服命令倒计时结束变为成功状态并且发送1s倒计时
viewCheckShutDown.setImageDrawable(
ContextCompat.getDrawable(
context,
R.drawable.icon_toolkit_item_stop_service_success
)
)
isPowerOffCountDown = false
}
//停服成功不可点击
7 -> {
//将倒计时内容隐藏
viewProgressBackground.visibility = View.GONE
viewProgress.visibility = View.GONE
tvCountDown.visibility = View.GONE
tvCountDownUnit.visibility = View.GONE
//停服成功,将按钮置为不可点击状态
viewCheckShutDown.setImageDrawable(
ContextCompat.getDrawable(
context,
R.drawable.icon_toolkit_item_stop_service_complete
)
)
viewCheckShutDown.isClickable = false
isPowerOffCountDown = false
}
}
}
/**
* 一键停服
*/
private fun powerOff() {
if (!connectStatus) {
ToastUtils.showShort("尚未连接工控机,无法下发一键停服命令")
return
}
if (AppConfigInfo.dockerVersion.isEmpty()) {
ToastUtils.showShort("尚未连接工控机,无法下发一键停服命令")
return
}
if (ParseVersionUtils.parseVersion(true, AppConfigInfo.dockerVersion) < 40100) {
ToastUtils.showShort("此域控版本不支持一键停服功能最低支持版本为4.1.0")
return
}
if (CallerAutoPilotStatusListenerManager.getState() == 2) {
//当前处于自动驾驶状态不可进行重启Toast提示
ToastUtils.showShort("请先退出自动驾驶状态")
return
}
if (isExecutingPowerOff) {
//一键停服命令下发执行中
ToastUtils.showShort("一键停服命令下发中,请勿重复点击")
return
}
if (isPowerOffCountDown) {
//系统停服中
ToastUtils.showShort("系统停服中,请勿重复点击")
return
}
//将是否正在下发一键停服命令标签改为true
isExecutingPowerOff = true
CallerDevaToolsManager.setPowerOffStatus(1)
hmiAction("$M_HMI$TAG", mapOf("powerOff" to true))
//系统命令请求 关机
powerOffMsgId = CallerAutoPilotControlManager.sendIpcPowerOff()
hmiAction("$M_HMI$TAG", mapOf("powerOffID" to powerOffMsgId))
//开始执行10秒等待倒计时
CallerDevaToolsManager.startCommandWaitCountDown()
}
override fun onAttachedToWindow() {
super.onAttachedToWindow()
CallerAutoPilotStatusListenerManager.addListener(TAG, this)
CallerPowerOffManager.addListener(TAG, this)
CallerReceiveReceivedAckListenerManager.addListener(TAG, this)
}
override fun onDetachedFromWindow() {
super.onDetachedFromWindow()
CallerAutoPilotStatusListenerManager.removeListener(TAG)
CallerPowerOffManager.removeListener(TAG)
CallerReceiveReceivedAckListenerManager.removeListener(TAG)
}
override fun onAutopilotIpcConnectStatusChanged(
status: AdasConstants.IpcConnectionStatus,
reason: String?
) {
super.onAutopilotIpcConnectStatusChanged(status, reason)
ThreadUtils.runOnUiThread {
setViewStatus(status == AdasConstants.IpcConnectionStatus.CONNECTED)
}
}
private fun setViewStatus(connectInfo: Boolean) {
connectStatus = connectInfo
//下发一键停服命令后又和域控重新连接
if ((powerOffStatus == 6 || powerOffStatus == 7) && connectStatus) {
CallerDevaToolsManager.setPowerOffStatus(0)
viewCheckShutDown.setImageDrawable(
ContextCompat.getDrawable(
context,
R.drawable.icon_toolkit_item_stop_service
)
)
viewCheckShutDown.isClickable = true
}
}
/**
* 一键停服调用SSM停服命令超时
*/
override fun commandTimeout() {
//停止命令超时倒计时
CallerDevaToolsManager.stopCommandWaitCountDown()
/**
* 如果点击一键停服按钮10秒后是否正在执行命令的标签仍为true代表域控未返回执行结果
* 此时应该将按钮状态短暂置为失败之后再置为常态并将此标签置为false
*/
if (isExecutingPowerOff) {
//更改标签状态
isExecutingPowerOff = false
CallerDevaToolsManager.setPowerOffStatus(4)
//将图标改为失败
viewCheckShutDown.setImageDrawable(
ContextCompat.getDrawable(
context,
R.drawable.icon_toolkit_item_stop_service_fail
)
)
//执行1秒倒计时命令
CallerDevaToolsManager.statusChangeCountDown(false)
}
}
/**
* 一键停服车辆下电等待倒计时
*/
override fun powerDownTick(second: Int) {
tvCountDown.text = second.toString()
CallerDevaToolsManager.setPowerOffStatus(5)
}
/**
* 一键停服车辆下电等待倒计时结束
*/
override fun powerDownFinish() {
CallerDevaToolsManager.setPowerOffStatus(6)
//停止一键停服进度属性动画
progressAnimator?.cancel()
//隐藏一键停服进度视图
viewProgressBackground.visibility = View.GONE
viewProgress.visibility = View.GONE
tvCountDown.visibility = View.GONE
tvCountDownUnit.visibility = View.GONE
//一键停服命令倒计时结束变为成功状态并且发送1s倒计时
viewCheckShutDown.setImageDrawable(
ContextCompat.getDrawable(
context,
R.drawable.icon_toolkit_item_stop_service_success
)
)
isPowerOffCountDown = false
//执行1秒倒计时命令
CallerDevaToolsManager.statusChangeCountDown(true)
}
/**
* 一键停服状态按钮变更通知
*/
override fun statusChange(isSuccess: Boolean) {
CallerDevaToolsManager.stopStatusCountDown()
if (isSuccess) {
//将倒计时内容隐藏
viewProgressBackground.visibility = View.GONE
viewProgress.visibility = View.GONE
tvCountDown.visibility = View.GONE
tvCountDownUnit.visibility = View.GONE
//停服成功,将按钮置为不可点击状态
viewCheckShutDown.setImageDrawable(
ContextCompat.getDrawable(
context,
R.drawable.icon_toolkit_item_stop_service_complete
)
)
viewCheckShutDown.isClickable = false
CallerDevaToolsManager.setPowerOffStatus(7)
} else {
//停服命令下发失败,将按钮置为常态,可点击
viewCheckShutDown.setImageDrawable(
ContextCompat.getDrawable(
context,
R.drawable.icon_toolkit_item_stop_service
)
)
viewCheckShutDown.isClickable = true
}
}
/**
* 命令下发回执
*/
override fun onReceiveReceivedAck(receivedAck: ReceivedAck) {
ThreadUtils.runOnUiThread {
if (receivedAck.messageType == MessageType.TYPE_SEND_SYSTEM_CMD_REQ && receivedAck.msgId == powerOffMsgId) {
isExecutingPowerOff = false
//停止命令超时倒计时
CallerDevaToolsManager.stopCommandWaitCountDown()
if (receivedAck.status == ReceivedAck.Status.NORMAL) {
//一键停服命令回执成功则正常进入停服阶段中1分钟倒计时并且TTS和消息盒子提示
CallerDevaToolsManager.setPowerOffStatus(2)
AIAssist.getInstance(context).speakTTSVoice("请等待1分钟再执行车辆下电")
saveMsgBox(
MsgBoxBean(
MsgBoxType.V2X, V2XMsg(
EventTypeEnumNew.TYPE_POWER_OFF_TIP.poiType,
EventTypeEnumNew.TYPE_POWER_OFF_TIP.content,
EventTypeEnumNew.TYPE_POWER_OFF_TIP.tts
)
)
)
viewCheckShutDown.setImageDrawable(
ContextCompat.getDrawable(
context,
R.drawable.icon_toolkit_item_stop_service_background
)
)
viewProgressBackground.visibility = View.VISIBLE
viewProgress.visibility = View.VISIBLE
tvCountDown.visibility = View.VISIBLE
tvCountDownUnit.visibility = View.VISIBLE
//开始旋转动画
if (progressAnimator == null) {
progressAnimator =
ObjectAnimator.ofFloat(viewProgress, "rotation", 0f, 360f)
}
progressAnimator?.interpolator = LinearInterpolator()
progressAnimator?.repeatCount = ValueAnimator.INFINITE //无限循环
progressAnimator?.duration = 10000 //设置持续时间
progressAnimator?.startDelay = 0
progressAnimator?.start()
//开始60S倒计时
CallerDevaToolsManager.startPowerDownCountDown()
//一键停服倒计时中
isPowerOffCountDown = true
} else {
//一键停服命令回执失败,则走失败流程
CallerDevaToolsManager.setPowerOffStatus(3)
viewCheckShutDown.setImageDrawable(
ContextCompat.getDrawable(
context,
R.drawable.icon_toolkit_item_stop_service_fail
)
)
//执行1秒倒计时命令
CallerDevaToolsManager.statusChangeCountDown(false)
}
}
}
}
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 19 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 23 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.6 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 23 KiB

View File

@@ -2,4 +2,5 @@
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/container"
android:layout_width="match_parent"
android:layout_height="wrap_content" />
android:layout_height="wrap_content"
android:layout_gravity="center" />

View File

@@ -13,7 +13,7 @@
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintTop_toTopOf="parent"
tools:src="@drawable/icon_toolkit_item_tiaoshi" />
tools:src="@drawable/icon_toolkit_item_debug_panel" />
<TextView
android:id="@+id/tvTitleView"

View File

@@ -0,0 +1,36 @@
<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout 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/containerView"
android:layout_width="match_parent"
android:layout_height="match_parent">
<ImageView
android:id="@+id/btnImageView"
android:layout_width="@dimen/dp_160"
android:layout_height="@dimen/dp_160"
android:scaleType="fitXY"
android:src="@drawable/icon_toolkit_item_restart_system"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintTop_toTopOf="parent"
tools:src="@drawable/icon_toolkit_item_debug_panel" />
<TextView
android:id="@+id/tvTitleView"
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="@string/check_system_reboot"
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/btnImageView"
tools:text="重启系统" />
</androidx.constraintlayout.widget.ConstraintLayout>

View File

@@ -0,0 +1,86 @@
<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout 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/clCheckSystem"
android:layout_width="match_parent"
android:layout_height="match_parent">
<ImageView
android:id="@+id/viewCheckShutDown"
android:layout_width="@dimen/dp_160"
android:layout_height="@dimen/dp_160"
android:contentDescription="@string/check_system_shut_down"
android:scaleType="fitXY"
android:src="@drawable/icon_toolkit_item_stop_service"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintTop_toTopOf="parent"
tools:src="@drawable/icon_toolkit_item_stop_service_background" />
<ImageView
android:id="@+id/viewProgressBackground"
android:layout_width="@dimen/dp_84"
android:layout_height="@dimen/dp_84"
android:layout_marginLeft="@dimen/dp_43"
android:layout_marginTop="@dimen/dp_30"
android:src="@drawable/icon_toolkit_item_stop_service_process_background"
android:visibility="gone"
app:layout_constraintLeft_toLeftOf="@id/viewCheckShutDown"
app:layout_constraintTop_toTopOf="@id/viewCheckShutDown"
tools:visibility="visible" />
<ImageView
android:id="@+id/viewProgress"
android:layout_width="@dimen/dp_84"
android:layout_height="@dimen/dp_84"
android:layout_marginLeft="@dimen/dp_43"
android:layout_marginTop="@dimen/dp_30"
android:src="@drawable/icon_toolkit_item_stop_service_process"
android:visibility="gone"
app:layout_constraintLeft_toLeftOf="@id/viewCheckShutDown"
app:layout_constraintTop_toTopOf="@id/viewCheckShutDown"
tools:visibility="visible" />
<TextView
android:id="@+id/tvCountDown"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textColor="@color/white"
android:textSize="@dimen/sp_28"
android:visibility="gone"
app:layout_constraintBottom_toBottomOf="@id/viewProgress"
app:layout_constraintEnd_toEndOf="@id/viewProgress"
app:layout_constraintStart_toStartOf="@id/viewProgress"
app:layout_constraintTop_toTopOf="@id/viewProgress"
tools:text="20"
tools:visibility="visible" />
<TextView
android:id="@+id/tvCountDownUnit"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="s"
android:textColor="#B2FFFFFF"
android:textSize="@dimen/sp_20"
android:visibility="gone"
app:layout_constraintBottom_toBottomOf="@id/tvCountDown"
app:layout_constraintStart_toEndOf="@id/tvCountDown"
tools:visibility="visible" />
<TextView
android:id="@+id/tvCheckShutDown"
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="@string/check_system_shut_down"
android:textColor="@color/color_FFFFFF"
android:textSize="@dimen/sp_38"
app:layout_constraintLeft_toLeftOf="@id/viewCheckShutDown"
app:layout_constraintRight_toRightOf="@id/viewCheckShutDown"
app:layout_constraintTop_toBottomOf="@id/viewCheckShutDown" />
</androidx.constraintlayout.widget.ConstraintLayout>