Преглед изворни кода

feat(spraying): 添加喷涂功能的拍照和OCR识别支持

- 在OfflineCmdServiceHelper中新增喷涂相关的语音命令
- 为InspectionActivity、ReviewActivity和SprayingActivity添加屏幕常亮功能
- 新增SprayingOCRActivity用于OCR识别和图像显示
- 实现拍照功能,包括语音控制拍照和手动点击拍照
- 集成GlassSdk媒体服务进行照片拍摄和回调处理
- 添加照片预览和重拍功能
- 更新布局文件以支持拍照提示和图像显示
- 移除MainActivity并将启动目标改为SprayingOCRActivity
- 清理WelcomeActivity中的调试日志输出
徐勤民 пре 2 дана
родитељ
комит
989ce90cff

+ 1 - 1
app/src/main/AndroidManifest.xml

@@ -82,7 +82,7 @@
             android:name=".ui.SprayingActivity"
             android:name=".ui.SprayingActivity"
             android:exported="false" />
             android:exported="false" />
         <activity
         <activity
-            android:name=".ui.MainActivity"
+            android:name=".ui.SprayingOCRActivity"
             android:exported="false" />
             android:exported="false" />
         <activity
         <activity
             android:name=".ui.WelcomeActivity"
             android:name=".ui.WelcomeActivity"

+ 9 - 0
app/src/main/java/com/nova/brain/glass/helper/OfflineCmdServiceHelper.kt

@@ -137,6 +137,15 @@ object OfflineCmdServiceHelper {
         add(OfflineCmdBean("打开第十项任务", "da kai di shi xiang ren wu"))
         add(OfflineCmdBean("打开第十项任务", "da kai di shi xiang ren wu"))
         add(OfflineCmdBean("处理第十条任务", "chu li di shi tiao ren wu"))
         add(OfflineCmdBean("处理第十条任务", "chu li di shi tiao ren wu"))
         add(OfflineCmdBean("处理第十项任务", "chu li di shi xiang ren wu"))
         add(OfflineCmdBean("处理第十项任务", "chu li di shi xiang ren wu"))
+
+        //喷涂
+        add(OfflineCmdBean("开始", "kai shi"))
+        add(OfflineCmdBean("开始拍照", "kai shi pai zhao"))
+        add(OfflineCmdBean("拍照", "pai zhao"))
+        add(OfflineCmdBean("开始任务", "kai shi ren wu"))
+        add(OfflineCmdBean("重拍", "chong pai"))
+        add(OfflineCmdBean("重新拍", "chong xin pai"))
+        add(OfflineCmdBean("再拍一次", "zai pai yi ci"))
     }
     }
     fun init(){
     fun init(){
         val service = GlassSdk.getGlassOfflineCmdService()
         val service = GlassSdk.getGlassOfflineCmdService()

+ 1 - 0
app/src/main/java/com/nova/brain/glass/ui/InspectionActivity.kt

@@ -37,6 +37,7 @@ class InspectionActivity : BaseListFormLayoutNormalActivity<ItemItem, ItemListVM
     }
     }
     override fun initData() {
     override fun initData() {
         super.initData()
         super.initData()
+        window.addFlags(android.view.WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON)
         OfflineCmdServiceHelper.addOnLineListener(listener)
         OfflineCmdServiceHelper.addOnLineListener(listener)
     }
     }
 
 

+ 0 - 22
app/src/main/java/com/nova/brain/glass/ui/MainActivity.kt

@@ -1,22 +0,0 @@
-package com.nova.brain.glass.ui
-
-import android.os.Bundle
-import androidx.activity.viewModels
-import com.nova.brain.glass.R
-import com.nova.brain.glass.databinding.ActivityMainBinding
-import com.nova.brain.glass.viewmodel.MainVM
-import com.xuqm.base.ui.BaseActivity
-
-class MainActivity : BaseActivity<ActivityMainBinding>() {
-    override fun fullscreen(): Boolean = true
-    override fun getLayoutId(): Int = R.layout.activity_main
-
-    private val vm: MainVM by viewModels()
-
-    override fun initView(savedInstanceState: Bundle?) {
-        super.initView(savedInstanceState)
-
-
-    }
-
-}

