feat(glass): 添加离线语音命令功能和审查界面

- 在 OfflineCmdServiceHelper 中添加同意、驳回、拒绝等语音命令
- 创建新的 ItemItem 数据模型用于列表项显示
- 新增 InspectionActivity 和 ReviewActivity 界面用于检查和审查流程
- 实现语音命令监听器处理各种审批操作
- 添加相应的布局文件 activity_inspection.xml 和 activity_review.xml
- 创建背景样式资源文件用于界面美化
- 在 TaskListActivity 中添加跳转到 ReviewActivity 的功能
- 移除基础组件中的加载完成提示以避免干扰用户体验
这个提交包含在:
徐勤民 2026-04-14 16:19:05 +08:00
父节点 e085f9d5ac
当前提交 c587df2e4b
共有 16 个文件被更改,包括 311 次插入6 次删除

查看文件

@ -69,6 +69,9 @@
<activity <activity
android:name=".ui.FoActivity" android:name=".ui.FoActivity"
android:exported="false" /> android:exported="false" />
<activity
android:name=".ui.ReviewActivity"
android:exported="false" />
<activity <activity
android:name=".ui.TaskListActivity" android:name=".ui.TaskListActivity"
android:exported="false" /> android:exported="false" />

查看文件

@ -25,6 +25,11 @@ object OfflineCmdServiceHelper {
add(OfflineCmdBean("退出", "tui chu")) add(OfflineCmdBean("退出", "tui chu"))
add(OfflineCmdBean("返回", "fan hui")) add(OfflineCmdBean("返回", "fan hui"))
add(OfflineCmdBean("退回", "tui hui")) add(OfflineCmdBean("退回", "tui hui"))
add(OfflineCmdBean("同意", "tong yi"))
add(OfflineCmdBean("驳回", "bo hui"))
add(OfflineCmdBean("不同意", "bu tong yi"))
add(OfflineCmdBean("拒绝", "ju jue"))
add(OfflineCmdBean("通过", "tong guo"))
} }
fun init(){ fun init(){
val service = GlassSdk.getGlassOfflineCmdService() val service = GlassSdk.getGlassOfflineCmdService()

查看文件

@ -0,0 +1,6 @@
package com.nova.brain.glass.model
import com.xuqm.base.adapter.BaseItem
data class ItemItem(val text: String): BaseItem() {
}

查看文件

@ -0,0 +1,37 @@
package com.nova.brain.glass.ui
import com.nova.brain.glass.R
import com.nova.brain.glass.databinding.ActivityFoBinding
import com.nova.brain.glass.databinding.ActivityReviewBinding
import com.nova.brain.glass.helper.OfflineCmdListener
import com.nova.brain.glass.helper.OfflineCmdServiceHelper
import com.xuqm.base.ui.BaseActivity
class InspectionActivity : BaseActivity<ActivityReviewBinding>() {
override fun getLayoutId(): Int =R.layout.activity_review
override fun fullscreen(): Boolean = true
private val listener = object : OfflineCmdListener {
override fun onOfflineCmd(cmd: String) {
when( cmd){
"退出","返回","退回"->{
finish()
}
"驳回","拒绝","不同意"->{
finish()
}
"同意","通过"->{
finish()
}
}
}
}
override fun initData() {
super.initData()
OfflineCmdServiceHelper.addOnLineListener(listener)
}
override fun onDestroy() {
super.onDestroy()
OfflineCmdServiceHelper.removeOnLineListener(listener)
}
}

查看文件

@ -0,0 +1,64 @@
package com.nova.brain.glass.ui
import android.content.Intent
import com.nova.brain.glass.R
import com.nova.brain.glass.databinding.ActivityFoBinding
import com.nova.brain.glass.databinding.ActivityReviewBinding
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.model.TaskItem
import com.nova.brain.glass.viewmodel.ItemListVM
import com.xuqm.base.adapter.BasePagedAdapter
import com.xuqm.base.adapter.CommonPagedAdapter
import com.xuqm.base.adapter.ViewHolder
import com.xuqm.base.ui.BaseActivity
import com.xuqm.base.ui.BaseListFormLayoutActivity
class ReviewActivity : BaseListFormLayoutActivity<ItemItem, ItemListVM,ActivityReviewBinding>() {
override fun getLayoutId(): Int =R.layout.activity_review
override fun fullscreen(): Boolean = true
private val listener = object : OfflineCmdListener {
override fun onOfflineCmd(cmd: String) {
when( cmd){
"退出","返回","退回"->{
finish()
}
"驳回","拒绝","不同意"->{
finish()
}
"同意","通过"->{
finish()
}
}
}
}
override fun initData() {
super.initData()
OfflineCmdServiceHelper.addOnLineListener(listener)
}
override fun onDestroy() {
super.onDestroy()
OfflineCmdServiceHelper.removeOnLineListener(listener)
}
private val adapter = object : CommonPagedAdapter<ItemItem>(R.layout.item_item) {
override fun convert(holder: ViewHolder, item: ItemItem, position: Int) {
holder
.setText(R.id.text, item.text)
.setClickListener(R.id.text
) {
when(item.text){
"同意" -> {
finish()
}
"拒绝" -> {
finish()
}
}
}
}
}
override fun adapter(): BasePagedAdapter<ItemItem> = adapter
}

查看文件

@ -12,6 +12,7 @@ import com.nova.brain.glass.viewmodel.TaskListVM
import com.xuqm.base.adapter.BasePagedAdapter import com.xuqm.base.adapter.BasePagedAdapter
import com.xuqm.base.adapter.CommonPagedAdapter 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.ToolsHelper import com.xuqm.base.common.ToolsHelper
import com.xuqm.base.ui.BaseListFormLayoutActivity import com.xuqm.base.ui.BaseListFormLayoutActivity
@ -63,6 +64,7 @@ class TaskListActivity :
val layoutManager = binding.baseRecyclerView.layoutManager as? LinearLayoutManager val layoutManager = binding.baseRecyclerView.layoutManager as? LinearLayoutManager
if (layoutManager != null) { if (layoutManager != null) {
val lastVisible = layoutManager.findLastVisibleItemPosition() val lastVisible = layoutManager.findLastVisibleItemPosition()
LogHelper.d("lastVisible:$lastVisible")
if (lastVisible < adapter.itemCount) { if (lastVisible < adapter.itemCount) {
layoutManager.scrollToPositionWithOffset(lastVisible, 0) layoutManager.scrollToPositionWithOffset(lastVisible, 0)
} else { } else {
@ -91,6 +93,9 @@ class TaskListActivity :
0 -> { 0 -> {
startActivity(Intent(this@TaskListActivity, FoActivity::class.java)) startActivity(Intent(this@TaskListActivity, FoActivity::class.java))
} }
1 -> {
startActivity(Intent(this@TaskListActivity, ReviewActivity::class.java))
}
} }
} }
} }

