refactor(glass): 移除相机预览功能并简化拍照流程

- 从 GlassMediaServiceHelper 中移除相机画面共享相关方法
- 从 InspectionActivity 中移除预览相关的变量、回调和监听器
- 简化拍照逻辑,直接调用拍照功能而不经过预览流程
- 隐藏预览容器和缩放文本控件
- 移除缩放调整和预览超时处理逻辑
- 在拍照完成时不再停止预览服务
这个提交包含在:
徐勤民 2026-04-23 10:09:16 +08:00
父节点 fbbd205386
当前提交 ade4513cdf
共有 2 个文件被更改,包括 6 次插入201 次删除

查看文件

@ -1,9 +1,9 @@
package com.nova.brain.glass.helper
import android.view.Surface
import com.nova.brain.glass.helper.GlassMediaServiceHelper.addPhotoCallback
import com.nova.brain.glass.helper.GlassMediaServiceHelper.getMaxZoomLevel
import com.rokid.security.glass3.open.sdk.GlassSdk
import com.rokid.security.system.server.media.IMediaServer
import com.rokid.security.system.server.media.callback.ICameraSurfaceCallback
import com.rokid.security.system.server.media.callback.PhotoFileCallback
/**
@ -49,16 +49,6 @@ object GlassMediaServiceHelper {
service()?.removePhotoCallback(callback)
}
/** 开始将相机画面共享到指定 Surface用于预览。 */
fun startCameraShare(surface: Surface, callback: ICameraSurfaceCallback) {
service()?.startCameraShare(surface, callback)
}
/** 停止相机画面共享。 */
fun stopCameraShare(callback: ICameraSurfaceCallback) {
service()?.stopCameraShare(callback)
}
/** 获取当前硬件支持的最大变焦级别。 */
fun getMaxZoomLevel(): Int {
return service()?.maxZoomLevel ?: 0

查看文件

@ -2,12 +2,7 @@ package com.nova.brain.glass.ui
import android.content.Intent
import android.os.Environment
import android.os.Handler
import android.os.Looper
import android.view.WindowManager
import android.view.Surface
import android.view.TextureView
import android.view.View
import androidx.recyclerview.widget.RecyclerView
import com.nova.brain.glass.R
import com.nova.brain.glass.databinding.ActivityInspectionBinding
@ -19,7 +14,6 @@ import com.nova.brain.glass.model.ItemItem
import com.nova.brain.glass.viewmodel.InspectionValidateState
import com.nova.brain.glass.viewmodel.InspectionVM
import com.rokid.security.glass3.sdk.base.data.media.PhotoResolution
import com.rokid.security.system.server.media.callback.ICameraSurfaceCallback
import com.rokid.security.system.server.media.callback.PhotoFileCallback
import com.xuqm.base.adapter.BasePagedAdapter
import com.xuqm.base.adapter.CommonPagedAdapter
@ -39,20 +33,6 @@ class InspectionActivity :
private val glassTaskId: String by lazy { intent.getStringExtra("glassTaskId").orEmpty() }
private var pendingPhotoPath: String? = null
private var isPreviewRequested = false
private var isPreviewActive = false
private var currentZoomLevel = 1
private var maxZoomLevel = 1
private var previewStartAttempted = false
private var previewSurface: Surface? = null
private val mainHandler = Handler(Looper.getMainLooper())
private val previewTimeoutRunnable = Runnable {
if (isPreviewActive || !isPreviewRequested) return@Runnable
LogHelper.d("Inspection preview timeout, fallback to direct takePhoto")
stopCameraPreview()
binding.hint.text = "预览不可用,直接拍照中,请稍后..."
takePhoto()
}
private val listener = object : OfflineCmdListener {
override fun onOfflineCmd(cmd: String) {
@ -61,84 +41,18 @@ class InspectionActivity :
when (cmd) {
"退出", "返回", "退回" -> finish()
"开始", "开始任务" -> startCapture()
"拍照", "拍摄" -> if (isPreviewActive) capturePhoto() else startCapture()
"放大", "拉近" -> adjustZoom(1)
"缩小", "拉远" -> adjustZoom(-1)
"拍照", "拍摄" -> startCapture()
}
}
}
}
private val cameraSurfaceCallbackId = UUID.randomUUID().toString()
private val cameraSurfaceCallback = object : ICameraSurfaceCallback.Stub() {
override fun onCameraOpened(width: Int, height: Int) {
LogHelper.d("Inspection preview onCameraOpened: ${width}x$height")
isPreviewActive = true
mainHandler.removeCallbacks(previewTimeoutRunnable)
currentZoomLevel = GlassMediaServiceHelper.getZoomLevel().coerceAtLeast(1)
maxZoomLevel = GlassMediaServiceHelper.getMaxZoomLevel().coerceAtLeast(1)
runOnUiThread {
binding.cameraPreviewContainer.visibility = View.VISIBLE
binding.zoomText.visibility = View.VISIBLE
updateZoomText()
binding.hint.text = "预览中,单击预览或语音输入“拍照”完成拍摄"
}
}
override fun onCameraClosed() {
LogHelper.d("Inspection preview onCameraClosed")
isPreviewActive = false
mainHandler.removeCallbacks(previewTimeoutRunnable)
runOnUiThread {
binding.cameraPreviewContainer.visibility = View.GONE
binding.zoomText.visibility = View.GONE
}
}
override fun onError(code: Int, message: String?) {
LogHelper.d("Inspection preview onError: code=$code msg=$message")
isPreviewActive = false
mainHandler.removeCallbacks(previewTimeoutRunnable)
runOnUiThread {
binding.cameraPreviewContainer.visibility = View.GONE
binding.zoomText.visibility = View.GONE
binding.hint.text = "相机预览失败,请重试"
(message ?: "相机预览失败").showMessage()
}
}
override fun getCallbackId(): String = cameraSurfaceCallbackId
}
private val previewTextureListener = object : TextureView.SurfaceTextureListener {
override fun onSurfaceTextureAvailable(surface: android.graphics.SurfaceTexture, width: Int, height: Int) {
LogHelper.d("Inspection preview surface available: ${width}x$height, requested=$isPreviewRequested")
if (isPreviewRequested) {
startCameraPreview()
}
}
override fun onSurfaceTextureSizeChanged(
surface: android.graphics.SurfaceTexture,
width: Int,
height: Int
) = Unit
override fun onSurfaceTextureDestroyed(surface: android.graphics.SurfaceTexture): Boolean = true
override fun onSurfaceTextureUpdated(surface: android.graphics.SurfaceTexture) = Unit
}
override fun initData() {
super.initData()
window.addFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON)
SprayingPhotoManager.clear()
binding.cameraPreview.surfaceTextureListener = previewTextureListener
binding.cameraPreview.setOnClickListener {
if (isPreviewActive) {
capturePhoto()
}
}
binding.cameraPreviewContainer.visibility = android.view.View.GONE
binding.zoomText.visibility = android.view.View.GONE
viewModel.taskInfo.observe(this) { item ->
if (item != null) {
@ -186,109 +100,13 @@ class InspectionActivity :
}
private fun startCapture() {
if (viewModel.validateState.value == InspectionValidateState.LOADING) return
if (isPreviewActive) {
capturePhoto()
return
}
LogHelper.d("Inspection startCapture: previewActive=$isPreviewActive, textureAvailable=${binding.cameraPreview.isAvailable}")
binding.hint.text = "相机预览启动中,请稍后..."
isPreviewRequested = true
previewStartAttempted = false
SprayingPhotoManager.clear()
binding.cameraPreviewContainer.visibility = View.VISIBLE
binding.zoomText.visibility = View.VISIBLE
if (binding.cameraPreview.isAvailable) {
startCameraPreview()
} else {
binding.cameraPreview.post {
LogHelper.d("Inspection preview post check: textureAvailable=${binding.cameraPreview.isAvailable}, requested=$isPreviewRequested")
if (isPreviewRequested && binding.cameraPreview.isAvailable) {
startCameraPreview()
}
}
}
}
private fun startCameraPreview() {
if (!isPreviewRequested || previewStartAttempted) {
LogHelper.d("Inspection startCameraPreview skipped: requested=$isPreviewRequested attempted=$previewStartAttempted")
return
}
val surfaceTexture = binding.cameraPreview.surfaceTexture ?: return
val width = binding.cameraPreview.width.coerceAtLeast(1)
val height = binding.cameraPreview.height.coerceAtLeast(1)
surfaceTexture.setDefaultBufferSize(width, height)
previewStartAttempted = true
previewSurface?.release()
previewSurface = Surface(surfaceTexture)
LogHelper.d("Inspection startCameraPreview invoke startCameraShare, buffer=${width}x$height")
mainHandler.removeCallbacks(previewTimeoutRunnable)
mainHandler.postDelayed(previewTimeoutRunnable, 1000L)
runCatching {
GlassMediaServiceHelper.startCameraShare(previewSurface!!, cameraSurfaceCallback)
}.onFailure {
isPreviewRequested = false
previewStartAttempted = false
mainHandler.removeCallbacks(previewTimeoutRunnable)
previewSurface?.release()
previewSurface = null
binding.cameraPreviewContainer.visibility = View.GONE
binding.zoomText.visibility = View.GONE
binding.hint.text = "相机预览启动失败,请重试"
LogHelper.e("Inspection startCameraPreview failed: ${it.message}", it)
(it.message ?: "相机预览启动失败").showMessage()
}
}
private fun stopCameraPreview() {
isPreviewRequested = false
isPreviewActive = false
previewStartAttempted = false
mainHandler.removeCallbacks(previewTimeoutRunnable)
LogHelper.d("Inspection stopCameraPreview")
runCatching {
GlassMediaServiceHelper.stopCameraShare(cameraSurfaceCallback)
}.onFailure {
LogHelper.e("Inspection stopCameraPreview failed: ${it.message}", it)
}
previewSurface?.release()
previewSurface = null
binding.cameraPreviewContainer.visibility = View.GONE
binding.zoomText.visibility = View.GONE
}
private fun capturePhoto() {
if (viewModel.validateState.value == InspectionValidateState.LOADING) return
binding.hint.text = "拍照中,请稍后..."
SprayingPhotoManager.clear()
takePhoto()
}
private fun adjustZoom(delta: Int) {
if (!isPreviewActive) return
maxZoomLevel = GlassMediaServiceHelper.getMaxZoomLevel().coerceAtLeast(1)
currentZoomLevel = (GlassMediaServiceHelper.getZoomLevel() + delta).coerceIn(1, maxZoomLevel)
runCatching {
GlassMediaServiceHelper.zoomCamera(currentZoomLevel)
}.onSuccess {
updateZoomText()
}.onFailure {
(it.message ?: "缩放失败").showMessage()
}
}
private fun updateZoomText() {
binding.zoomText.text = "缩放 ${currentZoomLevel}x"
}
private fun takePhoto() {
runCatching {
val maxZoom = GlassMediaServiceHelper.getMaxZoomLevel().coerceAtLeast(1)
GlassMediaServiceHelper.zoomCamera(maxZoom)
currentZoomLevel = maxZoom
}.onFailure {
LogHelper.e("Inspection takePhoto set max zoom failed: ${it.message}", it)
}
val fileName = "inspection_${System.currentTimeMillis()}.png"
val file = File(
Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_PICTURES),
@ -309,7 +127,6 @@ class InspectionActivity :
override fun onTakePhotoV2(path: String?, width: Int, height: Int) {
if (path == null) {
runOnUiThread {
stopCameraPreview()
binding.hint.text = "单击或语音输入\"开始\",进入下一步"
}
"相机异常".showMessage()
@ -318,7 +135,6 @@ class InspectionActivity :
SprayingPhotoManager.addPhoto(path)
pendingPhotoPath = path
runOnUiThread {
stopCameraPreview()
viewModel.validateDocument(path)
}
}
@ -347,7 +163,6 @@ class InspectionActivity :
override fun onPause() {
super.onPause()
stopCameraPreview()
GlassMediaServiceHelper.removePhotoCallback(mPhotoFileCallback)
OfflineCmdServiceHelper.removeOnLineListener(listener)
OfflineCmdServiceHelper.removeListenerInspectionCapture()