+ 1 - 0
app/src/main/java/com/nova/brain/glass/ui/ReviewActivity.kt

@@ -37,6 +37,7 @@ class ReviewActivity : BaseListFormLayoutNormalActivity<ItemItem, ItemListVM, Ac
     }
     }
     override fun initData() {
     override fun initData() {
         super.initData()
         super.initData()
+        window.addFlags(android.view.WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON)
         OfflineCmdServiceHelper.addOnLineListener(listener)
         OfflineCmdServiceHelper.addOnLineListener(listener)
     }
     }
 
 

+ 76 - 3
app/src/main/java/com/nova/brain/glass/ui/SprayingActivity.kt

@@ -1,19 +1,29 @@
 package com.nova.brain.glass.ui
 package com.nova.brain.glass.ui
 
 
+import android.content.Intent
+import android.graphics.BitmapFactory
+import android.os.Environment
 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.ActivitySprayingBinding
 import com.nova.brain.glass.databinding.ActivitySprayingBinding
 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.ItemListVM
 import com.nova.brain.glass.viewmodel.SprayingVM
 import com.nova.brain.glass.viewmodel.SprayingVM
+import com.rokid.security.glass3.open.sdk.GlassSdk
+import com.rokid.security.glass3.sdk.base.data.media.PhotoResolution
+import com.rokid.security.system.server.media.callback.PhotoFileCallback
 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.extensions.showMessage
 import com.xuqm.base.ui.BaseListFormLayoutNormalActivity
 import com.xuqm.base.ui.BaseListFormLayoutNormalActivity
+import java.io.File
+import java.util.UUID
 
 
-class SprayingActivity : BaseListFormLayoutNormalActivity<ItemItem, SprayingVM, ActivitySprayingBinding>() {
+class SprayingActivity :
+    BaseListFormLayoutNormalActivity<ItemItem, SprayingVM, ActivitySprayingBinding>() {
     override fun getLayoutId(): Int = R.layout.activity_spraying
     override fun getLayoutId(): Int = R.layout.activity_spraying
     override fun fullscreen(): Boolean = true
     override fun fullscreen(): Boolean = true
 
 
@@ -26,28 +36,91 @@ class SprayingActivity : BaseListFormLayoutNormalActivity<ItemItem, SprayingVM,
                     "退出", "返回", "退回" -> {
                     "退出", "返回", "退回" -> {
                         finish()
                         finish()
                     }
                     }
+
+                    "开始", "拍照", "开始拍照", "开始任务" -> {
+                        runOnUiThread {
+                            binding.hint.text = "拍照中,请稍后..."
+                        }
+                        isPhoto = true
+                        takePhoto()
+                    }
                 }
                 }
             }
             }
         }
         }
+
+    }
+
+    fun takePhoto() {
+        val fileName = "test_${System.currentTimeMillis()}.png"
+        val publicPicturesDir =
+            Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_PICTURES)
+        val file = File(publicPicturesDir, fileName)
+        GlassSdk.getGlassMediaService()
+            ?.takePhoto(PhotoResolution.RESOLUTION_480P, file.absolutePath)
     }
     }
 
 