查看文件

@ -0,0 +1,18 @@
package com.nova.brain.glass.viewmodel
import com.nova.brain.glass.model.ItemItem
import com.nova.brain.glass.model.TaskItem
import com.xuqm.base.viewmodel.BaseListViewModel
import com.xuqm.base.viewmodel.callback.Response
class ItemListVM: BaseListViewModel<ItemItem>() {
override fun loadData(
page: Int,
onResponse: Response<ItemItem>
) {
onResponse.onResponse(arrayListOf<ItemItem>().apply {
add(ItemItem("驳回"))
add(ItemItem("同意"))
})
}
}

查看文件

@ -0,0 +1,5 @@
<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<item android:state_focused="true" android:drawable="@drawable/bg_selected"/>
<item android:state_focused="false" android:drawable="@drawable/bg_task_title_normal"/>
</selector>

查看文件

@ -0,0 +1,9 @@
<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android"
android:shape="rectangle">
<solid android:color="#1040FF5E" />
<stroke
android:width="2dp"
android:color="#ff40FF5E" />
<corners android:radius="4dp" />
</shape>

查看文件

@ -0,0 +1,14 @@
<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android"
android:shape="rectangle">
<solid android:color="#1040FF5E" />
<stroke
android:width="2dp"
android:color="#ff40FF5E" />
<corners android:radius="4dp" />
<padding
android:bottom="5dp"
android:left="10dp"
android:right="10dp"
android:top="5dp" />
</shape>

