feat(camera): 添加相机预览超时处理机制

- 引入 Handler 和 Looper 处理异步操作
- 实现预览超时检测功能,超时后自动执行拍照
- 在相机打开、关闭和出错时移除超时回调
- 开始预览时启动超时计时器,1秒后触发
- 执行拍照前移除所有待执行的超时回调
- 显示预览不可用时的用户提示信息
这个提交包含在:
徐勤民 2026-04-21 18:16:55 +08:00
父节点 4319bbad86
当前提交 59eb5cc33b

查看文件

@ -2,6 +2,8 @@ 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
@ -43,6 +45,14 @@ class InspectionActivity :
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) {
@ -64,6 +74,7 @@ class InspectionActivity :
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 {
@ -77,6 +88,7 @@ class InspectionActivity :
override fun onCameraClosed() {
LogHelper.d("Inspection preview onCameraClosed")
isPreviewActive = false
mainHandler.removeCallbacks(previewTimeoutRunnable)
runOnUiThread {
binding.cameraPreviewContainer.visibility = View.GONE
binding.zoomText.visibility = View.GONE
@ -86,6 +98,7 @@ class InspectionActivity :
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
@ -208,11 +221,14 @@ class InspectionActivity :
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
@ -227,6 +243,7 @@ class InspectionActivity :
isPreviewRequested = false
isPreviewActive = false
previewStartAttempted = false
mainHandler.removeCallbacks(previewTimeoutRunnable)
LogHelper.d("Inspection stopCameraPreview")
runCatching {
GlassMediaServiceHelper.stopCameraShare(cameraSurfaceCallback)