refactor(task): 重构复合材料铺贴任务流程
- 将任务列表注释更新为包含决策中心功能 - 移除不必要的导入和枚举定义,简化 CompositeLayupTaskActivity 类结构 - 替换基础 Activity 为 BaseListFormLayoutNormalActivity 以支持分页功能 - 更新适配器实现为 BasePagedAdapter 和 CommonPagedAdapter - 简化屏幕模式管理,移除复杂的 UI 状态切换逻辑 - 优化拍照和识别流程,直接跳转到结果页面 - 添加 CompositeLayupResultActivity 来处理识别结果和铺贴过程 - 更新视图模型继承自 BaseListViewModel 并优化数据加载逻辑 - 修改布局文件以匹配新的 UI 流程设计 - 在 AndroidManifest 中注册新的结果活动页面
这个提交包含在:
父节点
47fa2c4464
当前提交
089c807340
@ -56,7 +56,7 @@ android {
|
|||||||
buildConfigField("String", "API_COOKIE", "\"__itrace_wid=87125211-8742-4f12-b5ca-32b9b6c860e4; locale=zh-Hans; _webtracing_device_id=t_13501877-b9b303fc-d3f52eb530e026b0\"")
|
buildConfigField("String", "API_COOKIE", "\"__itrace_wid=87125211-8742-4f12-b5ca-32b9b6c860e4; locale=zh-Hans; _webtracing_device_id=t_13501877-b9b303fc-d3f52eb530e026b0\"")
|
||||||
buildConfigField("String", "API_ENVIRONMENT", "\"2\"")
|
buildConfigField("String", "API_ENVIRONMENT", "\"2\"")
|
||||||
buildConfigField("String", "API_CURRENT_USER_ID", "\"rokid\"")
|
buildConfigField("String", "API_CURRENT_USER_ID", "\"rokid\"")
|
||||||
// 任务列表+审核+fo
|
// 任务列表+审核+fo+决策中心
|
||||||
buildConfigField("String", "API_BASE_URL_1", "\"http://10.230.4.80:12119\"")
|
buildConfigField("String", "API_BASE_URL_1", "\"http://10.230.4.80:12119\"")
|
||||||
// 意图识别
|
// 意图识别
|
||||||
buildConfigField("String", "API_BASE_URL_2", "\"http://10.230.4.80\"")
|
buildConfigField("String", "API_BASE_URL_2", "\"http://10.230.4.80\"")
|
||||||
|
|||||||
@ -78,6 +78,9 @@
|
|||||||
<activity
|
<activity
|
||||||
android:name=".ui.CompositeLayupTaskActivity"
|
android:name=".ui.CompositeLayupTaskActivity"
|
||||||
android:exported="false" />
|
android:exported="false" />
|
||||||
|
<activity
|
||||||
|
android:name=".ui.CompositeLayupResultActivity"
|
||||||
|
android:exported="false" />
|
||||||
<activity
|
<activity
|
||||||
android:name=".ui.ChatActivity"
|
android:name=".ui.ChatActivity"
|
||||||
android:exported="false" />
|
android:exported="false" />
|
||||||
|
|||||||
@ -0,0 +1,319 @@
|
|||||||
|
package com.nova.brain.glass.ui
|
||||||
|
|
||||||
|
import android.content.Intent
|
||||||
|
import android.os.Environment
|
||||||
|
import android.os.Handler
|
||||||
|
import android.os.Looper
|
||||||
|
import androidx.lifecycle.ViewModelProvider
|
||||||
|
import androidx.recyclerview.widget.LinearLayoutManager
|
||||||
|
import androidx.recyclerview.widget.RecyclerView
|
||||||
|
import com.nova.brain.glass.R
|
||||||
|
import com.nova.brain.glass.databinding.ActivityCompositeLayupResultBinding
|
||||||
|
import com.nova.brain.glass.helper.GlassMediaServiceHelper
|
||||||
|
import com.nova.brain.glass.helper.OfflineCmdListener
|
||||||
|
import com.nova.brain.glass.helper.OfflineCmdServiceHelper
|
||||||
|
import com.nova.brain.glass.model.ItemItem
|
||||||
|
import com.nova.brain.glass.viewmodel.CompositeLayupResultState
|
||||||
|
import com.nova.brain.glass.viewmodel.CompositeLayupResultVM
|
||||||
|
import com.rokid.security.glass3.sdk.base.data.media.PhotoResolution
|
||||||
|
import com.rokid.security.system.server.media.callback.PhotoFileCallback
|
||||||
|
import com.xuqm.base.adapter.CommonAdapter
|
||||||
|
import com.xuqm.base.adapter.ViewHolder
|
||||||
|
import com.xuqm.base.extensions.showMessage
|
||||||
|
import com.xuqm.base.ui.BaseActivity
|
||||||
|
import java.io.File
|
||||||
|
import java.util.UUID
|
||||||
|
|
||||||
|
class CompositeLayupResultActivity : BaseActivity<ActivityCompositeLayupResultBinding>() {
|
||||||
|
|
||||||
|
override fun getLayoutId(): Int = R.layout.activity_composite_layup_result
|
||||||
|
override fun fullscreen(): Boolean = true
|
||||||
|
|
||||||
|
private val viewModel: CompositeLayupResultVM by lazy {
|
||||||
|
ViewModelProvider(this)[CompositeLayupResultVM::class.java]
|
||||||
|
}
|
||||||
|
|
||||||
|
private enum class UiMode {
|
||||||
|
RECOGNIZE_SUCCESS,
|
||||||
|
RECOGNIZE_FAILED,
|
||||||
|
LAYUP_PROMPT,
|
||||||
|
LAYUP_WORKING,
|
||||||
|
CONFIRM_FINISH,
|
||||||
|
COMPLETE
|
||||||
|
}
|
||||||
|
|
||||||
|
private val taskNo: String by lazy { intent.getStringExtra(EXTRA_TASK_NO).orEmpty() }
|
||||||
|
private val taskName: String by lazy { intent.getStringExtra(EXTRA_TASK_NAME).orEmpty() }
|
||||||
|
private val partNo: String by lazy { intent.getStringExtra(EXTRA_PART_NO).orEmpty() }
|
||||||
|
private val photoPath: String by lazy { intent.getStringExtra(EXTRA_PHOTO_PATH).orEmpty() }
|
||||||
|
private val stepSeq: Int by lazy { intent.getIntExtra(EXTRA_STEP_SEQ, 1) }
|
||||||
|
private val totalSteps: Int by lazy { intent.getIntExtra(EXTRA_TOTAL_STEPS, 1) }
|
||||||
|
private val direction: String by lazy { intent.getStringExtra(EXTRA_DIRECTION).orEmpty() }
|
||||||
|
private val vacuum: String by lazy { intent.getStringExtra(EXTRA_VACUUM).orEmpty() }
|
||||||
|
private val uiHandler = Handler(Looper.getMainLooper())
|
||||||
|
|
||||||
|
private var isPhoto = false
|
||||||
|
private var uiMode = UiMode.RECOGNIZE_SUCCESS
|
||||||
|
|
||||||
|
private val layupWorkingRunnable: Runnable = Runnable {
|
||||||
|
if (uiMode == UiMode.LAYUP_PROMPT) {
|
||||||
|
applyMode(UiMode.LAYUP_WORKING)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
private val completeRunnable: Runnable = Runnable {
|
||||||
|
if (uiMode == UiMode.COMPLETE) {
|
||||||
|
goTaskList()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private val listener: OfflineCmdListener = object : OfflineCmdListener {
|
||||||
|
override fun onOfflineCmd(cmd: String) {
|
||||||
|
runOnUiThread {
|
||||||
|
when (cmd) {
|
||||||
|
"退出", "返回", "退回" -> finish()
|
||||||
|
"重拍", "重新拍照", "重新拍摄" -> if (uiMode == UiMode.RECOGNIZE_FAILED) retake()
|
||||||
|
"开始铺贴" -> if (uiMode == UiMode.RECOGNIZE_SUCCESS) startLayup()
|
||||||
|
"确认并继续", "继续" -> if (uiMode == UiMode.CONFIRM_FINISH) confirmAndContinue()
|
||||||
|
"否" -> if (uiMode == UiMode.CONFIRM_FINISH) applyMode(UiMode.LAYUP_WORKING)
|
||||||
|
"完成", "完成任务" -> if (uiMode == UiMode.CONFIRM_FINISH && stepSeq >= totalSteps) finishCurrentTask()
|
||||||
|
"返回任务列表" -> if (uiMode == UiMode.COMPLETE) goTaskList()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private val photoCallbackId = UUID.randomUUID().toString()
|
||||||
|
private val photoCallback: PhotoFileCallback = object : PhotoFileCallback.Stub() {
|
||||||
|
override fun onTakePhoto(path: String) = Unit
|
||||||
|
|
||||||
|
override fun getCallbackId(): String = photoCallbackId
|
||||||
|
|
||||||
|
override fun onTakePhotoV2(path: String?, width: Int, height: Int) {
|
||||||
|
if (path == null) {
|
||||||
|
if (isPhoto) {
|
||||||
|
isPhoto = false
|
||||||
|
takePhoto()
|
||||||
|
} else {
|
||||||
|
binding.hint.text = "单击或语音输入“重新拍照”,进入下一步"
|
||||||
|
"相机异常".showMessage()
|
||||||
|
}
|
||||||
|
return
|
||||||
|
}
|
||||||
|
startActivity(Intent(this@CompositeLayupResultActivity, CompositeLayupResultActivity::class.java).apply {
|
||||||
|
putExtra(EXTRA_PHOTO_PATH, path)
|
||||||
|
putExtra(EXTRA_TASK_NO, taskNo)
|
||||||
|
putExtra(EXTRA_TASK_NAME, taskName)
|
||||||
|
putExtra(EXTRA_PART_NO, partNo)
|
||||||
|
putExtra(EXTRA_STEP_SEQ, stepSeq)
|
||||||
|
putExtra(EXTRA_TOTAL_STEPS, totalSteps)
|
||||||
|
putExtra(EXTRA_DIRECTION, direction)
|
||||||
|
putExtra(EXTRA_VACUUM, vacuum)
|
||||||
|
})
|
||||||
|
finish()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun initData() {
|
||||||
|
super.initData()
|
||||||
|
window.addFlags(android.view.WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON)
|
||||||
|
binding.baseRecyclerView.layoutManager = LinearLayoutManager(this, RecyclerView.VERTICAL, false)
|
||||||
|
binding.baseRecyclerView.adapter = actionAdapter
|
||||||
|
binding.main.setOnClickListener {
|
||||||
|
if (uiMode == UiMode.LAYUP_WORKING) {
|
||||||
|
applyMode(UiMode.CONFIRM_FINISH)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
viewModel.resultState.observe(this) { state ->
|
||||||
|
when (state) {
|
||||||
|
CompositeLayupResultState.LOADING -> {
|
||||||
|
binding.hint.text = "OCR识别中,请稍后..."
|
||||||
|
renderActions(emptyList())
|
||||||
|
}
|
||||||
|
CompositeLayupResultState.SUCCESS -> {
|
||||||
|
val result = viewModel.recognizeResult.value ?: return@observe
|
||||||
|
if (result.success) {
|
||||||
|
applyMode(UiMode.RECOGNIZE_SUCCESS)
|
||||||
|
} else {
|
||||||
|
applyMode(UiMode.RECOGNIZE_FAILED, result.errorMessage.ifBlank { "识别失败,请重试!" })
|
||||||
|
}
|
||||||
|
}
|
||||||
|
CompositeLayupResultState.FAILED -> {
|
||||||
|
applyMode(UiMode.RECOGNIZE_FAILED, viewModel.errorMessage.value ?: "识别失败,请重试!")
|
||||||
|
}
|
||||||
|
else -> Unit
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (taskNo.isNotBlank() && photoPath.isNotBlank()) {
|
||||||
|
viewModel.recognize(taskNo, stepSeq, photoPath)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun applyMode(mode: UiMode, errorMessage: String = "") {
|
||||||
|
uiMode = mode
|
||||||
|
uiHandler.removeCallbacks(layupWorkingRunnable)
|
||||||
|
uiHandler.removeCallbacks(completeRunnable)
|
||||||
|
binding.icon.visibility = android.view.View.VISIBLE
|
||||||
|
when (mode) {
|
||||||
|
UiMode.RECOGNIZE_SUCCESS -> {
|
||||||
|
binding.icon.setImageResource(R.mipmap.ocr_true)
|
||||||
|
binding.title.text = "铺贴层与零件信息正确"
|
||||||
|
binding.subtitle1.text = "识别到这是${stepSeq}/${totalSteps}张"
|
||||||
|
binding.subtitle2.text = buildInstruction()
|
||||||
|
renderActions(listOf("开始铺贴"))
|
||||||
|
binding.hint.text = "单击或语音输入“开始铺贴”,进入下一步"
|
||||||
|
}
|
||||||
|
UiMode.RECOGNIZE_FAILED -> {
|
||||||
|
binding.icon.setImageResource(R.mipmap.ocr_false)
|
||||||
|
binding.title.text = errorMessage
|
||||||
|
binding.subtitle1.text = "识别到这是${stepSeq}/${totalSteps}张"
|
||||||
|
binding.subtitle2.text = "请重新拿取"
|
||||||
|
renderActions(listOf("重新拍照"))
|
||||||
|
binding.hint.text = "单击或语音输入“重新拍照”,进入下一步"
|
||||||
|
}
|
||||||
|
UiMode.LAYUP_PROMPT -> {
|
||||||
|
binding.icon.visibility = android.view.View.INVISIBLE
|
||||||
|
binding.title.text = "请进行铺贴工作"
|
||||||
|
binding.subtitle1.text = "完成后,滑动唤醒眼镜!"
|
||||||
|
binding.subtitle2.text = ""
|
||||||
|
renderActions(emptyList())
|
||||||
|
binding.hint.text = ""
|
||||||
|
uiHandler.postDelayed(layupWorkingRunnable, 5000L)
|
||||||
|
}
|
||||||
|
UiMode.LAYUP_WORKING -> {
|
||||||
|
binding.icon.visibility = android.view.View.INVISIBLE
|
||||||
|
binding.title.text = "正在铺贴第${stepSeq}张"
|
||||||
|
binding.subtitle1.text = buildWorkingInstruction()
|
||||||
|
binding.subtitle2.text = ""
|
||||||
|
renderActions(emptyList())
|
||||||
|
binding.hint.text = ""
|
||||||
|
}
|
||||||
|
UiMode.CONFIRM_FINISH -> {
|
||||||
|
binding.icon.visibility = android.view.View.INVISIBLE
|
||||||
|
binding.title.text = "请确认是否已完成第${stepSeq}/${totalSteps}张铺贴"
|
||||||
|
binding.subtitle1.text = ""
|
||||||
|
binding.subtitle2.text = ""
|
||||||
|
renderActions(listOf(if (stepSeq >= totalSteps) "完成" else "确认并继续", "否"))
|
||||||
|
binding.hint.text = "点击或语音输入对应按钮,继续流程"
|
||||||
|
}
|
||||||
|
UiMode.COMPLETE -> {
|
||||||
|
binding.icon.setImageResource(R.mipmap.ocr_true)
|
||||||
|
binding.title.text = "恭喜完成当前铺贴任务!"
|
||||||
|
binding.subtitle1.text = "3S后自动返回铺贴任务界面"
|
||||||
|
binding.subtitle2.text = ""
|
||||||
|
renderActions(listOf("返回任务列表"))
|
||||||
|
binding.hint.text = ""
|
||||||
|
uiHandler.postDelayed(completeRunnable, 3000L)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun buildInstruction(): String {
|
||||||
|
val vacuumText = if (vacuum.isBlank()) "" else "请真空铺贴、"
|
||||||
|
val directionText = if (direction.isBlank()) "" else "纹理方向:$direction"
|
||||||
|
return (vacuumText + directionText).ifBlank { "请开始铺贴" }
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun buildWorkingInstruction(): String {
|
||||||
|
val vacuumText = if (vacuum.isBlank()) "" else "请真空铺贴、"
|
||||||
|
val directionText = if (direction.isBlank()) "" else "纹理方向$direction、"
|
||||||
|
return "${vacuumText}${directionText}撕衬纸\n完成后,滑动唤醒眼镜!"
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun renderActions(actions: List<String>) {
|
||||||
|
actionAdapter.setmDatas(actions.map(::ItemItem))
|
||||||
|
binding.baseRecyclerView.visibility = if (actions.isEmpty()) android.view.View.INVISIBLE else android.view.View.VISIBLE
|
||||||
|
binding.baseRecyclerView.layoutParams = binding.baseRecyclerView.layoutParams.apply {
|
||||||
|
height = dpToPx(if (actions.size > 1) 152 else 88)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun startLayup() {
|
||||||
|
applyMode(UiMode.LAYUP_PROMPT)
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun retake() {
|
||||||
|
binding.hint.text = "拍照中,请稍后..."
|
||||||
|
isPhoto = true
|
||||||
|
takePhoto()
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun takePhoto() {
|
||||||
|
val fileName = "composite_layup_${System.currentTimeMillis()}.png"
|
||||||
|
val file = File(
|
||||||
|
Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_PICTURES),
|
||||||
|
fileName
|
||||||
|
)
|
||||||
|
GlassMediaServiceHelper.takePhoto(PhotoResolution.RESOLUTION_720P, file.absolutePath)
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun confirmAndContinue() {
|
||||||
|
startActivity(Intent(this, CompositeLayupTaskActivity::class.java).apply {
|
||||||
|
putExtra(CompositeLayupTaskActivity.EXTRA_TASK_NO, taskNo)
|
||||||
|
putExtra(CompositeLayupTaskActivity.EXTRA_STEP_SEQ, stepSeq + 1)
|
||||||
|
})
|
||||||
|
finish()
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun finishCurrentTask() {
|
||||||
|
applyMode(UiMode.COMPLETE)
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun goTaskList() {
|
||||||
|
startActivity(Intent(this, TaskListActivity::class.java).apply {
|
||||||
|
addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP or Intent.FLAG_ACTIVITY_SINGLE_TOP)
|
||||||
|
})
|
||||||
|
finish()
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun dpToPx(dp: Int): Int =
|
||||||
|
(dp * resources.displayMetrics.density).toInt()
|
||||||
|
|
||||||
|
override fun onResume() {
|
||||||
|
super.onResume()
|
||||||
|
GlassMediaServiceHelper.addPhotoCallback(photoCallback)
|
||||||
|
OfflineCmdServiceHelper.addListenerCompositeLayup()
|
||||||
|
OfflineCmdServiceHelper.addOnLineListener(listener)
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun onPause() {
|
||||||
|
super.onPause()
|
||||||
|
uiHandler.removeCallbacks(layupWorkingRunnable)
|
||||||
|
uiHandler.removeCallbacks(completeRunnable)
|
||||||
|
GlassMediaServiceHelper.removePhotoCallback(photoCallback)
|
||||||
|
OfflineCmdServiceHelper.removeListenerCompositeLayup()
|
||||||
|
OfflineCmdServiceHelper.removeOnLineListener(listener)
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun onDestroy() {
|
||||||
|
super.onDestroy()
|
||||||
|
window.clearFlags(android.view.WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON)
|
||||||
|
}
|
||||||
|
|
||||||
|
private val actionAdapter: CommonAdapter<ItemItem> =
|
||||||
|
object : CommonAdapter<ItemItem>(R.layout.item_manual_result_action) {
|
||||||
|
override fun convert(holder: ViewHolder, item: ItemItem, position: Int) {
|
||||||
|
holder.setText(R.id.text, item.text)
|
||||||
|
.setClickListener(R.id.actionRoot) {
|
||||||
|
when (item.text) {
|
||||||
|
"重新拍照" -> retake()
|
||||||
|
"开始铺贴" -> startLayup()
|
||||||
|
"确认并继续" -> confirmAndContinue()
|
||||||
|
"否" -> applyMode(UiMode.LAYUP_WORKING)
|
||||||
|
"完成" -> finishCurrentTask()
|
||||||
|
"返回任务列表" -> goTaskList()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
companion object {
|
||||||
|
const val EXTRA_PHOTO_PATH = "extra_photo_path"
|
||||||
|
const val EXTRA_TASK_NO = "extra_task_no"
|
||||||
|
const val EXTRA_TASK_NAME = "extra_task_name"
|
||||||
|
const val EXTRA_PART_NO = "extra_part_no"
|
||||||
|
const val EXTRA_STEP_SEQ = "extra_step_seq"
|
||||||
|
const val EXTRA_TOTAL_STEPS = "extra_total_steps"
|
||||||
|
const val EXTRA_DIRECTION = "extra_direction"
|
||||||
|
const val EXTRA_VACUUM = "extra_vacuum"
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -2,11 +2,6 @@ package com.nova.brain.glass.ui
|
|||||||
|
|
||||||
import android.content.Intent
|
import android.content.Intent
|
||||||
import android.os.Environment
|
import android.os.Environment
|
||||||
import android.os.Handler
|
|
||||||
import android.os.Looper
|
|
||||||
import android.view.View
|
|
||||||
import androidx.lifecycle.ViewModelProvider
|
|
||||||
import androidx.recyclerview.widget.LinearLayoutManager
|
|
||||||
import androidx.recyclerview.widget.RecyclerView
|
import androidx.recyclerview.widget.RecyclerView
|
||||||
import com.nova.brain.glass.R
|
import com.nova.brain.glass.R
|
||||||
import com.nova.brain.glass.databinding.ActivityCompositeLayupTaskBinding
|
import com.nova.brain.glass.databinding.ActivityCompositeLayupTaskBinding
|
||||||
@ -14,84 +9,49 @@ import com.nova.brain.glass.helper.GlassMediaServiceHelper
|
|||||||
import com.nova.brain.glass.helper.OfflineCmdListener
|
import com.nova.brain.glass.helper.OfflineCmdListener
|
||||||
import com.nova.brain.glass.helper.OfflineCmdServiceHelper
|
import com.nova.brain.glass.helper.OfflineCmdServiceHelper
|
||||||
import com.nova.brain.glass.model.ItemItem
|
import com.nova.brain.glass.model.ItemItem
|
||||||
import com.nova.brain.glass.viewmodel.CompositeLayupRecognizeState
|
|
||||||
import com.nova.brain.glass.viewmodel.CompositeLayupTaskVM
|
import com.nova.brain.glass.viewmodel.CompositeLayupTaskVM
|
||||||
import com.rokid.security.glass3.sdk.base.data.media.PhotoResolution
|
import com.rokid.security.glass3.sdk.base.data.media.PhotoResolution
|
||||||
import com.rokid.security.system.server.media.callback.PhotoFileCallback
|
import com.rokid.security.system.server.media.callback.PhotoFileCallback
|
||||||
import com.xuqm.base.adapter.CommonAdapter
|
import com.xuqm.base.adapter.BasePagedAdapter
|
||||||
|
import com.xuqm.base.adapter.CommonPagedAdapter
|
||||||
import com.xuqm.base.adapter.ViewHolder
|
import com.xuqm.base.adapter.ViewHolder
|
||||||
import com.xuqm.base.common.LogHelper
|
import com.xuqm.base.common.LogHelper
|
||||||
import com.xuqm.base.extensions.showMessage
|
import com.xuqm.base.extensions.showMessage
|
||||||
import com.xuqm.base.ui.BaseActivity
|
import com.xuqm.base.ui.BaseListFormLayoutNormalActivity
|
||||||
import java.io.File
|
import java.io.File
|
||||||
import java.util.UUID
|
import java.util.UUID
|
||||||
|
|
||||||
class CompositeLayupTaskActivity : BaseActivity<ActivityCompositeLayupTaskBinding>() {
|
class CompositeLayupTaskActivity :
|
||||||
|
BaseListFormLayoutNormalActivity<ItemItem, CompositeLayupTaskVM, ActivityCompositeLayupTaskBinding>() {
|
||||||
|
|
||||||
override fun getLayoutId(): Int = R.layout.activity_composite_layup_task
|
override fun getLayoutId(): Int = R.layout.activity_composite_layup_task
|
||||||
override fun fullscreen(): Boolean = true
|
override fun fullscreen(): Boolean = true
|
||||||
|
override fun getRecyclerOrientation(): Int = RecyclerView.VERTICAL
|
||||||
|
|
||||||
private enum class ScreenMode {
|
|
||||||
TASK_INFO,
|
|
||||||
CAPTURE,
|
|
||||||
RECOGNIZE_SUCCESS,
|
|
||||||
RECOGNIZE_FAILED,
|
|
||||||
LAYUP_PROMPT,
|
|
||||||
LAYUP_WORKING,
|
|
||||||
CONFIRM_FINISH,
|
|
||||||
COMPLETE
|
|
||||||
}
|
|
||||||
|
|
||||||
private val viewModel: CompositeLayupTaskVM by lazy {
|
|
||||||
ViewModelProvider(this)[CompositeLayupTaskVM::class.java]
|
|
||||||
}
|
|
||||||
private val taskNoFromIntent: String by lazy {
|
private val taskNoFromIntent: String by lazy {
|
||||||
intent.getStringExtra(EXTRA_TASK_NO).orEmpty()
|
intent.getStringExtra(EXTRA_TASK_NO).orEmpty()
|
||||||
}
|
}
|
||||||
private val mainHandler = Handler(Looper.getMainLooper())
|
private val stepSeqFromIntent: Int by lazy {
|
||||||
|
intent.getIntExtra(EXTRA_STEP_SEQ, 0)
|
||||||
|
}
|
||||||
|
|
||||||
private var isPhotoFallback = false
|
private var isPhoto = false
|
||||||
private var isCaptureInFlight = false
|
private var isCaptureInFlight = false
|
||||||
private var screenMode = ScreenMode.TASK_INFO
|
private var hasNavigatedNextPage = false
|
||||||
private var autoReturned = false
|
|
||||||
|
|
||||||
private val layupWorkingRunnable = Runnable {
|
private val listener: OfflineCmdListener = object : OfflineCmdListener {
|
||||||
if (screenMode == ScreenMode.LAYUP_PROMPT) {
|
|
||||||
applyScreenMode(ScreenMode.LAYUP_WORKING)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private val completeRunnable = Runnable {
|
|
||||||
if (screenMode == ScreenMode.COMPLETE && !autoReturned) {
|
|
||||||
autoReturned = true
|
|
||||||
goTaskList()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private val listener = object : OfflineCmdListener {
|
|
||||||
override fun onOfflineCmd(cmd: String) {
|
override fun onOfflineCmd(cmd: String) {
|
||||||
runOnUiThread {
|
runOnUiThread {
|
||||||
when (cmd) {
|
when (cmd) {
|
||||||
"退出", "返回", "退回" -> finish()
|
"退出", "返回", "退回" -> finish()
|
||||||
"开始", "开始任务" -> if (screenMode == ScreenMode.TASK_INFO) startCaptureFlow()
|
"开始", "拍照", "开始拍照", "开始任务" -> startCapture()
|
||||||
"重新拍照", "重拍", "重新拍摄" -> {
|
|
||||||
if (screenMode == ScreenMode.RECOGNIZE_FAILED) startCaptureFlow()
|
|
||||||
}
|
|
||||||
"开始铺贴" -> if (screenMode == ScreenMode.RECOGNIZE_SUCCESS) startLayup()
|
|
||||||
"确认并继续", "继续" -> if (screenMode == ScreenMode.CONFIRM_FINISH) confirmAndContinue()
|
|
||||||
"否" -> if (screenMode == ScreenMode.CONFIRM_FINISH) backToWorking()
|
|
||||||
"完成", "完成任务" -> {
|
|
||||||
if (screenMode == ScreenMode.CONFIRM_FINISH && viewModel.canFinishAfterCurrentStep()) {
|
|
||||||
finishCurrentTask()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
"返回任务列表" -> if (screenMode == ScreenMode.COMPLETE) goTaskList()
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private val photoCallbackId = UUID.randomUUID().toString()
|
private val photoCallbackId = UUID.randomUUID().toString()
|
||||||
private val photoCallback = object : PhotoFileCallback.Stub() {
|
private val photoCallback: PhotoFileCallback = object : PhotoFileCallback.Stub() {
|
||||||
override fun onTakePhoto(path: String) {
|
override fun onTakePhoto(path: String) {
|
||||||
LogHelper.d("CompositeLayupTask onTakePhoto: $path")
|
LogHelper.d("CompositeLayupTask onTakePhoto: $path")
|
||||||
}
|
}
|
||||||
@ -101,293 +61,128 @@ class CompositeLayupTaskActivity : BaseActivity<ActivityCompositeLayupTaskBindin
|
|||||||
override fun onTakePhotoV2(path: String?, width: Int, height: Int) {
|
override fun onTakePhotoV2(path: String?, width: Int, height: Int) {
|
||||||
LogHelper.d("CompositeLayupTask onTakePhotoV2 width=$width height=$height path=$path")
|
LogHelper.d("CompositeLayupTask onTakePhotoV2 width=$width height=$height path=$path")
|
||||||
if (path == null) {
|
if (path == null) {
|
||||||
if (isPhotoFallback) {
|
if (isPhoto) {
|
||||||
isPhotoFallback = false
|
isPhoto = false
|
||||||
takePhoto()
|
takePhoto()
|
||||||
} else {
|
} else {
|
||||||
isCaptureInFlight = false
|
isCaptureInFlight = false
|
||||||
runOnUiThread {
|
runOnUiThread {
|
||||||
val message = "相机异常,请重试"
|
binding.hint.text = "单击或语音输入“开始”,进入下一步"
|
||||||
updateHint(message)
|
|
||||||
applyScreenMode(ScreenMode.RECOGNIZE_FAILED, message)
|
|
||||||
}
|
}
|
||||||
"相机异常".showMessage()
|
"相机异常".showMessage()
|
||||||
}
|
}
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
if (hasNavigatedNextPage) {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
val taskDetail = viewModel.taskDetail.value
|
||||||
|
val currentDetail = viewModel.currentDetail()
|
||||||
|
val currentTaskStepSeq = currentDetail?.stepSeq ?: viewModel.currentStepSeq
|
||||||
isCaptureInFlight = false
|
isCaptureInFlight = false
|
||||||
runOnUiThread {
|
hasNavigatedNextPage = true
|
||||||
updateHint("OCR识别中,请稍后...")
|
GlassMediaServiceHelper.removePhotoCallback(photoCallback)
|
||||||
viewModel.recognize(path)
|
OfflineCmdServiceHelper.removeListenerCompositeLayup()
|
||||||
}
|
OfflineCmdServiceHelper.removeOnLineListener(listener)
|
||||||
}
|
startActivity(Intent(this@CompositeLayupTaskActivity, CompositeLayupResultActivity::class.java).apply {
|
||||||
}
|
putExtra(CompositeLayupResultActivity.EXTRA_PHOTO_PATH, path)
|
||||||
|
putExtra(CompositeLayupResultActivity.EXTRA_TASK_NO, viewModel.taskNo)
|
||||||
private val actionAdapter = object : CommonAdapter<ItemItem>(R.layout.item_manual_result_action) {
|
putExtra(CompositeLayupResultActivity.EXTRA_TASK_NAME, taskDetail?.taskName.orEmpty())
|
||||||
override fun convert(holder: ViewHolder, item: ItemItem, position: Int) {
|
putExtra(CompositeLayupResultActivity.EXTRA_PART_NO, taskDetail?.partNo.orEmpty())
|
||||||
holder.setText(R.id.text, item.text)
|
putExtra(CompositeLayupResultActivity.EXTRA_STEP_SEQ, currentTaskStepSeq)
|
||||||
.setClickListener(R.id.actionRoot) {
|
putExtra(CompositeLayupResultActivity.EXTRA_TOTAL_STEPS, viewModel.totalSteps)
|
||||||
when (item.text) {
|
putExtra(CompositeLayupResultActivity.EXTRA_DIRECTION, currentDetail?.direction.orEmpty())
|
||||||
"开始任务" -> startCaptureFlow()
|
putExtra(CompositeLayupResultActivity.EXTRA_VACUUM, currentDetail?.vacuum.orEmpty())
|
||||||
"重新拍照" -> startCaptureFlow()
|
})
|
||||||
"开始铺贴" -> startLayup()
|
finish()
|
||||||
"确认并继续" -> confirmAndContinue()
|
|
||||||
"否" -> backToWorking()
|
|
||||||
"完成" -> finishCurrentTask()
|
|
||||||
"返回任务列表" -> goTaskList()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun initData() {
|
override fun initData() {
|
||||||
super.initData()
|
super.initData()
|
||||||
window.addFlags(android.view.WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON)
|
window.addFlags(android.view.WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON)
|
||||||
binding.baseRecyclerView.layoutManager = LinearLayoutManager(this, RecyclerView.VERTICAL, false)
|
binding.tvTaskHeader.text = "复材铺贴任务"
|
||||||
binding.baseRecyclerView.adapter = actionAdapter
|
|
||||||
binding.main.setOnClickListener {
|
|
||||||
if (screenMode == ScreenMode.LAYUP_WORKING) {
|
|
||||||
applyScreenMode(ScreenMode.CONFIRM_FINISH)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
observeViewModel()
|
|
||||||
applyScreenMode(ScreenMode.TASK_INFO)
|
|
||||||
if (taskNoFromIntent.isBlank()) {
|
|
||||||
val message = "任务编号缺失"
|
|
||||||
updateHint(message)
|
|
||||||
message.showMessage()
|
|
||||||
} else {
|
|
||||||
viewModel.loadTaskDetail(taskNoFromIntent)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private fun observeViewModel() {
|
|
||||||
viewModel.taskDetail.observe(this) { detail ->
|
viewModel.taskDetail.observe(this) { detail ->
|
||||||
if (detail != null) {
|
if (detail == null) return@observe
|
||||||
binding.tvTaskName.text = detail.taskName.ifBlank { "铺贴任务" }
|
val currentDetail = viewModel.currentDetail()
|
||||||
renderTaskInfo()
|
binding.tvTaskName.text = currentDetail?.ply?.ifBlank {
|
||||||
applyScreenMode(ScreenMode.TASK_INFO)
|
detail.taskName.ifBlank { "铺贴任务" }
|
||||||
}
|
} ?: detail.taskName.ifBlank { "铺贴任务" }
|
||||||
}
|
|
||||||
viewModel.taskDetailError.observe(this) { msg ->
|
|
||||||
if (msg.isNotBlank()) {
|
|
||||||
updateHint(msg)
|
|
||||||
msg.showMessage()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
viewModel.recognizeState.observe(this) { state ->
|
|
||||||
when (state) {
|
|
||||||
CompositeLayupRecognizeState.LOADING -> {
|
|
||||||
updateHint("OCR识别中,请稍后...")
|
|
||||||
renderActions(emptyList())
|
|
||||||
}
|
|
||||||
CompositeLayupRecognizeState.SUCCESS -> handleRecognizeResult()
|
|
||||||
CompositeLayupRecognizeState.FAILED -> {
|
|
||||||
val error = viewModel.recognizeError.value?.ifBlank { "OCR识别失败" } ?: "OCR识别失败"
|
|
||||||
applyScreenMode(ScreenMode.RECOGNIZE_FAILED, error)
|
|
||||||
}
|
|
||||||
else -> Unit
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private fun renderTaskInfo() {
|
|
||||||
val detail = viewModel.taskDetail.value ?: return
|
|
||||||
binding.content1.text = "零件号:${detail.partNo.ifBlank { "-" }}"
|
binding.content1.text = "零件号:${detail.partNo.ifBlank { "-" }}"
|
||||||
binding.content2.text = "任务编号:${detail.taskNo.ifBlank { taskNoFromIntent }}"
|
binding.content2.text = "任务编号:${detail.taskNo.ifBlank { taskNoFromIntent }}"
|
||||||
binding.content3.text = "任务进度:${viewModel.currentProgressText()}"
|
binding.content3.text = "任务进度:${viewModel.currentStepSeq}/${detail.taskSteps}"
|
||||||
|
binding.hint.text = "单击或语音输入“开始”,进入下一步"
|
||||||
}
|
}
|
||||||
|
viewModel.taskDetailError.observe(this) { message ->
|
||||||
private fun handleRecognizeResult() {
|
if (message.isNotBlank()) {
|
||||||
val result = viewModel.recognizeResult.value ?: return
|
binding.hint.text = "单击或语音输入“开始”,进入下一步"
|
||||||
if (result.success) {
|
message.showMessage()
|
||||||
applyScreenMode(ScreenMode.RECOGNIZE_SUCCESS)
|
}
|
||||||
|
}
|
||||||
|
if (taskNoFromIntent.isBlank()) {
|
||||||
|
binding.hint.text = "任务编号缺失"
|
||||||
} else {
|
} else {
|
||||||
applyScreenMode(
|
viewModel.loadTaskDetail(taskNoFromIntent, stepSeqFromIntent.takeIf { it > 0 })
|
||||||
ScreenMode.RECOGNIZE_FAILED,
|
|
||||||
result.errorMessage.ifBlank { "识别失败,请重试!" }
|
|
||||||
)
|
|
||||||
}
|
|
||||||
viewModel.resetRecognizeState()
|
|
||||||
}
|
|
||||||
|
|
||||||
private fun startCaptureFlow() {
|
|
||||||
if (isCaptureInFlight || taskNoFromIntent.isBlank()) {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
isCaptureInFlight = true
|
|
||||||
applyScreenMode(ScreenMode.CAPTURE)
|
|
||||||
takePhoto()
|
|
||||||
}
|
|
||||||
|
|
||||||
private fun takePhoto() {
|
|
||||||
isPhotoFallback = true
|
|
||||||
val fileName = "composite_layup_${System.currentTimeMillis()}.png"
|
|
||||||
val file = File(
|
|
||||||
Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_PICTURES),
|
|
||||||
fileName
|
|
||||||
)
|
|
||||||
GlassMediaServiceHelper.takePhoto(PhotoResolution.RESOLUTION_720P, file.absolutePath)
|
|
||||||
}
|
|
||||||
|
|
||||||
private fun startLayup() {
|
|
||||||
applyScreenMode(ScreenMode.LAYUP_PROMPT)
|
|
||||||
}
|
|
||||||
|
|
||||||
private fun backToWorking() {
|
|
||||||
applyScreenMode(ScreenMode.LAYUP_WORKING)
|
|
||||||
}
|
|
||||||
|
|
||||||
private fun confirmAndContinue() {
|
|
||||||
if (viewModel.canFinishAfterCurrentStep()) {
|
|
||||||
finishCurrentTask()
|
|
||||||
return
|
|
||||||
}
|
|
||||||
if (viewModel.moveToNextStep()) {
|
|
||||||
renderTaskInfo()
|
|
||||||
applyScreenMode(ScreenMode.TASK_INFO)
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun finishCurrentTask() {
|
|
||||||
applyScreenMode(ScreenMode.COMPLETE)
|
|
||||||
}
|
|
||||||
|
|
||||||
private fun applyScreenMode(mode: ScreenMode, errorMessage: String = "") {
|
|
||||||
screenMode = mode
|
|
||||||
mainHandler.removeCallbacks(layupWorkingRunnable)
|
|
||||||
mainHandler.removeCallbacks(completeRunnable)
|
|
||||||
renderTaskInfo()
|
|
||||||
binding.groupStart.visibility = if (mode == ScreenMode.TASK_INFO) View.VISIBLE else View.GONE
|
|
||||||
binding.groupCapture.visibility = if (mode == ScreenMode.CAPTURE) View.VISIBLE else View.GONE
|
|
||||||
binding.groupResult.visibility =
|
|
||||||
if (mode == ScreenMode.RECOGNIZE_SUCCESS || mode == ScreenMode.RECOGNIZE_FAILED) View.VISIBLE else View.GONE
|
|
||||||
binding.groupWork.visibility =
|
|
||||||
if (mode == ScreenMode.LAYUP_PROMPT || mode == ScreenMode.LAYUP_WORKING) View.VISIBLE else View.GONE
|
|
||||||
binding.groupConfirm.visibility = if (mode == ScreenMode.CONFIRM_FINISH) View.VISIBLE else View.GONE
|
|
||||||
binding.groupComplete.visibility = if (mode == ScreenMode.COMPLETE) View.VISIBLE else View.GONE
|
|
||||||
|
|
||||||
when (mode) {
|
|
||||||
ScreenMode.TASK_INFO -> {
|
|
||||||
binding.captureMessage.text = "请对准下一张复材铺贴物料上的字符内容"
|
|
||||||
binding.startIcon.setImageResource(R.mipmap.ocr_photo)
|
|
||||||
renderActions(listOf("开始任务"))
|
|
||||||
updateHint("单击或语音输入\"开始\",进入下一步")
|
|
||||||
}
|
|
||||||
ScreenMode.CAPTURE -> {
|
|
||||||
binding.captureMessage.text = "请对准复材铺贴物料上的字符内容"
|
|
||||||
renderActions(emptyList())
|
|
||||||
updateHint("拍照中,请稍后...")
|
|
||||||
}
|
|
||||||
ScreenMode.RECOGNIZE_SUCCESS -> {
|
|
||||||
val currentDetail = viewModel.currentDetail()
|
|
||||||
binding.resultIcon.setImageResource(R.mipmap.ocr_true)
|
|
||||||
binding.resultTitle.text = "铺贴层与零件信息正确"
|
|
||||||
binding.resultSubtitle1.text = "识别到这是${viewModel.currentProgressText()}张"
|
|
||||||
binding.resultSubtitle2.text = buildRecognizeInstruction(currentDetail?.vacuum, currentDetail?.direction)
|
|
||||||
renderActions(listOf("开始铺贴"))
|
|
||||||
updateHint("单击或语音输入\"开始铺贴\",进入下一步")
|
|
||||||
}
|
|
||||||
ScreenMode.RECOGNIZE_FAILED -> {
|
|
||||||
binding.resultIcon.setImageResource(R.mipmap.ocr_false)
|
|
||||||
binding.resultTitle.text = errorMessage.ifBlank { "识别失败,请重试!" }
|
|
||||||
binding.resultSubtitle1.text = "识别到这是${viewModel.currentProgressText()}张"
|
|
||||||
binding.resultSubtitle2.text = "请重新拿取"
|
|
||||||
renderActions(listOf("重新拍照"))
|
|
||||||
updateHint("单击或语音输入\"重新拍照\",进入下一步")
|
|
||||||
}
|
|
||||||
ScreenMode.LAYUP_PROMPT -> {
|
|
||||||
binding.workText.text = "请进行铺贴工作\n完成后,滑动唤醒眼镜!"
|
|
||||||
renderActions(emptyList())
|
|
||||||
updateHint("")
|
|
||||||
mainHandler.postDelayed(layupWorkingRunnable, 5000L)
|
|
||||||
}
|
|
||||||
ScreenMode.LAYUP_WORKING -> {
|
|
||||||
binding.workText.text = buildWorkingInstruction()
|
|
||||||
renderActions(emptyList())
|
|
||||||
updateHint("")
|
|
||||||
}
|
|
||||||
ScreenMode.CONFIRM_FINISH -> {
|
|
||||||
binding.confirmTitle.text = "请确认是否已完成第${viewModel.currentProgressText()}张铺贴"
|
|
||||||
val primary = if (viewModel.canFinishAfterCurrentStep()) "完成" else "确认并继续"
|
|
||||||
renderActions(listOf(primary, "否"))
|
|
||||||
updateHint("点击或语音输入对应按钮,继续流程")
|
|
||||||
}
|
|
||||||
ScreenMode.COMPLETE -> {
|
|
||||||
autoReturned = false
|
|
||||||
binding.completeSubtitle.text = "3S后自动返回铺贴任务界面"
|
|
||||||
renderActions(listOf("返回任务列表"))
|
|
||||||
updateHint("")
|
|
||||||
mainHandler.postDelayed(completeRunnable, 3000L)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private fun renderActions(actions: List<String>) {
|
|
||||||
actionAdapter.setmDatas(actions.map(::ItemItem))
|
|
||||||
binding.baseRecyclerView.layoutParams = binding.baseRecyclerView.layoutParams.apply {
|
|
||||||
height = dpToPx(
|
|
||||||
when {
|
|
||||||
actions.isEmpty() -> 88
|
|
||||||
actions.size == 1 -> 88
|
|
||||||
else -> 152
|
|
||||||
}
|
|
||||||
)
|
|
||||||
}
|
|
||||||
binding.baseRecyclerView.visibility = if (actions.isEmpty()) View.INVISIBLE else View.VISIBLE
|
|
||||||
}
|
|
||||||
|
|
||||||
private fun updateHint(text: String) {
|
|
||||||
binding.hint.text = text
|
|
||||||
binding.hint.visibility = if (text.isBlank()) View.INVISIBLE else View.VISIBLE
|
|
||||||
}
|
|
||||||
|
|
||||||
private fun buildRecognizeInstruction(vacuum: String?, direction: String?): String {
|
|
||||||
val vacuumText = if (vacuum.isNullOrBlank()) "" else "请真空铺贴、"
|
|
||||||
val directionText = if (direction.isNullOrBlank()) "" else "纹理方向$direction"
|
|
||||||
return (vacuumText + directionText).ifBlank { "请开始铺贴" }
|
|
||||||
}
|
|
||||||
|
|
||||||
private fun buildWorkingInstruction(): String {
|
|
||||||
val detail = viewModel.currentDetail()
|
|
||||||
val stepText = "正在铺贴第${viewModel.currentStepSeq}张"
|
|
||||||
val vacuumText = if (detail?.vacuum.isNullOrBlank()) "" else "请真空铺贴、"
|
|
||||||
val directionText = if (detail?.direction.isNullOrBlank()) "" else "纹理方向${detail?.direction}、"
|
|
||||||
return "$stepText\n${vacuumText}${directionText}撕衬纸\n完成后,滑动唤醒眼镜!"
|
|
||||||
}
|
|
||||||
|
|
||||||
private fun goTaskList() {
|
|
||||||
startActivity(Intent(this, TaskListActivity::class.java).apply {
|
|
||||||
addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP or Intent.FLAG_ACTIVITY_SINGLE_TOP)
|
|
||||||
})
|
|
||||||
finish()
|
|
||||||
}
|
|
||||||
|
|
||||||
private fun dpToPx(dp: Int): Int =
|
|
||||||
(dp * resources.displayMetrics.density).toInt()
|
|
||||||
|
|
||||||
override fun onResume() {
|
override fun onResume() {
|
||||||
super.onResume()
|
super.onResume()
|
||||||
|
hasNavigatedNextPage = false
|
||||||
|
isCaptureInFlight = false
|
||||||
GlassMediaServiceHelper.addPhotoCallback(photoCallback)
|
GlassMediaServiceHelper.addPhotoCallback(photoCallback)
|
||||||
OfflineCmdServiceHelper.addListenerCompositeLayup()
|
|
||||||
OfflineCmdServiceHelper.addOnLineListener(listener)
|
OfflineCmdServiceHelper.addOnLineListener(listener)
|
||||||
|
OfflineCmdServiceHelper.addListenerCompositeLayup()
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun onPause() {
|
override fun onPause() {
|
||||||
super.onPause()
|
super.onPause()
|
||||||
mainHandler.removeCallbacks(layupWorkingRunnable)
|
|
||||||
mainHandler.removeCallbacks(completeRunnable)
|
|
||||||
GlassMediaServiceHelper.removePhotoCallback(photoCallback)
|
|
||||||
OfflineCmdServiceHelper.removeListenerCompositeLayup()
|
OfflineCmdServiceHelper.removeListenerCompositeLayup()
|
||||||
OfflineCmdServiceHelper.removeOnLineListener(listener)
|
OfflineCmdServiceHelper.removeOnLineListener(listener)
|
||||||
|
GlassMediaServiceHelper.removePhotoCallback(photoCallback)
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun onDestroy() {
|
override fun onDestroy() {
|
||||||
|
isCaptureInFlight = false
|
||||||
|
hasNavigatedNextPage = false
|
||||||
super.onDestroy()
|
super.onDestroy()
|
||||||
window.clearFlags(android.view.WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON)
|
window.clearFlags(android.view.WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private fun startCapture() {
|
||||||
|
if (isCaptureInFlight || hasNavigatedNextPage || taskNoFromIntent.isBlank()) {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
binding.hint.text = "拍照中,请稍后..."
|
||||||
|
isPhoto = true
|
||||||
|
isCaptureInFlight = true
|
||||||
|
takePhoto()
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun takePhoto() {
|
||||||
|
val fileName = "composite_layup_${System.currentTimeMillis()}.png"
|
||||||
|
val publicPicturesDir =
|
||||||
|
Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_PICTURES)
|
||||||
|
val file = File(publicPicturesDir, fileName)
|
||||||
|
GlassMediaServiceHelper.takePhoto(PhotoResolution.RESOLUTION_720P, file.absolutePath)
|
||||||
|
}
|
||||||
|
|
||||||
|
private val adapter: BasePagedAdapter<ItemItem> =
|
||||||
|
object : CommonPagedAdapter<ItemItem>(R.layout.item_photo) {
|
||||||
|
override fun convert(holder: ViewHolder, item: ItemItem, position: Int) {
|
||||||
|
holder.setText(R.id.text, item.text)
|
||||||
|
.setClickListener(R.id.photo) {
|
||||||
|
if (item.text == "开始任务") {
|
||||||
|
startCapture()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun adapter(): BasePagedAdapter<ItemItem> = adapter
|
||||||
|
|
||||||
companion object {
|
companion object {
|
||||||
const val EXTRA_TASK_NO = "extra_task_no"
|
const val EXTRA_TASK_NO = "extra_task_no"
|
||||||
|
const val EXTRA_STEP_SEQ = "extra_step_seq"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -56,8 +56,8 @@ class WelcomeActivity : BaseActivity<ActivityWelcomeBinding>() {
|
|||||||
binding.tv.setOnClickListener {
|
binding.tv.setOnClickListener {
|
||||||
runWithNetwork {
|
runWithNetwork {
|
||||||
// triggerRecognize()
|
// triggerRecognize()
|
||||||
// startActivity(Intent(this, TaskListActivity::class.java))
|
startActivity(Intent(this, TaskListActivity::class.java))
|
||||||
startActivity(Intent(this, ChatActivity::class.java))
|
// startActivity(Intent(this, ChatActivity::class.java))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -0,0 +1,68 @@
|
|||||||
|
package com.nova.brain.glass.viewmodel
|
||||||
|
|
||||||
|
import androidx.lifecycle.MutableLiveData
|
||||||
|
import com.nova.brain.glass.MyApplication
|
||||||
|
import com.nova.brain.glass.model.ItemItem
|
||||||
|
import com.nova.brain.glass.model.data.CompositeLayupRecognizeResult
|
||||||
|
import com.nova.brain.glass.repository.Service4
|
||||||
|
import com.xuqm.base.di.manager.HttpManager
|
||||||
|
import com.xuqm.base.viewmodel.BaseListViewModel
|
||||||
|
import com.xuqm.base.viewmodel.callback.Response
|
||||||
|
import io.reactivex.android.schedulers.AndroidSchedulers
|
||||||
|
import io.reactivex.disposables.CompositeDisposable
|
||||||
|
import io.reactivex.schedulers.Schedulers
|
||||||
|
import okhttp3.MediaType.Companion.toMediaTypeOrNull
|
||||||
|
import okhttp3.MultipartBody
|
||||||
|
import okhttp3.RequestBody.Companion.asRequestBody
|
||||||
|
import okhttp3.RequestBody.Companion.toRequestBody
|
||||||
|
import java.io.File
|
||||||
|
|
||||||
|
enum class CompositeLayupResultState { IDLE, LOADING, SUCCESS, FAILED }
|
||||||
|
|
||||||
|
class CompositeLayupResultVM : BaseListViewModel<ItemItem>() {
|
||||||
|
val resultState = MutableLiveData(CompositeLayupResultState.IDLE)
|
||||||
|
val recognizeResult = MutableLiveData<CompositeLayupRecognizeResult?>()
|
||||||
|
val errorMessage = MutableLiveData<String>()
|
||||||
|
|
||||||
|
private val disposables = CompositeDisposable()
|
||||||
|
|
||||||
|
override fun loadData(page: Int, onResponse: Response<ItemItem>) {
|
||||||
|
onResponse.onResponse(arrayListOf())
|
||||||
|
}
|
||||||
|
|
||||||
|
fun recognize(taskNo: String, stepSeq: Int, photoPath: String) {
|
||||||
|
val file = File(photoPath)
|
||||||
|
if (!file.exists()) {
|
||||||
|
resultState.value = CompositeLayupResultState.FAILED
|
||||||
|
errorMessage.value = "图片不存在"
|
||||||
|
return
|
||||||
|
}
|
||||||
|
resultState.value = CompositeLayupResultState.LOADING
|
||||||
|
val taskNoBody = taskNo.toRequestBody("text/plain".toMediaTypeOrNull())
|
||||||
|
val stepSeqBody = stepSeq.toString().toRequestBody("text/plain".toMediaTypeOrNull())
|
||||||
|
val requestFile = file.asRequestBody("application/octet-stream".toMediaTypeOrNull())
|
||||||
|
val filePart = MultipartBody.Part.createFormData("file", file.name, requestFile)
|
||||||
|
val disposable = HttpManager.getApi(MyApplication.appComponent4, Service4::class.java)
|
||||||
|
.ocrRecognize(taskNoBody, stepSeqBody, filePart)
|
||||||
|
.subscribeOn(Schedulers.io())
|
||||||
|
.observeOn(AndroidSchedulers.mainThread())
|
||||||
|
.subscribe({ response ->
|
||||||
|
if (response.success && response.data != null) {
|
||||||
|
recognizeResult.value = response.data
|
||||||
|
resultState.value = CompositeLayupResultState.SUCCESS
|
||||||
|
} else {
|
||||||
|
resultState.value = CompositeLayupResultState.FAILED
|
||||||
|
errorMessage.value = response.message.ifBlank { "OCR识别失败" }
|
||||||
|
}
|
||||||
|
}, { e ->
|
||||||
|
resultState.value = CompositeLayupResultState.FAILED
|
||||||
|
errorMessage.value = e.message ?: "OCR识别失败"
|
||||||
|
})
|
||||||
|
disposables.add(disposable)
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun onCleared() {
|
||||||
|
super.onCleared()
|
||||||
|
disposables.clear()
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -2,12 +2,14 @@ package com.nova.brain.glass.viewmodel
|
|||||||
|
|
||||||
import androidx.lifecycle.MutableLiveData
|
import androidx.lifecycle.MutableLiveData
|
||||||
import com.nova.brain.glass.MyApplication
|
import com.nova.brain.glass.MyApplication
|
||||||
|
import com.nova.brain.glass.model.ItemItem
|
||||||
import com.nova.brain.glass.model.data.CompositeLayupRecognizeResult
|
import com.nova.brain.glass.model.data.CompositeLayupRecognizeResult
|
||||||
import com.nova.brain.glass.model.data.CompositeLayupDetailItem
|
import com.nova.brain.glass.model.data.CompositeLayupDetailItem
|
||||||
import com.nova.brain.glass.model.data.CompositeLayupTaskDetail
|
import com.nova.brain.glass.model.data.CompositeLayupTaskDetail
|
||||||
import com.nova.brain.glass.repository.Service4
|
import com.nova.brain.glass.repository.Service4
|
||||||
import com.xuqm.base.di.manager.HttpManager
|
import com.xuqm.base.di.manager.HttpManager
|
||||||
import androidx.lifecycle.ViewModel
|
import com.xuqm.base.viewmodel.BaseListViewModel
|
||||||
|
import com.xuqm.base.viewmodel.callback.Response
|
||||||
import io.reactivex.android.schedulers.AndroidSchedulers
|
import io.reactivex.android.schedulers.AndroidSchedulers
|
||||||
import io.reactivex.disposables.CompositeDisposable
|
import io.reactivex.disposables.CompositeDisposable
|
||||||
import io.reactivex.schedulers.Schedulers
|
import io.reactivex.schedulers.Schedulers
|
||||||
@ -19,7 +21,7 @@ import java.io.File
|
|||||||
|
|
||||||
enum class CompositeLayupRecognizeState { IDLE, LOADING, SUCCESS, FAILED }
|
enum class CompositeLayupRecognizeState { IDLE, LOADING, SUCCESS, FAILED }
|
||||||
|
|
||||||
class CompositeLayupTaskVM : ViewModel() {
|
class CompositeLayupTaskVM : BaseListViewModel<ItemItem>() {
|
||||||
|
|
||||||
val taskDetail = MutableLiveData<CompositeLayupTaskDetail?>()
|
val taskDetail = MutableLiveData<CompositeLayupTaskDetail?>()
|
||||||
val taskDetailError = MutableLiveData<String>()
|
val taskDetailError = MutableLiveData<String>()
|
||||||
@ -36,15 +38,19 @@ class CompositeLayupTaskVM : ViewModel() {
|
|||||||
var lastRecognizeFinished: Boolean = false
|
var lastRecognizeFinished: Boolean = false
|
||||||
private set
|
private set
|
||||||
|
|
||||||
fun loadTaskDetail(taskNo: String) {
|
override fun loadData(page: Int, onResponse: Response<ItemItem>) {
|
||||||
|
onResponse.onResponse(arrayListOf(ItemItem("开始任务")))
|
||||||
|
}
|
||||||
|
|
||||||
|
fun loadTaskDetail(taskNo: String, stepOverride: Int? = null) {
|
||||||
this.taskNo = taskNo
|
this.taskNo = taskNo
|
||||||
val disposable = HttpManager.getApi(MyApplication.appComponent4, Service4::class.java)
|
val disposable = HttpManager.getApi(MyApplication.appComponent4, Service4::class.java)
|
||||||
.queryTask(taskNo)
|
.queryTask(taskNo)
|
||||||
.subscribeOn(Schedulers.io())
|
.subscribeOn(Schedulers.io())
|
||||||
.observeOn(AndroidSchedulers.mainThread())
|
.observeOn(AndroidSchedulers.mainThread())
|
||||||
.subscribe({ response ->
|
.subscribe({ response ->
|
||||||
if (response.success && response.data != null) {
|
if (response.code == 200 && response.data != null) {
|
||||||
bindTaskDetail(response.data)
|
bindTaskDetail(response.data, stepOverride)
|
||||||
} else {
|
} else {
|
||||||
taskDetailError.value = response.message.ifBlank { "获取任务详情失败" }
|
taskDetailError.value = response.message.ifBlank { "获取任务详情失败" }
|
||||||
}
|
}
|
||||||
@ -100,9 +106,6 @@ class CompositeLayupTaskVM : ViewModel() {
|
|||||||
|
|
||||||
fun currentDetail(): CompositeLayupDetailItem? =
|
fun currentDetail(): CompositeLayupDetailItem? =
|
||||||
taskDetail.value?.detailList
|
taskDetail.value?.detailList
|
||||||
?.sortedBy { it.stepSeq }
|
|
||||||
?.firstOrNull { it.stepSeq == currentStepSeq }
|
|
||||||
?: taskDetail.value?.detailList
|
|
||||||
?.sortedBy { it.stepSeq }
|
?.sortedBy { it.stepSeq }
|
||||||
?.getOrNull((currentStepSeq - 1).coerceAtLeast(0))
|
?.getOrNull((currentStepSeq - 1).coerceAtLeast(0))
|
||||||
|
|
||||||
@ -121,16 +124,13 @@ class CompositeLayupTaskVM : ViewModel() {
|
|||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun bindTaskDetail(detail: CompositeLayupTaskDetail) {
|
private fun bindTaskDetail(detail: CompositeLayupTaskDetail, stepOverride: Int? = null) {
|
||||||
taskDetail.value = detail
|
taskDetail.value = detail
|
||||||
this.taskNo = detail.taskNo.ifBlank { taskNo }
|
this.taskNo = detail.taskNo.ifBlank { taskNo }
|
||||||
totalSteps = detail.taskSteps.coerceAtLeast(detail.detailList?.size ?: 1).coerceAtLeast(1)
|
totalSteps = detail.taskSteps.coerceAtLeast(detail.detailList?.size ?: 1).coerceAtLeast(1)
|
||||||
currentStepSeq = when {
|
currentStepSeq = when {
|
||||||
|
stepOverride != null && stepOverride > 0 -> stepOverride
|
||||||
detail.taskCurrentStep > 0 -> detail.taskCurrentStep
|
detail.taskCurrentStep > 0 -> detail.taskCurrentStep
|
||||||
!detail.detailList.isNullOrEmpty() -> {
|
|
||||||
detail.detailList.firstOrNull { it.detailStatus != 9 }?.stepSeq
|
|
||||||
?: detail.detailList.last().stepSeq.coerceAtLeast(1)
|
|
||||||
}
|
|
||||||
else -> 1
|
else -> 1
|
||||||
}.coerceIn(1, totalSteps)
|
}.coerceIn(1, totalSteps)
|
||||||
lastRecognizeFinished = currentStepSeq >= totalSteps
|
lastRecognizeFinished = currentStepSeq >= totalSteps
|
||||||
|
|||||||
@ -0,0 +1,85 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<layout>
|
||||||
|
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
|
xmlns:app="http://schemas.android.com/apk/res-auto"
|
||||||
|
android:id="@+id/main"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="match_parent"
|
||||||
|
android:background="@color/app_color_black">
|
||||||
|
|
||||||
|
<ImageView
|
||||||
|
android:id="@+id/icon"
|
||||||
|
android:layout_width="120dp"
|
||||||
|
android:layout_height="120dp"
|
||||||
|
android:layout_marginTop="44dp"
|
||||||
|
android:src="@mipmap/ocr_true"
|
||||||
|
app:layout_constraintEnd_toEndOf="parent"
|
||||||
|
app:layout_constraintStart_toStartOf="parent"
|
||||||
|
app:layout_constraintTop_toTopOf="parent" />
|
||||||
|
|
||||||
|
<TextView
|
||||||
|
android:id="@+id/title"
|
||||||
|
android:layout_width="0dp"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_marginTop="16dp"
|
||||||
|
android:gravity="center"
|
||||||
|
android:text="铺贴层与零件信息正确"
|
||||||
|
android:textColor="#ff40FF5E"
|
||||||
|
android:textSize="22sp"
|
||||||
|
android:textStyle="bold"
|
||||||
|
app:layout_constraintEnd_toEndOf="parent"
|
||||||
|
app:layout_constraintStart_toStartOf="parent"
|
||||||
|
app:layout_constraintTop_toBottomOf="@+id/icon" />
|
||||||
|
|
||||||
|
<TextView
|
||||||
|
android:id="@+id/subtitle1"
|
||||||
|
android:layout_width="0dp"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_marginTop="8dp"
|
||||||
|
android:gravity="center"
|
||||||
|
android:text="识别到这是1/12张"
|
||||||
|
android:textColor="#ff40FF5E"
|
||||||
|
android:textSize="18sp"
|
||||||
|
app:layout_constraintEnd_toEndOf="parent"
|
||||||
|
app:layout_constraintStart_toStartOf="parent"
|
||||||
|
app:layout_constraintTop_toBottomOf="@+id/title" />
|
||||||
|
|
||||||
|
<TextView
|
||||||
|
android:id="@+id/subtitle2"
|
||||||
|
android:layout_width="0dp"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_marginTop="8dp"
|
||||||
|
android:gravity="center"
|
||||||
|
android:text="请真空铺贴、纹理方向+90"
|
||||||
|
android:textColor="#ff40FF5E"
|
||||||
|
android:textSize="18sp"
|
||||||
|
app:layout_constraintEnd_toEndOf="parent"
|
||||||
|
app:layout_constraintStart_toStartOf="parent"
|
||||||
|
app:layout_constraintTop_toBottomOf="@+id/subtitle1" />
|
||||||
|
|
||||||
|
<androidx.recyclerview.widget.RecyclerView
|
||||||
|
android:id="@+id/baseRecyclerView"
|
||||||
|
android:layout_width="0dp"
|
||||||
|
android:layout_height="88dp"
|
||||||
|
android:layout_marginTop="24dp"
|
||||||
|
android:clipToPadding="false"
|
||||||
|
android:overScrollMode="never"
|
||||||
|
app:layout_constraintEnd_toEndOf="parent"
|
||||||
|
app:layout_constraintStart_toStartOf="parent"
|
||||||
|
app:layout_constraintTop_toBottomOf="@+id/subtitle2" />
|
||||||
|
|
||||||
|
<TextView
|
||||||
|
android:id="@+id/hint"
|
||||||
|
android:layout_width="0dp"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_marginTop="12dp"
|
||||||
|
android:gravity="center"
|
||||||
|
android:text="单击或语音输入“开始铺贴”,进入下一步"
|
||||||
|
android:textColor="#ff40FF5E"
|
||||||
|
android:textSize="14sp"
|
||||||
|
app:layout_constraintEnd_toEndOf="parent"
|
||||||
|
app:layout_constraintStart_toStartOf="parent"
|
||||||
|
app:layout_constraintTop_toBottomOf="@+id/baseRecyclerView" />
|
||||||
|
|
||||||
|
</androidx.constraintlayout.widget.ConstraintLayout>
|
||||||
|
</layout>
|
||||||
@ -55,7 +55,7 @@
|
|||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:layout_marginStart="15dp"
|
android:layout_marginStart="15dp"
|
||||||
android:layout_marginTop="4dp"
|
android:layout_marginTop="4dp"
|
||||||
android:text="零件号:20293989-001"
|
android:text="零件号:"
|
||||||
android:textColor="#ff40FF5E"
|
android:textColor="#ff40FF5E"
|
||||||
android:textSize="14sp" />
|
android:textSize="14sp" />
|
||||||
|
|
||||||
@ -65,7 +65,7 @@
|
|||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:layout_marginStart="15dp"
|
android:layout_marginStart="15dp"
|
||||||
android:layout_marginTop="4dp"
|
android:layout_marginTop="4dp"
|
||||||
android:text="任务编号:PT20260422001"
|
android:text="任务编号:"
|
||||||
android:textColor="#ff40FF5E"
|
android:textColor="#ff40FF5E"
|
||||||
android:textSize="14sp" />
|
android:textSize="14sp" />
|
||||||
|
|
||||||
@ -75,7 +75,7 @@
|
|||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:layout_marginStart="15dp"
|
android:layout_marginStart="15dp"
|
||||||
android:layout_marginVertical="4dp"
|
android:layout_marginVertical="4dp"
|
||||||
android:text="任务进度:1/12"
|
android:text="任务进度:"
|
||||||
android:textColor="#ff40FF5E"
|
android:textColor="#ff40FF5E"
|
||||||
android:textSize="14sp" />
|
android:textSize="14sp" />
|
||||||
</LinearLayout>
|
</LinearLayout>
|
||||||
@ -84,8 +84,8 @@
|
|||||||
android:id="@+id/baseRecyclerView"
|
android:id="@+id/baseRecyclerView"
|
||||||
android:layout_width="0dp"
|
android:layout_width="0dp"
|
||||||
android:layout_height="88dp"
|
android:layout_height="88dp"
|
||||||
android:layout_marginTop="24dp"
|
|
||||||
android:clipToPadding="false"
|
android:clipToPadding="false"
|
||||||
|
android:layout_marginTop="12dp"
|
||||||
android:overScrollMode="never"
|
android:overScrollMode="never"
|
||||||
app:layout_constraintEnd_toEndOf="parent"
|
app:layout_constraintEnd_toEndOf="parent"
|
||||||
app:layout_constraintStart_toStartOf="parent"
|
app:layout_constraintStart_toStartOf="parent"
|
||||||
@ -93,238 +93,17 @@
|
|||||||
|
|
||||||
<TextView
|
<TextView
|
||||||
android:id="@+id/hint"
|
android:id="@+id/hint"
|
||||||
android:layout_width="0dp"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:layout_marginTop="12dp"
|
android:layout_marginStart="15dp"
|
||||||
|
android:layout_marginTop="10dp"
|
||||||
|
android:layout_marginVertical="4dp"
|
||||||
android:gravity="center"
|
android:gravity="center"
|
||||||
android:text="单击或语音输入"开始",进入下一步"
|
android:text="单击或语音输入"开始",进入下一步"
|
||||||
android:textColor="#ff40FF5E"
|
android:textColor="#ff40FF5E"
|
||||||
android:textSize="14sp"
|
android:textSize="14sp"
|
||||||
app:layout_constraintEnd_toEndOf="parent"
|
|
||||||
app:layout_constraintStart_toStartOf="parent"
|
|
||||||
app:layout_constraintTop_toBottomOf="@+id/baseRecyclerView" />
|
app:layout_constraintTop_toBottomOf="@+id/baseRecyclerView" />
|
||||||
|
|
||||||
<FrameLayout
|
|
||||||
android:layout_width="0dp"
|
|
||||||
android:layout_height="0dp"
|
|
||||||
android:layout_marginStart="24dp"
|
|
||||||
android:layout_marginTop="12dp"
|
|
||||||
android:layout_marginEnd="24dp"
|
|
||||||
android:layout_marginBottom="12dp"
|
|
||||||
app:layout_constraintBottom_toBottomOf="parent"
|
|
||||||
app:layout_constraintEnd_toEndOf="parent"
|
|
||||||
app:layout_constraintStart_toStartOf="parent"
|
|
||||||
app:layout_constraintTop_toBottomOf="@id/hint">
|
|
||||||
|
|
||||||
<LinearLayout
|
|
||||||
android:id="@+id/groupStart"
|
|
||||||
android:layout_width="match_parent"
|
|
||||||
android:layout_height="match_parent"
|
|
||||||
android:gravity="center"
|
|
||||||
android:orientation="vertical">
|
|
||||||
|
|
||||||
<FrameLayout
|
|
||||||
android:layout_width="128dp"
|
|
||||||
android:layout_height="128dp"
|
|
||||||
android:background="@drawable/bg_composite_circle">
|
|
||||||
|
|
||||||
<ImageView
|
|
||||||
android:id="@+id/startIcon"
|
|
||||||
android:layout_width="52dp"
|
|
||||||
android:layout_height="52dp"
|
|
||||||
android:layout_gravity="center"
|
|
||||||
android:src="@mipmap/ocr_photo" />
|
|
||||||
</FrameLayout>
|
|
||||||
</LinearLayout>
|
|
||||||
|
|
||||||
<LinearLayout
|
|
||||||
android:id="@+id/groupCapture"
|
|
||||||
android:layout_width="match_parent"
|
|
||||||
android:layout_height="match_parent"
|
|
||||||
android:gravity="center"
|
|
||||||
android:orientation="vertical"
|
|
||||||
android:visibility="gone">
|
|
||||||
|
|
||||||
<FrameLayout
|
|
||||||
android:layout_width="320dp"
|
|
||||||
android:layout_height="220dp">
|
|
||||||
|
|
||||||
<View
|
|
||||||
android:layout_width="60dp"
|
|
||||||
android:layout_height="4dp"
|
|
||||||
android:background="#ff40FF5E" />
|
|
||||||
|
|
||||||
<View
|
|
||||||
android:layout_width="4dp"
|
|
||||||
android:layout_height="60dp"
|
|
||||||
android:background="#ff40FF5E" />
|
|
||||||
|
|
||||||
<View
|
|
||||||
android:layout_width="60dp"
|
|
||||||
android:layout_height="4dp"
|
|
||||||
android:layout_gravity="top|end"
|
|
||||||
android:background="#ff40FF5E" />
|
|
||||||
|
|
||||||
<View
|
|
||||||
android:layout_width="4dp"
|
|
||||||
android:layout_height="60dp"
|
|
||||||
android:layout_gravity="top|end"
|
|
||||||
android:background="#ff40FF5E" />
|
|
||||||
|
|
||||||
<View
|
|
||||||
android:layout_width="60dp"
|
|
||||||
android:layout_height="4dp"
|
|
||||||
android:layout_gravity="bottom|start"
|
|
||||||
android:background="#ff40FF5E" />
|
|
||||||
|
|
||||||
<View
|
|
||||||
android:layout_width="4dp"
|
|
||||||
android:layout_height="60dp"
|
|
||||||
android:layout_gravity="bottom|start"
|
|
||||||
android:background="#ff40FF5E" />
|
|
||||||
|
|
||||||
<View
|
|
||||||
android:layout_width="60dp"
|
|
||||||
android:layout_height="4dp"
|
|
||||||
android:layout_gravity="bottom|end"
|
|
||||||
android:background="#ff40FF5E" />
|
|
||||||
|
|
||||||
<View
|
|
||||||
android:layout_width="4dp"
|
|
||||||
android:layout_height="60dp"
|
|
||||||
android:layout_gravity="bottom|end"
|
|
||||||
android:background="#ff40FF5E" />
|
|
||||||
|
|
||||||
<TextView
|
|
||||||
android:id="@+id/captureMessage"
|
|
||||||
android:layout_width="wrap_content"
|
|
||||||
android:layout_height="wrap_content"
|
|
||||||
android:layout_gravity="center"
|
|
||||||
android:gravity="center"
|
|
||||||
android:text="请对准复材铺贴物料上的字符内容"
|
|
||||||
android:textColor="#ff40FF5E"
|
|
||||||
android:textSize="16sp" />
|
|
||||||
</FrameLayout>
|
|
||||||
</LinearLayout>
|
|
||||||
|
|
||||||
<LinearLayout
|
|
||||||
android:id="@+id/groupResult"
|
|
||||||
android:layout_width="match_parent"
|
|
||||||
android:layout_height="match_parent"
|
|
||||||
android:gravity="center"
|
|
||||||
android:orientation="vertical"
|
|
||||||
android:visibility="gone">
|
|
||||||
|
|
||||||
<ImageView
|
|
||||||
android:id="@+id/resultIcon"
|
|
||||||
android:layout_width="120dp"
|
|
||||||
android:layout_height="120dp"
|
|
||||||
android:src="@mipmap/ocr_true" />
|
|
||||||
|
|
||||||
<TextView
|
|
||||||
android:id="@+id/resultTitle"
|
|
||||||
android:layout_width="wrap_content"
|
|
||||||
android:layout_height="wrap_content"
|
|
||||||
android:layout_marginTop="20dp"
|
|
||||||
android:gravity="center"
|
|
||||||
android:text="铺贴层与料号信息正确"
|
|
||||||
android:textColor="#ff40FF5E"
|
|
||||||
android:textSize="22sp"
|
|
||||||
android:textStyle="bold" />
|
|
||||||
|
|
||||||
<TextView
|
|
||||||
android:id="@+id/resultSubtitle1"
|
|
||||||
android:layout_width="wrap_content"
|
|
||||||
android:layout_height="wrap_content"
|
|
||||||
android:layout_marginTop="10dp"
|
|
||||||
android:gravity="center"
|
|
||||||
android:text="识别到这是1/12张"
|
|
||||||
android:textColor="#ff40FF5E"
|
|
||||||
android:textSize="18sp" />
|
|
||||||
|
|
||||||
<TextView
|
|
||||||
android:id="@+id/resultSubtitle2"
|
|
||||||
android:layout_width="wrap_content"
|
|
||||||
android:layout_height="wrap_content"
|
|
||||||
android:layout_marginTop="8dp"
|
|
||||||
android:gravity="center"
|
|
||||||
android:text="请真空铺贴、纹理方向+90"
|
|
||||||
android:textColor="#ff40FF5E"
|
|
||||||
android:textSize="18sp" />
|
|
||||||
</LinearLayout>
|
|
||||||
|
|
||||||
<LinearLayout
|
|
||||||
android:id="@+id/groupWork"
|
|
||||||
android:layout_width="match_parent"
|
|
||||||
android:layout_height="match_parent"
|
|
||||||
android:gravity="center"
|
|
||||||
android:orientation="vertical"
|
|
||||||
android:visibility="gone">
|
|
||||||
|
|
||||||
<TextView
|
|
||||||
android:id="@+id/workText"
|
|
||||||
android:layout_width="wrap_content"
|
|
||||||
android:layout_height="wrap_content"
|
|
||||||
android:gravity="center"
|
|
||||||
android:lineSpacingExtra="6dp"
|
|
||||||
android:text="请进行铺贴工作"
|
|
||||||
android:textColor="#ff40FF5E"
|
|
||||||
android:textSize="22sp" />
|
|
||||||
</LinearLayout>
|
|
||||||
|
|
||||||
<LinearLayout
|
|
||||||
android:id="@+id/groupConfirm"
|
|
||||||
android:layout_width="match_parent"
|
|
||||||
android:layout_height="match_parent"
|
|
||||||
android:gravity="center"
|
|
||||||
android:orientation="vertical"
|
|
||||||
android:visibility="gone">
|
|
||||||
|
|
||||||
<TextView
|
|
||||||
android:id="@+id/confirmTitle"
|
|
||||||
android:layout_width="wrap_content"
|
|
||||||
android:layout_height="wrap_content"
|
|
||||||
android:gravity="center"
|
|
||||||
android:text="请确认是否已完成第3/12张铺贴"
|
|
||||||
android:textColor="#ff40FF5E"
|
|
||||||
android:textSize="22sp" />
|
|
||||||
</LinearLayout>
|
|
||||||
|
|
||||||
<LinearLayout
|
|
||||||
android:id="@+id/groupComplete"
|
|
||||||
android:layout_width="match_parent"
|
|
||||||
android:layout_height="match_parent"
|
|
||||||
android:gravity="center"
|
|
||||||
android:orientation="vertical"
|
|
||||||
android:visibility="gone">
|
|
||||||
|
|
||||||
<ImageView
|
|
||||||
android:layout_width="120dp"
|
|
||||||
android:layout_height="120dp"
|
|
||||||
android:src="@mipmap/ocr_true" />
|
|
||||||
|
|
||||||
<TextView
|
|
||||||
android:layout_width="wrap_content"
|
|
||||||
android:layout_height="wrap_content"
|
|
||||||
android:layout_marginTop="20dp"
|
|
||||||
android:gravity="center"
|
|
||||||
android:text="恭喜完成当前铺贴任务!"
|
|
||||||
android:textColor="#ff40FF5E"
|
|
||||||
android:textSize="22sp"
|
|
||||||
android:textStyle="bold" />
|
|
||||||
|
|
||||||
<TextView
|
|
||||||
android:id="@+id/completeSubtitle"
|
|
||||||
android:layout_width="wrap_content"
|
|
||||||
android:layout_height="wrap_content"
|
|
||||||
android:layout_marginTop="12dp"
|
|
||||||
android:gravity="center"
|
|
||||||
android:text="3S后自动返回铺贴任务界面"
|
|
||||||
android:textColor="#ff40FF5E"
|
|
||||||
android:textSize="18sp" />
|
|
||||||
</LinearLayout>
|
|
||||||
|
|
||||||
</FrameLayout>
|
|
||||||
|
|
||||||
</androidx.constraintlayout.widget.ConstraintLayout>
|
</androidx.constraintlayout.widget.ConstraintLayout>
|
||||||
</layout>
|
</layout>
|
||||||
|
|||||||
@ -103,13 +103,5 @@
|
|||||||
android:text="单击或语音输入“开始”,进入下一步"
|
android:text="单击或语音输入“开始”,进入下一步"
|
||||||
android:textColor="#ff40FF5E"
|
android:textColor="#ff40FF5E"
|
||||||
android:textSize="14sp"/>
|
android:textSize="14sp"/>
|
||||||
<ImageView
|
|
||||||
android:layout_width="120dp"
|
|
||||||
android:id="@+id/iv"
|
|
||||||
android:layout_height="150dp"
|
|
||||||
app:layout_constraintStart_toStartOf="parent"
|
|
||||||
app:layout_constraintEnd_toEndOf="parent"
|
|
||||||
app:layout_constraintTop_toBottomOf="@+id/hint"/>
|
|
||||||
|
|
||||||
</androidx.constraintlayout.widget.ConstraintLayout>
|
</androidx.constraintlayout.widget.ConstraintLayout>
|
||||||
</layout>
|
</layout>
|
||||||
|
|||||||
正在加载...
在新工单中引用
屏蔽一个用户