添加了图片拍照及识别逻辑
This commit is contained in:
@@ -63,65 +63,27 @@ object InteractionUtils {
|
||||
// ======================== 防抖处理 ========================
|
||||
|
||||
/**
|
||||
* 防抖处理器
|
||||
* 防抖工具类
|
||||
* @param delayMillis 防抖延迟时间(毫秒)
|
||||
*/
|
||||
class Debouncer(
|
||||
private val delayMillis: Long = 300L,
|
||||
private val coroutineScope: CoroutineScope
|
||||
) {
|
||||
private var debounceJob: Job? = null
|
||||
class Debouncer(private val delayMillis: Long) {
|
||||
private var lastActionTime = 0L
|
||||
|
||||
/**
|
||||
* 执行防抖操作
|
||||
* @param block 要执行的代码块
|
||||
* @return Boolean 是否实际执行了操作
|
||||
*/
|
||||
fun <T> debounce(value: T, action: (T) -> Unit) {
|
||||
debounceJob?.cancel()
|
||||
debounceJob = coroutineScope.launch {
|
||||
delay(delayMillis)
|
||||
action(value)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 记住防抖处理器
|
||||
*/
|
||||
@Composable
|
||||
fun rememberDebouncer(
|
||||
delayMillis: Long = 300L,
|
||||
coroutineScope: CoroutineScope = rememberCoroutineScope()
|
||||
): Debouncer {
|
||||
return remember { Debouncer(delayMillis, coroutineScope) }
|
||||
}
|
||||
|
||||
// ======================== 节流处理 ========================
|
||||
|
||||
/**
|
||||
* 节流处理器
|
||||
*/
|
||||
class Throttler(private val timeoutMs: Long = 300L) {
|
||||
private var lastRunTime: Long = 0
|
||||
|
||||
/**
|
||||
* 执行节流操作
|
||||
*/
|
||||
fun throttle(block: () -> Unit) {
|
||||
val now = System.currentTimeMillis()
|
||||
if (now - lastRunTime > timeoutMs) {
|
||||
lastRunTime = now
|
||||
fun debounce(block: () -> Unit): Boolean {
|
||||
val currentTime = System.currentTimeMillis()
|
||||
if (currentTime - lastActionTime >= delayMillis) {
|
||||
lastActionTime = currentTime
|
||||
block()
|
||||
return true
|
||||
}
|
||||
return false
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 记住节流处理器
|
||||
*/
|
||||
@Composable
|
||||
fun rememberThrottler(timeoutMs: Long = 300L): Throttler {
|
||||
return remember { Throttler(timeoutMs) }
|
||||
}
|
||||
|
||||
// ======================== 双击检测 ========================
|
||||
|
||||
/**
|
||||
|
||||
@@ -0,0 +1,100 @@
|
||||
package com.sw.inbound.utils
|
||||
|
||||
import android.content.Context
|
||||
import android.net.Uri
|
||||
import androidx.camera.core.ImageCapture
|
||||
import androidx.camera.core.ImageCaptureException
|
||||
import androidx.camera.view.CameraController
|
||||
import androidx.compose.runtime.Composable
|
||||
import androidx.compose.runtime.remember
|
||||
import androidx.compose.ui.platform.LocalContext
|
||||
import androidx.core.content.ContextCompat
|
||||
import timber.log.Timber
|
||||
import java.io.File
|
||||
|
||||
/**
|
||||
* 拍照工具类
|
||||
* @param context Context 上下文
|
||||
* @param cameraController CameraController 相机控制器
|
||||
* @param onSuccess (Uri) -> Unit 拍照成功回调
|
||||
* @param onError (String) -> Unit 拍照失败回调
|
||||
*/
|
||||
class PhotoCaptureHelper(
|
||||
private val context: Context,
|
||||
private val cameraController: CameraController,
|
||||
private val onSuccess: (Uri) -> Unit = {},
|
||||
private val onError: (String) -> Unit = {}
|
||||
) {
|
||||
|
||||
/**
|
||||
* 拍照方法
|
||||
* @param fileNamePrefix 文件名前缀,默认为"IMG_"
|
||||
* @param fileExtension 文件扩展名,默认为".jpg"
|
||||
*/
|
||||
fun takePhoto(
|
||||
fileNamePrefix: String = "IMG_",
|
||||
fileExtension: String = ".jpg"
|
||||
) {
|
||||
Timber.d("开始拍照采集")
|
||||
|
||||
try {
|
||||
val executor = ContextCompat.getMainExecutor(context)
|
||||
val cacheDir = context.cacheDir
|
||||
val photoFile = File.createTempFile(
|
||||
"${fileNamePrefix}${System.currentTimeMillis()}",
|
||||
fileExtension,
|
||||
cacheDir
|
||||
)
|
||||
|
||||
val outputOptions = ImageCapture.OutputFileOptions.Builder(photoFile).build()
|
||||
|
||||
cameraController.takePicture(
|
||||
outputOptions,
|
||||
executor,
|
||||
object : ImageCapture.OnImageSavedCallback {
|
||||
override fun onImageSaved(outputFileResults: ImageCapture.OutputFileResults) {
|
||||
val photoUri = outputFileResults.savedUri ?: Uri.fromFile(photoFile)
|
||||
Timber.d("照片保存成功: $photoUri")
|
||||
onSuccess(photoUri)
|
||||
}
|
||||
|
||||
override fun onError(exception: ImageCaptureException) {
|
||||
val errorMsg = "拍照失败: ${exception.message}"
|
||||
Timber.e(exception, errorMsg)
|
||||
onError(errorMsg)
|
||||
}
|
||||
}
|
||||
)
|
||||
} catch (e: Exception) {
|
||||
val errorMsg = "创建临时文件失败: ${e.message}"
|
||||
Timber.e(e, errorMsg)
|
||||
onError(errorMsg)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 用于Compose的拍照Hook
|
||||
* @param cameraController CameraController 相机控制器
|
||||
* @param onSuccess (Uri) -> Unit 拍照成功回调
|
||||
* @param onError (String) -> Unit 拍照失败回调
|
||||
* @return Pair<PhotoCaptureHelper, () -> Unit> 返回工具类实例和拍照函数
|
||||
*/
|
||||
@Composable
|
||||
fun rememberPhotoCapture(
|
||||
cameraController: CameraController,
|
||||
onSuccess: (Uri) -> Unit = {},
|
||||
onError: (String) -> Unit = {}
|
||||
): Pair<PhotoCaptureHelper, () -> Unit> {
|
||||
val context = LocalContext.current
|
||||
val photoCaptureHelper = remember {
|
||||
PhotoCaptureHelper(
|
||||
context = context,
|
||||
cameraController = cameraController,
|
||||
onSuccess = onSuccess,
|
||||
onError = onError
|
||||
)
|
||||
}
|
||||
|
||||
return Pair(photoCaptureHelper) { photoCaptureHelper.takePhoto() }
|
||||
}
|
||||
Reference in New Issue
Block a user