查看文件

@ -0,0 +1,65 @@
<?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"
xmlns:tools="http://schemas.android.com/tools"
android:id="@+id/main"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="@color/app_color_black">
<TextView
android:id="@+id/tvTaskHeader"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:text="130工序要求如下"
android:textColor="#ff40FF5E"
android:background="@drawable/bg_item"
android:textSize="20sp"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
<TextView
android:id="@+id/content"
android:layout_width="0dp"
android:background="@drawable/bg_item"
android:layout_height="300dp"
android:text="采用手工铺贴,按操作规程CD1442要求进行铺贴,将铺层信息填写在表SAMC 31-71《零件铺层信息、生产记录表》中,并扫描上传。 1I型表面胶膜铺贴最大搭接6mm或对接最大间隙1.5mm。按投影线及工装余量刻线进行铺贴。 2织物铺层的方向公差为±5°,铺贴中允许搭接13mm25mm或对接间隙≤1.5mm,拼缝错开至少25mm,同向铺层之间可以每隔4层重复拼缝的错开位置。按投影线及工装余量刻线进行铺贴,加强层铺贴位置公差为投影位置±2.5mm。"
android:textColor="#ff40FF5E"
android:layout_marginTop="10dp"
android:lineHeight="20sp"
android:textSize="16sp"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@+id/tvTaskHeader" />
<TextView
android:id="@+id/reject"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="20dp"
android:textColor="#ff40FF5E"
android:background="@drawable/bg_item"
android:textSize="16sp"
android:paddingHorizontal="10dp"
android:paddingVertical="3dp"
android:text="驳回"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@+id/content" />
<TextView
android:id="@+id/agree"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="20dp"
android:textColor="#ff40FF5E"
android:background="@drawable/bg_item"
android:textSize="16sp"
android:paddingHorizontal="10dp"
android:layout_marginLeft="10dp"
android:paddingVertical="3dp"
android:text="同意"
app:layout_constraintStart_toEndOf="@+id/reject"
app:layout_constraintTop_toBottomOf="@+id/content" />
</androidx.constraintlayout.widget.ConstraintLayout>
</layout>

查看文件

@ -0,0 +1,63 @@
<?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"
xmlns:tools="http://schemas.android.com/tools"
android:id="@+id/main"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="@color/app_color_black">
<TextView
android:id="@+id/tvTaskHeader"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:text="130工序要求如下"
android:textColor="#ff40FF5E"
android:background="@drawable/bg_item"
android:textSize="20sp"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
<TextView
android:id="@+id/content"
android:layout_width="0dp"
android:background="@drawable/bg_item"
android:layout_height="300dp"
android:text="采用手工铺贴,按操作规程CD1442要求进行铺贴,将铺层信息填写在表SAMC 31-71《零件铺层信息、生产记录表》中,并扫描上传。 1I型表面胶膜铺贴最大搭接6mm或对接最大间隙1.5mm。按投影线及工装余量刻线进行铺贴。 2织物铺层的方向公差为±5°,铺贴中允许搭接13mm25mm或对接间隙≤1.5mm,拼缝错开至少25mm,同向铺层之间可以每隔4层重复拼缝的错开位置。按投影线及工装余量刻线进行铺贴,加强层铺贴位置公差为投影位置±2.5mm。"
android:textColor="#ff40FF5E"
android:layout_marginTop="10dp"
android:lineHeight="20sp"
android:textSize="16sp"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@+id/tvTaskHeader" />
<androidx.swiperefreshlayout.widget.SwipeRefreshLayout
android:id="@+id/baseRefreshLayout"
android:layout_width="0dp"
android:layout_height="50dp"
android:layout_marginTop="16dp"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@id/content">
<com.xuqm.base.view.EmptyView
android:id="@+id/baseEmptyView"
android:layout_width="match_parent"
android:layout_height="match_parent">
<androidx.recyclerview.widget.RecyclerView
android:id="@+id/baseRecyclerView"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="horizontal"
android:overScrollMode="never"
app:layoutManager="androidx.recyclerview.widget.LinearLayoutManager" />
</com.xuqm.base.view.EmptyView>
</androidx.swiperefreshlayout.widget.SwipeRefreshLayout>
</androidx.constraintlayout.widget.ConstraintLayout>
</layout>