+    private val photoCallbackId = UUID.randomUUID().toString()
+
+    private val mPhotoFileCallback = object : PhotoFileCallback.Stub() {
+        override fun onTakePhoto(path: String) {
+            LogHelper.d("onTakePhoto-->path = $path")
+        }
+
+        override fun getCallbackId(): String {
+            return photoCallbackId
+        }
+
+        override fun onTakePhotoV2(path: String?, width: Int, height: Int) {
+            LogHelper.d("width:$width--height:$height")
+            if (path == null) {
+                if (isPhoto) {
+                    isPhoto = false
+                    takePhoto()
+                } else {
+                    runOnUiThread {
+                        binding.hint.text = "单击或语音输入“开始”,进入下一步"
+                    }
+                    "相机异常".showMessage()
+                }
+            } else {
+                startActivity(Intent(this@SprayingActivity, SprayingOCRActivity::class.java).apply {
+                    putExtra("path", path)
+                })
+                finish()
+//                runOnUiThread {
+//                    binding.hint.text = "单击或语音输入“开始”,进入下一步"
+//                    binding.iv.setImageBitmap(BitmapFactory.decodeFile(path))
+//                }
+            }
+        }
+    }
+
+
     override fun initData() {
     override fun initData() {
         super.initData()
         super.initData()
+        window.addFlags(android.view.WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON)
         OfflineCmdServiceHelper.addOnLineListener(listener)
         OfflineCmdServiceHelper.addOnLineListener(listener)
+        GlassSdk.getGlassMediaService()?.addPhotoCallback(mPhotoFileCallback)
     }
     }
 
 
     override fun onDestroy() {
     override fun onDestroy() {
         super.onDestroy()
         super.onDestroy()
         OfflineCmdServiceHelper.removeOnLineListener(listener)
         OfflineCmdServiceHelper.removeOnLineListener(listener)
+        GlassSdk.getGlassMediaService()?.removePhotoCallback(mPhotoFileCallback)
     }
     }
 
 
