增量人脸查询优化

This commit is contained in:
2025-12-31 11:54:17 +08:00
parent 0d2a38391c
commit fc04db9268
5 changed files with 57 additions and 47 deletions
@@ -41,7 +41,6 @@ import com.sw.dualscreen.objbox.FoodModule
import com.sw.dualscreen.objbox.FoodModule.IdNameScore import com.sw.dualscreen.objbox.FoodModule.IdNameScore
import com.sw.dualscreen.presentation.MainScreenPresentation import com.sw.dualscreen.presentation.MainScreenPresentation
import com.sw.dualscreen.sdk.SensorScaleUtils import com.sw.dualscreen.sdk.SensorScaleUtils
import com.sw.dualscreen.socket.LanServer
import com.sw.dualscreen.socket.TcpClient import com.sw.dualscreen.socket.TcpClient
import com.sw.dualscreen.utils.BitmapSaver import com.sw.dualscreen.utils.BitmapSaver
import com.sw.dualscreen.utils.Debouncer import com.sw.dualscreen.utils.Debouncer
@@ -53,8 +52,6 @@ import com.sw.dualscreen.utils.SpTool
import com.sw.dualscreen.view.CustomBottomSheetDialog import com.sw.dualscreen.view.CustomBottomSheetDialog
import com.sw.dualscreen.viewmodel.BaseViewModel import com.sw.dualscreen.viewmodel.BaseViewModel
import com.sw.dualscreen.viewmodel.UserViewModel import com.sw.dualscreen.viewmodel.UserViewModel
import com.sw.face.collect.view.LanServerListenerImpl
import com.sw.face.collect.view.TcpClientListenerImpl
import com.sw.plate.utils.Base64 import com.sw.plate.utils.Base64
import com.sw.plate.utils.LightManager import com.sw.plate.utils.LightManager
import com.sw.plate.utils.ToastUtils import com.sw.plate.utils.ToastUtils
@@ -73,7 +70,6 @@ import java.time.format.DateTimeFormatter
import java.util.Locale import java.util.Locale
import java.util.concurrent.Executors import java.util.concurrent.Executors
import kotlin.math.roundToInt import kotlin.math.roundToInt
import kotlin.text.compareTo
/** /**
* 服务员显示界面 * 服务员显示界面
@@ -278,16 +274,17 @@ class MainActivity : BaseActivity<ActivityMainBinding>() {
binding.tvFoodName.text = foodInfo.foodName binding.tvFoodName.text = foodInfo.foodName
binding.previewView.gone() binding.previewView.gone()
binding.ivImg.visible() binding.ivImg.visible()
if (foodInfo.foodImg.isNullOrBlank()) { // if (foodInfo.foodImg.isNullOrBlank()) {
takePhoto(successCallback = { imgUri -> // takePhoto(successCallback = { imgUri ->
binding.ivImg.load(imgUri) // binding.ivImg.load(imgUri)
presentation?.updateFood(foodInfo.copy(foodImg = imgUri.toString())) // presentation?.updateFood(foodInfo.copy(foodImg = imgUri.toString()))
}, failureCallback = { // }, failureCallback = {
//
}) // })
} else { // } else {
// binding.ivImg.load(foodInfo.foodImg)
// }
binding.ivImg.load(foodInfo.foodImg) binding.ivImg.load(foodInfo.foodImg)
}
//pauseAnalysis() //pauseAnalysis()
} }
@@ -352,7 +349,8 @@ class MainActivity : BaseActivity<ActivityMainBinding>() {
fun recognizeFood() { fun recognizeFood() {
startTime = System.currentTimeMillis() startTime = System.currentTimeMillis()
LightManager.openRedLight() // LightManager.openRedLight()
LightManager.closeRedLight()
LightManager.openGreenLight() LightManager.openGreenLight()
showWaitingDialog("识别中,请稍后……") showWaitingDialog("识别中,请稍后……")
takePhoto(successCallback = { photoUri -> takePhoto(successCallback = { photoUri ->
@@ -414,13 +412,15 @@ class MainActivity : BaseActivity<ActivityMainBinding>() {
} }
}, failureCallback = { }, failureCallback = {
runOnUiThread {
hideWaitingDialog() hideWaitingDialog()
ToastUtils.showToast("拍照异常,请手动放置后重新识别") // ToastUtils.showToast("拍照异常,请手动放置后重新识别")
}
// binding.root.postDelayed({ shutdownCamera()
// recognizeFood() setupCamera()
// }, 500)
binding.root.postDelayed({
recognizeFood()
}, 500)
}) })
} }
@@ -604,14 +604,11 @@ class MainActivity : BaseActivity<ActivityMainBinding>() {
executor, executor,
object : ImageCapture.OnImageSavedCallback { object : ImageCapture.OnImageSavedCallback {
override fun onImageSaved(outputFileResults: ImageCapture.OutputFileResults) { override fun onImageSaved(outputFileResults: ImageCapture.OutputFileResults) {
runOnUiThread {
val savedUri = outputFileResults.savedUri val savedUri = outputFileResults.savedUri
Timber.d("takePhoto savedUri = $savedUri") Timber.d("takePhoto savedUri = $savedUri")
// ToastUtils.showToast("照片保存成功: $savedUri")
if (savedUri != null) { if (savedUri != null) {
successCallback(savedUri) successCallback(savedUri)
} }
}
// 恢复图像分析 // 恢复图像分析
isAnalyzing = true isAnalyzing = true
} }
@@ -619,9 +616,7 @@ class MainActivity : BaseActivity<ActivityMainBinding>() {
override fun onError(exception: ImageCaptureException) { override fun onError(exception: ImageCaptureException) {
Timber.e("拍照失败: ${exception.message}") Timber.e("拍照失败: ${exception.message}")
failureCallback() failureCallback()
//runOnUiThread { ToastUtils.showToast("拍照失败: ${exception.message}")
// ToastUtils.showToast("拍照失败: ${exception.message}")
//}
// 恢复图像分析 // 恢复图像分析
isAnalyzing = true isAnalyzing = true
} }
@@ -952,14 +947,12 @@ class MainActivity : BaseActivity<ActivityMainBinding>() {
timestamp = timestamp, timestamp = timestamp,
onAllQueryFinished = { onAllQueryFinished = {
taskPageNo = 1 taskPageNo = 1
SpTool.setLastFaceTimestamp(System.currentTimeMillis())
}, },
onPageQueryFinished = { list -> onPageQueryFinished = { list ->
runOnUiThread { runOnUiThread {
if (list.isEmpty()) { if (list.isEmpty()) {
return@runOnUiThread return@runOnUiThread
} }
SpTool.setLastFaceTimestamp(System.currentTimeMillis())
updateFaceData(list) updateFaceData(list)
} }
} }
@@ -21,7 +21,7 @@ data class UserFaceModel(
// @SerializedName("userId") // @SerializedName("userId")
val userId: String? = "", val userId: String? = "",
val faceFeatureStr: String? = "", val faceFeatureStr: String? = "",
val faceUpdateTimestamp:Long?=null,
val faceDeleted: Boolean? = false val faceDeleted: Boolean? = false
) : Parcelable ) : Parcelable
@@ -1,7 +1,6 @@
package com.sw.face.collect.view package com.sw.dualscreen.socket
import android.util.Log import android.util.Log
import com.sw.dualscreen.socket.LanCommunicationManager
import org.json.JSONObject import org.json.JSONObject
open class LanServerListenerImpl: LanCommunicationManager.Listener { open class LanServerListenerImpl: LanCommunicationManager.Listener {
@@ -1,7 +1,6 @@
package com.sw.face.collect.view package com.sw.dualscreen.socket
import android.util.Log import android.util.Log
import com.sw.dualscreen.socket.TcpClient
import org.json.JSONObject import org.json.JSONObject
import java.lang.Exception import java.lang.Exception
@@ -64,6 +64,8 @@ class UserViewModel : BaseViewModel() {
private val _identifiedFoodInfoList2 = MutableStateFlow<List<FoodInfo>>(emptyList()) private val _identifiedFoodInfoList2 = MutableStateFlow<List<FoodInfo>>(emptyList())
val identifiedFoodInfoList2: StateFlow<List<FoodInfo>> = _identifiedFoodInfoList2 val identifiedFoodInfoList2: StateFlow<List<FoodInfo>> = _identifiedFoodInfoList2
private var lastFaceTimestamp = 0L
/** /**
* 获取token * 获取token
*/ */
@@ -90,14 +92,15 @@ class UserViewModel : BaseViewModel() {
Timber.tag(TAG).d("getUserFaceCache index = $currentPageNo") Timber.tag(TAG).d("getUserFaceCache index = $currentPageNo")
launch { launch {
_loadFaceResult.value = false _loadFaceResult.value = false
//获取全量数据时,时间戳改为0
SpTool.setLastFaceTimestamp(0)
val response = repository.getUserFaceCache(currentPageNo) val response = repository.getUserFaceCache(currentPageNo)
if (parseResponse(response)) { if (parseResponse(response)) {
// 获取成功一次后缓存状态 // 获取成功一次后缓存状态
SPUtil.getInstance().put(GlobalKey.KEY_FIRST_RUN, true) SPUtil.getInstance().put(GlobalKey.KEY_FIRST_RUN, true)
withContext(Dispatchers.Default) { withContext(Dispatchers.Default) {
val list: List<UserFaceModel> = response.data ?: emptyList() val list: List<UserFaceModel> = response.data ?: emptyList()
if (list.isEmpty()) { if (pageNo == 1 && list.isEmpty()) {
SpTool.setLastFaceTimestamp(System.currentTimeMillis())
ToastUtils.showToast("查询人脸数据为空") ToastUtils.showToast("查询人脸数据为空")
return@withContext return@withContext
} }
@@ -108,12 +111,18 @@ class UserViewModel : BaseViewModel() {
} }
faceApi.updateFaceData(currentPageNo, faceEntity) faceApi.updateFaceData(currentPageNo, faceEntity)
if (list.size >= pageSize) { if (list.size >= pageSize) {
lastFaceTimestamp = list.last().faceUpdateTimestamp ?: 0L
currentPageNo++ currentPageNo++
getUserFaceCache(currentPageNo) getUserFaceCache(currentPageNo)
} else { return@withContext
SpTool.setLastFaceTimestamp(System.currentTimeMillis())
_loadFaceResult.value = true
} }
//查询完成所有数据,保存时间戳
if (list.isNotEmpty()) {
//非空最后一条数据的是时间戳,空使用上次list最后一条时间戳
lastFaceTimestamp = list.last().faceUpdateTimestamp ?: 0L
}
SpTool.setLastFaceTimestamp(lastFaceTimestamp)
_loadFaceResult.value = true
} }
// val nextPageIndex = response.result?.nextPageIndex ?: -1 // val nextPageIndex = response.result?.nextPageIndex ?: -1
@@ -170,8 +179,12 @@ class UserViewModel : BaseViewModel() {
if (parseResponse(response)) { if (parseResponse(response)) {
withContext(Dispatchers.Default) { withContext(Dispatchers.Default) {
val list: List<UserFaceModel> = response.data ?: emptyList() val list: List<UserFaceModel> = response.data ?: emptyList()
if (pageNo == 1 && list.isEmpty()) {
return@withContext
}
onPageQueryFinished(list) onPageQueryFinished(list)
if (list.size >= pageSize) { if (list.size >= pageSize) {
lastFaceTimestamp = list.last().faceUpdateTimestamp ?: 0L
getFaceIncrementList( getFaceIncrementList(
pageNo = pageNo + 1, pageNo = pageNo + 1,
pageSize = pageSize, pageSize = pageSize,
@@ -179,9 +192,15 @@ class UserViewModel : BaseViewModel() {
onAllQueryFinished = onAllQueryFinished, onAllQueryFinished = onAllQueryFinished,
onPageQueryFinished = onPageQueryFinished onPageQueryFinished = onPageQueryFinished
) )
} else { return@withContext
onAllQueryFinished()
} }
//查询完成所有数据,保存时间戳
if (list.isNotEmpty()) {
//非空实现最后一条数据的是时间戳,空使用上次list最后一条时间戳
lastFaceTimestamp = list.last().faceUpdateTimestamp ?: 0L
}
SpTool.setLastFaceTimestamp(lastFaceTimestamp)
onAllQueryFinished()
} }
} }
} }