查看文件

@ -0,0 +1,11 @@
<?xml version="1.0" encoding="utf-8"?>
<TextView xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/text"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textColor="#ff40FF5E"
android:background="@drawable/bg_item"
android:textSize="16sp"
android:paddingHorizontal="10dp"
android:paddingVertical="3dp"
android:text="驳回"/>

查看文件

@ -137,7 +137,7 @@ public abstract class BaseListActivity<T extends BaseItem, VM extends BaseListVi
getBinding().baseEmptyView.setStatus(Status.NO_DATA); getBinding().baseEmptyView.setStatus(Status.NO_DATA);
else if (result == RefreshResult.NO_MORE) { else if (result == RefreshResult.NO_MORE) {
getBinding().baseEmptyView.setStatus(Status.DISMISS); getBinding().baseEmptyView.setStatus(Status.DISMISS);
ToolsHelper.snack(getBinding().baseEmptyView, "全部加载完成"); // ToolsHelper.snack(getBinding().baseEmptyView, "全部加载完成");
} }
} }
@ -146,7 +146,7 @@ public abstract class BaseListActivity<T extends BaseItem, VM extends BaseListVi
// } else if (result == RefreshResult.FAILED) { // } else if (result == RefreshResult.FAILED) {
// } else // } else
if (result == RefreshResult.NO_MORE) { if (result == RefreshResult.NO_MORE) {
ToolsHelper.snack(getBinding().baseEmptyView, "全部加载完成"); // ToolsHelper.snack(getBinding().baseEmptyView, "全部加载完成");
} }
} }

查看文件

@ -150,7 +150,7 @@ public abstract class BaseListAppBarFragment<T extends BaseItem, VM extends Base
getBinding().baseEmptyView.setStatus(Status.NO_DATA); getBinding().baseEmptyView.setStatus(Status.NO_DATA);
else if (result == RefreshResult.NO_MORE) { else if (result == RefreshResult.NO_MORE) {
getBinding().baseEmptyView.setStatus(Status.DISMISS); getBinding().baseEmptyView.setStatus(Status.DISMISS);
ToolsHelper.snack(getBinding().baseEmptyView, "全部加载完成"); // ToolsHelper.snack(getBinding().baseEmptyView, "全部加载完成");
} }
} }
@ -159,7 +159,7 @@ public abstract class BaseListAppBarFragment<T extends BaseItem, VM extends Base
// } else if (result == RefreshResult.FAILED) { // } else if (result == RefreshResult.FAILED) {
// } else // } else
if (result == RefreshResult.NO_MORE) { if (result == RefreshResult.NO_MORE) {
ToolsHelper.snack(getBinding().baseEmptyView, "全部加载完成"); // ToolsHelper.snack(getBinding().baseEmptyView, "全部加载完成");
} }
} }

查看文件

@ -150,7 +150,7 @@ public abstract class BaseListFormLayoutActivity<T extends BaseItem, VM extends
baseEmptyView.setStatus(Status.NO_DATA); baseEmptyView.setStatus(Status.NO_DATA);
else if (result == RefreshResult.NO_MORE) { else if (result == RefreshResult.NO_MORE) {
baseEmptyView.setStatus(Status.DISMISS); baseEmptyView.setStatus(Status.DISMISS);
ToolsHelper.snack(baseEmptyView, "全部加载完成"); // ToolsHelper.snack(baseEmptyView, "全部加载完成");
} }
} }
@ -159,7 +159,7 @@ public abstract class BaseListFormLayoutActivity<T extends BaseItem, VM extends
// } else if (result == RefreshResult.FAILED) { // } else if (result == RefreshResult.FAILED) {
// } else // } else
if (result == RefreshResult.NO_MORE) { if (result == RefreshResult.NO_MORE) {
ToolsHelper.snack(baseEmptyView, "全部加载完成"); // ToolsHelper.snack(baseEmptyView, "全部加载完成");
} }
} }