+    private var isPhoto = false
     private val adapter = object : CommonPagedAdapter<ItemItem>(R.layout.item_photo) {
     private val adapter = object : CommonPagedAdapter<ItemItem>(R.layout.item_photo) {
         override fun convert(holder: ViewHolder, item: ItemItem, position: Int) {
         override fun convert(holder: ViewHolder, item: ItemItem, position: Int) {
             holder
             holder
                 .setClickListener(R.id.photo) {
                 .setClickListener(R.id.photo) {
                     when (item.text) {
                     when (item.text) {
                         "拍照" -> {
                         "拍照" -> {
-
+                            runOnUiThread {
+                                binding.hint.text = "拍照中,请稍后..."
+                            }
+                            isPhoto = true
+                            takePhoto()
                         }
                         }
                     }
                     }
                 }
                 }

+ 129 - 0
app/src/main/java/com/nova/brain/glass/ui/SprayingOCRActivity.kt

@@ -0,0 +1,129 @@
+package com.nova.brain.glass.ui
+
+import android.R.attr.path
+import android.graphics.BitmapFactory
+import android.os.Environment
+import android.view.WindowManager
+import androidx.recyclerview.widget.RecyclerView
+import com.nova.brain.glass.R
+import com.nova.brain.glass.databinding.ActivitySprayingBinding
+import com.nova.brain.glass.databinding.ActivitySprayingOcrBinding
+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.SprayingVM
+import com.rokid.security.glass3.open.sdk.GlassSdk
+import com.rokid.security.glass3.sdk.base.data.media.PhotoResolution
+import com.rokid.security.system.server.media.callback.PhotoFileCallback
+import com.xuqm.base.adapter.BasePagedAdapter
+import com.xuqm.base.adapter.CommonPagedAdapter
+import com.xuqm.base.adapter.ViewHolder
+import com.xuqm.base.common.FileHelper
+import com.xuqm.base.common.LogHelper
+import com.xuqm.base.extensions.showMessage
+import com.xuqm.base.ui.BaseListFormLayoutNormalActivity
+import java.io.File
+import java.util.UUID
+
+class SprayingOCRActivity :
+    BaseListFormLayoutNormalActivity<ItemItem, SprayingVM, ActivitySprayingOcrBinding>() {
+    override fun getLayoutId(): Int = R.layout.activity_spraying_ocr
+    override fun fullscreen(): Boolean = true
+
+    override fun getRecyclerOrientation(): Int = RecyclerView.VERTICAL
+
+    private val listener = object : OfflineCmdListener {
+        override fun onOfflineCmd(cmd: String) {
+            runOnUiThread {
+                when (cmd) {
+                    "退出", "返回", "退回" -> {
+                        finish()
+                    }
+                    "开始", "拍照", "开始拍照", "开始任务", "重拍", "重新拍", "在拍一次" -> {
+                        runOnUiThread {
+                            binding.hint.text = "拍照中,请稍后..."
+                        }
+                        isPhoto = true
+                        takePhoto()
+                    }
+                }
+            }
+        }
+
+    }
+
+    fun takePhoto() {
+        val fileName = "test_${System.currentTimeMillis()}.png"
+        val publicPicturesDir = Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_PICTURES)
+        val file = File(publicPicturesDir, fileName)
+        GlassSdk.getGlassMediaService()?.takePhoto(PhotoResolution.RESOLUTION_480P, file.absolutePath)
+    }
+    private val photoCallbackId = UUID.randomUUID().toString()
+
+    private val mPhotoFileCallback = object : PhotoFileCallback.Stub() {
+        override fun onTakePhoto(path: String) {
+            LogHelper.d("onTakePhoto-->path = $path")
+        }
+
+        override fun getCallbackId(): String {
+            return photoCallbackId
+        }
+
+        override fun onTakePhotoV2(path: String?, width: Int, height: Int) {
+            LogHelper.d("width:$width--height:$height")
+            if (path == null) {
+                if (isPhoto) {
+                    isPhoto = false
+                    takePhoto()
+                } else {
+                    runOnUiThread {
+                        binding.hint.text = "单击或语音输入“重拍”,可重新拍摄"
+                    }
+                    "相机异常".showMessage()
+                }
+            } else {
+                runOnUiThread {
+                    binding.hint.text = "单击或语音输入“重拍”,可重新拍摄"
+                    binding.content.setImageBitmap(BitmapFactory.decodeFile(path))
+                }
+            }
+        }
+    }
+
+
+    override fun initData() {
+        super.initData()
+        window.addFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON)
+        OfflineCmdServiceHelper.addOnLineListener(listener)
+        GlassSdk.getGlassMediaService()?.addPhotoCallback(mPhotoFileCallback)
+        intent.getStringExtra("path")?.apply {
+            binding.content.setImageBitmap(BitmapFactory.decodeFile(this))
+        }
+    }
+
+    override fun onDestroy() {
+        super.onDestroy()
+        OfflineCmdServiceHelper.removeOnLineListener(listener)
+        GlassSdk.getGlassMediaService()?.removePhotoCallback(mPhotoFileCallback)
+    }
+
+    private var isPhoto = false
+    private val adapter = object : CommonPagedAdapter<ItemItem>(R.layout.item_photo) {
+        override fun convert(holder: ViewHolder, item: ItemItem, position: Int) {
+            holder
+                .setClickListener(R.id.photo) {
+                    when (item.text) {
+                        "拍照" -> {
+                            runOnUiThread {
+                                binding.hint.text = "拍照中,请稍后..."
+                            }
+                            isPhoto = true
+                            takePhoto()
+                        }
+                    }
+                }
+        }
+    }
+
+    override fun adapter(): BasePagedAdapter<ItemItem> = adapter
+}

+ 0 - 2
app/src/main/java/com/nova/brain/glass/ui/WelcomeActivity.kt

@@ -39,13 +39,11 @@ class WelcomeActivity : BaseActivity<ActivityWelcomeBinding>() {
 
 
     override fun onResume() {
     override fun onResume() {
         super.onResume()
         super.onResume()
-        LogHelper.d(">>>>>>>>>>>>>>>>>>>>>>>>>>>>>")
         OfflineCmdServiceHelper.addOnLineListener(offlineCmdListener)
         OfflineCmdServiceHelper.addOnLineListener(offlineCmdListener)
     }
     }
 
 
     override fun onPause() {
     override fun onPause() {
         super.onPause()
         super.onPause()
-        LogHelper.d("---------------------------")
         OfflineCmdServiceHelper.removeOnLineListener(offlineCmdListener)
         OfflineCmdServiceHelper.removeOnLineListener(offlineCmdListener)
     }
     }
 
 

+ 8 - 0
app/src/main/res/layout/activity_spraying.xml

@@ -94,6 +94,7 @@
         <TextView
         <TextView
             android:layout_width="match_parent"
             android:layout_width="match_parent"
             android:layout_marginStart="15dp"
             android:layout_marginStart="15dp"
+            android:id="@+id/hint"
             android:layout_marginTop="10dp"
             android:layout_marginTop="10dp"
             android:layout_height="wrap_content"
             android:layout_height="wrap_content"
             app:layout_constraintTop_toBottomOf="@+id/baseRecyclerView"
             app:layout_constraintTop_toBottomOf="@+id/baseRecyclerView"
@@ -102,6 +103,13 @@
             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>

+ 58 - 0
app/src/main/res/layout/activity_spraying_ocr.xml

@@ -0,0 +1,58 @@
+<?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">
+
+        <TextView
+            android:id="@+id/tvTaskHeader"
+            android:layout_width="0dp"
+            android:layout_height="wrap_content"
+            android:layout_marginTop="67dp"
+            android:background="@drawable/bg_item"
+            android:text="OCR识别中,请稍后..."
+            android:gravity="center"
+            android:textColor="#ff40FF5E"
+            android:textSize="20sp"
+            app:layout_constraintEnd_toEndOf="parent"
+            app:layout_constraintStart_toStartOf="parent"
+            app:layout_constraintTop_toTopOf="parent" />
+
+        <ImageView
+            android:layout_width="120dp"
+            android:id="@+id/content"
+            android:layout_height="wrap_content"
+            android:layout_marginTop="12dp"
+            app:layout_constraintStart_toStartOf="parent"
+            app:layout_constraintEnd_toEndOf="parent"
+            app:layout_constraintTop_toBottomOf="@+id/tvTaskHeader"/>
+
+        <androidx.recyclerview.widget.RecyclerView
+            android:id="@+id/baseRecyclerView"
+            android:layout_width="0dp"
+            android:layout_height="88dp"
+            android:clipToPadding="false"
+            android:layout_marginTop="12dp"
+            android:overScrollMode="never"
+            app:layout_constraintEnd_toEndOf="parent"
+            app:layout_constraintStart_toStartOf="parent"
+            app:layout_constraintTop_toBottomOf="@id/content" />
+        <TextView
+            android:layout_width="match_parent"
+            android:layout_marginStart="15dp"
+            android:id="@+id/hint"
+            android:layout_marginTop="10dp"
+            android:layout_height="wrap_content"
+            app:layout_constraintTop_toBottomOf="@+id/baseRecyclerView"
+            android:layout_marginVertical="4dp"
+            android:gravity="center"
+            android:text="单击或语音输入“重拍”,可重新拍摄"
+            android:textColor="#ff40FF5E"
+            android:textSize="14sp"/>
+
+    </androidx.constraintlayout.widget.ConstraintLayout>
+</layout>

+ 0 - 5
app/src/main/res/layout/activity_welcome.xml

@@ -8,18 +8,13 @@
             android:id="@+id/tv"
             android:id="@+id/tv"
             android:layout_width="wrap_content"
             android:layout_width="wrap_content"
             android:layout_height="wrap_content"
             android:layout_height="wrap_content"
-            android:background="@color/app_color_black"
-            android:layout_alignParentTop="true"
             android:textColor="#ff3FFF5F"
             android:textColor="#ff3FFF5F"
             android:textSize="19sp"
             android:textSize="19sp"
             android:text="您可以说:Nova,我的任务有哪些?"
             android:text="您可以说:Nova,我的任务有哪些?"
-            android:fontFamily="Source Han Sans"
             app:layout_constraintTop_toTopOf="parent"
             app:layout_constraintTop_toTopOf="parent"
             app:layout_constraintEnd_toEndOf="parent"
             app:layout_constraintEnd_toEndOf="parent"
             app:layout_constraintBottom_toBottomOf="parent"
             app:layout_constraintBottom_toBottomOf="parent"
             app:layout_constraintStart_toStartOf="parent"
             app:layout_constraintStart_toStartOf="parent"
-            android:gravity="left|top"
-            android:alpha="1"
             />
             />
 
 
     </androidx.constraintlayout.widget.ConstraintLayout>
     </androidx.constraintlayout.widget.ConstraintLayout>