refactor(face): 优化人脸识别状态管理与菜品选择逻辑

- 移除 MainFoodListAdapter 中未使用的适配器和视图参数
- 提取菜品重选逻辑到独立的 resetSelectedFood 方法中
- 删除临时的独立支付模式测试代码
- 在余量计量场景中添加人脸状态检查避免重复数据读取
- 修复倒计时任务状态判断逻辑并清理任务引用
- 添加空值检查防止 CompareResult 为空时的异常
- 实现 resetFaceState 方法清空人脸识别状态
- 在订单提交前重置人脸状态确保下次识别正常进行
This commit is contained in:
2026-04-09 16:02:24 +08:00
parent 0498e124b3
commit e5b682f021
3 changed files with 59 additions and 28 deletions
@@ -114,7 +114,7 @@ class MainActivity : BaseActivity<ActivityMainBinding>() {
private val handler by lazy { Handler(Looper.getMainLooper()) } private val handler by lazy { Handler(Looper.getMainLooper()) }
private val adapter by lazy { private val adapter by lazy {
MainFoodListAdapter(mutableListOf()).apply { MainFoodListAdapter(mutableListOf()).apply {
setOnItemClickListener { adapter, view, position -> setOnItemClickListener { _, _, position ->
if (items[position].isChecked) { if (items[position].isChecked) {
return@setOnItemClickListener return@setOnItemClickListener
} }
@@ -126,12 +126,19 @@ class MainActivity : BaseActivity<ActivityMainBinding>() {
item.photoUri = null item.photoUri = null
checkedItem = item checkedItem = item
notifyDataSetChanged() notifyDataSetChanged()
updateCurrentFood(item) resetSelectedFood(item)
}
}
}
fun resetSelectedFood(foodInfo: FoodInfo) {
recognizeViewModel.resetFaceState()
updateCurrentFood(foodInfo)
if (settlementMode == 0) { if (settlementMode == 0) {
//联合支付,切换菜品重新请求接口 //联合支付,切换菜品重新请求接口
presentation?.let { presentation?.let {
it.pauseCamera() it.pauseCamera()
it.step2FaceRecognizing(item, true) it.step2FaceRecognizing(foodInfo, true)
} }
// presentation?.step3ShowRecognizeResult(presentation!!.currentUserId?:"") // presentation?.step3ShowRecognizeResult(presentation!!.currentUserId?:"")
} else { } else {
@@ -144,8 +151,7 @@ class MainActivity : BaseActivity<ActivityMainBinding>() {
} }
} }
} }
}
}
var checkedItem: FoodInfo? = null var checkedItem: FoodInfo? = null
private var imageAnalysis: ImageAnalysis? = null private var imageAnalysis: ImageAnalysis? = null
private var cameraProviderFuture: ListenableFuture<ProcessCameraProvider>? = null private var cameraProviderFuture: ListenableFuture<ProcessCameraProvider>? = null
@@ -201,9 +207,6 @@ class MainActivity : BaseActivity<ActivityMainBinding>() {
} }
//结算模式:1-独立支付,2-联合结算 //结算模式:1-独立支付,2-联合结算
settlementMode = if (deviceConfig.payType == 2) 0 else 1 settlementMode = if (deviceConfig.payType == 2) 0 else 1
// TODO: 临时修改为独立支付模式用于测试--------------------------
settlementMode = 1
// TODO: 临时修改为独立支付模式用于测试--------------------------
SPUtil.getInstance().put(GlobalKey.KEY_SETTLEMENT_MODE, settlementMode) SPUtil.getInstance().put(GlobalKey.KEY_SETTLEMENT_MODE, settlementMode)
GlobalData.appId = deviceConfig.arcsoftAppId ?: "" GlobalData.appId = deviceConfig.arcsoftAppId ?: ""
@@ -257,11 +260,11 @@ class MainActivity : BaseActivity<ActivityMainBinding>() {
bottomSheetDialog = CustomBottomSheetDialog.newInstance(viewModel) { bottomSheetDialog = CustomBottomSheetDialog.newInstance(viewModel) {
checkedItem = it checkedItem = it
it.photoUri = null it.photoUri = null
updateCurrentFood(it)
adapter.items.forEachIndexed { index, info -> adapter.items.forEachIndexed { index, info ->
adapter.items[index].isChecked = false adapter.items[index].isChecked = false
} }
adapter.notifyDataSetChanged() adapter.notifyDataSetChanged()
resetSelectedFood(it)
} }
bottomSheetDialog!!.show(supportFragmentManager, "CustomBottomSheetDialog") bottomSheetDialog!!.show(supportFragmentManager, "CustomBottomSheetDialog")
} }
@@ -345,6 +348,10 @@ class MainActivity : BaseActivity<ActivityMainBinding>() {
log("registerDataChange weight 联合支付-余量计量") log("registerDataChange weight 联合支付-余量计量")
if (weight <= WEIGHT_RESET_RECOGNIZE) { if (weight <= WEIGHT_RESET_RECOGNIZE) {
log("registerDataChange weight 联合支付-余量计量,重量小于${WEIGHT_RESET_RECOGNIZE}g,step1FoodRecognizing") log("registerDataChange weight 联合支付-余量计量,重量小于${WEIGHT_RESET_RECOGNIZE}g,step1FoodRecognizing")
if (presentation?.currentUserId.isNullOrBlank().not()) {
//联合支付+余量计量,已识别人脸的状态下,从秤上拿餐品后,不再读取数据,等待人脸离开提交订单
return
}
//秤上重量过小,显示识别中页面 //秤上重量过小,显示识别中页面
presentation?.step1FoodRecognizing() presentation?.step1FoodRecognizing()
return return
@@ -419,7 +426,12 @@ class MainActivity : BaseActivity<ActivityMainBinding>() {
super.registerDataChange() super.registerDataChange()
SensorScaleUtils.addWeightListener { value -> SensorScaleUtils.addWeightListener { value ->
runOnUiThread { runOnUiThread {
if (foodRecognizeState.not()) return@runOnUiThread if (foodRecognizeState.not()) {
if (value <= WEIGHT_RESET_RECOGNIZE) {
presentation?.step1FoodRecognizing()
}
return@runOnUiThread
}
readWeight(value) readWeight(value)
} }
} }
@@ -165,7 +165,7 @@ class MainScreenPresentation(
return@runOnUiThread return@runOnUiThread
} }
//余量计量 //余量计量
if (countDownResetJob == null) { if (countDownResetJob == null || countDownResetJob?.isActive == false) {
countDownResetJob = countDownByFlow( countDownResetJob = countDownByFlow(
total = 30, total = 30,
scope = activity.lifecycleScope, scope = activity.lifecycleScope,
@@ -174,11 +174,13 @@ class MainScreenPresentation(
Timber.tag(TAG).e("余量计量模型秤重量已清空,等待${seconds}秒后继续重置识别状态") Timber.tag(TAG).e("余量计量模型秤重量已清空,等待${seconds}秒后继续重置识别状态")
if (lastWeight > MainActivity.WEIGHT_RESET_RECOGNIZE) { if (lastWeight > MainActivity.WEIGHT_RESET_RECOGNIZE) {
countDownResetJob?.cancel() countDownResetJob?.cancel()
countDownResetJob = null
} }
}, },
onFinish = { onFinish = {
step1FoodRecognizing() step1FoodRecognizing()
countDownResetJob?.cancel() countDownResetJob?.cancel()
countDownResetJob = null
} }
) )
} }
@@ -523,6 +525,7 @@ class MainScreenPresentation(
*/ */
fun step1FoodRecognizing() { fun step1FoodRecognizing() {
if (currentStep == 1 && currentFood == null) { if (currentStep == 1 && currentFood == null) {
activity.clearRecognizeFood()
return return
} }
Timber.tag(TAG).d("main,step1,耗时:${System.currentTimeMillis() - startTime}") Timber.tag(TAG).d("main,step1,耗时:${System.currentTimeMillis() - startTime}")
@@ -1011,7 +1014,8 @@ class MainScreenPresentation(
recognizeViewModel.recognizeUserId.observe( recognizeViewModel.recognizeUserId.observe(
activity, activity,
Observer { compareResult: CompareResult -> Observer { result: CompareResult? ->
if (result == null) return@Observer
if (currentStep != 2 || System.currentTimeMillis() - recognizeTime <= 2000) { if (currentStep != 2 || System.currentTimeMillis() - recognizeTime <= 2000) {
//忽略非识别中及5秒内的再次识别 //忽略非识别中及5秒内的再次识别
return@Observer return@Observer
@@ -1024,11 +1028,11 @@ class MainScreenPresentation(
activity.showWaitingDialog("加载中,请稍后……") activity.showWaitingDialog("加载中,请稍后……")
} }
Timber.tag(TAG) Timber.tag(TAG)
.i("recognizeUserId observe compareResult = ${compareResult.trackId}, userId = ${compareResult.faceEntity.userName}, step = $currentStep") .i("recognizeUserId observe compareResult = ${result.trackId}, userId = ${result.faceEntity.userName}, step = $currentStep")
recognitionTime = System.currentTimeMillis() recognitionTime = System.currentTimeMillis()
recognitionWeight = lastWeight recognitionWeight = lastWeight
lastFaceTrackId = compareResult.trackId lastFaceTrackId = result.trackId
val faceEntity = compareResult.faceEntity val faceEntity = result.faceEntity
val userId = faceEntity.userName val userId = faceEntity.userName
currentUserId = userId currentUserId = userId
isMember = faceEntity.userType == "1" isMember = faceEntity.userType == "1"
@@ -1323,6 +1327,8 @@ class MainScreenPresentation(
if (userNutrition == null || currentFood == null || currentUserId == null) { if (userNutrition == null || currentFood == null || currentUserId == null) {
return return
} }
//重置人脸
recognizeViewModel.resetFaceState()
Timber.tag(TAG).d("drawPreviewInfo,开始提交订单") Timber.tag(TAG).d("drawPreviewInfo,开始提交订单")
createOrder(notEnoughOneBlock = { createOrder(notEnoughOneBlock = {
Timber.tag(TAG).d("drawPreviewInfo,notEnoughOneBlock") Timber.tag(TAG).d("drawPreviewInfo,notEnoughOneBlock")
@@ -397,6 +397,19 @@ public class RecognizeViewModel extends ViewModel implements RecognizeCallback {
} }
} }
/**
* 重置人脸识别状态:清空上次识别结果及 FaceHelper 内部的 recognizeInfoMap
* 使下一帧进入时能重新触发识别流程。
*/
public void resetFaceState() {
// 清空粘性 LiveData,防止旧结果被重新投递给 observer
recognizeUserId.postValue(null);
// 清空 FaceHelper 内部所有人脸状态,让 trackId 对应的状态回到 TO_RETRY
if (faceHelper != null) {
faceHelper.clearFacePreviewInfoList();
}
}
/** /**
* 释放操作 * 释放操作
*/ */