优化识别及增加扫码枪逻辑

This commit is contained in:
2026-02-04 18:00:46 +08:00
parent 7596924d75
commit e2c0ed35ec
9 changed files with 152 additions and 35 deletions
@@ -4,7 +4,9 @@ import android.content.Context
import android.graphics.drawable.ColorDrawable
import android.hardware.display.DisplayManager
import android.os.Bundle
import android.util.Log
import android.view.Display
import android.view.KeyEvent
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
@@ -21,6 +23,7 @@ import com.sw.dualscreen.model.response.PostEvent
import com.sw.dualscreen.utils.FileUtil
import com.sw.dualscreen.view.CustomDialog
import com.sw.dualscreen.viewmodel.BaseViewModel
import com.sw.plate.utils.ScanGunKeyEventHelper
import com.sw.plate.utils.ToastUtils
import org.greenrobot.eventbus.EventBus
import org.greenrobot.eventbus.Subscribe
@@ -56,6 +59,7 @@ abstract class BaseActivity<VB : ViewBinding> : AppCompatActivity() {
}
override fun onDestroy() {
keyEventHelper?.onDestroy()
EventBus.getDefault().unregister(this)
super.onDestroy()
}
@@ -142,4 +146,41 @@ abstract class BaseActivity<VB : ViewBinding> : AppCompatActivity() {
fun onPostEvent(event: PostEvent) {
}
/**
* 监听扫描枪扫描事件
*/
fun registerKeyEvent() {
keyEventHelper =
ScanGunKeyEventHelper(context, object : ScanGunKeyEventHelper.OnScanSuccessListener {
override fun onScanSuccess(barcode: String?) {
Timber.d("onScanSuccess barcode = $barcode")
if (barcode == null) return
handleScanKeyInfo(barcode)
}
})
}
protected var keyEventHelper: ScanGunKeyEventHelper? = null
/**
* 处理扫描枪数据
*/
protected open fun handleScanKeyInfo(scanInfo: String) {
var payCode = scanInfo
//if (scanInfo.length > 6) {
// payCode = scanInfo.take(6)
//}
Log.d("TAG", "handleScanKeyInfo: " + payCode)
}
override fun dispatchKeyEvent(event: KeyEvent): Boolean {
if (keyEventHelper != null) {
if (keyEventHelper!!.isScanGunEvent(event)) {
keyEventHelper!!.analysisKeyEvent(event)
return true
}
}
return super.dispatchKeyEvent(event)
}
}
@@ -39,6 +39,7 @@ import com.sw.dualscreen.model.response.ClickBackEvent
import com.sw.dualscreen.model.response.FoodInfo
import com.sw.dualscreen.model.response.FoodOrder
import com.sw.dualscreen.model.response.PaySuccessEvent
import com.sw.dualscreen.model.response.UpdateRefreshEvent
import com.sw.dualscreen.model.response.UserFaceModel
import com.sw.dualscreen.objbox.Food
import com.sw.dualscreen.objbox.FoodModule
@@ -155,6 +156,7 @@ class MainActivity : BaseActivity<ActivityMainBinding>() {
viewModel.getUserFaceCache(pageNo = 1)
setupCamera()
initData()
registerKeyEvent()
}
private fun initData() {
@@ -239,6 +241,15 @@ class MainActivity : BaseActivity<ActivityMainBinding>() {
super.registerDataChange()
SensorScaleUtils.addWeightListener { weight ->
log("registerDataChange weight = $weight")
//runOnUiThread { binding.tvShowWeight.text="${weight*1000}克" }
if (lastWeight - weight > 0.005) {
//及放及取,从秤上拿走超过5克
if (presentation?.mealPickupMode == 0) {
presentation?.updateWeight(weight)
lastWeight = weight
return@addWeightListener
}
}
if (isPageVisible.not() || isStartRecognize.not()) {
if (ActivityManager.currentActivity() is MainActivity) {
isPageVisible = true
@@ -246,7 +257,9 @@ class MainActivity : BaseActivity<ActivityMainBinding>() {
}
return@addWeightListener
}
val isWeightChange = abs(weight - lastWeight) > 0.05
//0.05
// val isWeightChange = abs(weight - lastWeight) > 0.02
val isWeightChange = weight - lastWeight > 0.02
log("recognizeByWeight---00001,weight=$weight,lastWeight=$lastWeight,isWeightChange=$isWeightChange")
recognizeByWeight(weight, isWeightChange)
}
@@ -256,8 +269,8 @@ class MainActivity : BaseActivity<ActivityMainBinding>() {
presentation?.updateWeight(weight)
if (weight <= 0.005) {
log("recognizeByWeight---00002,未超过5克")
////余量取餐,检测到秤上没有东西,重新启动识别菜品 && presentation?.mealPickupMode == 1
log("recognizeByWeight---00002秤重未超过5克")
//检测到秤上没有东西,重新启动识别菜品 && presentation?.mealPickupMode == 1
isRecognitionFood = true
return
}
@@ -270,11 +283,17 @@ class MainActivity : BaseActivity<ActivityMainBinding>() {
debouncer.debounce {
log("recognizeByWeight---00004")
recognizeFood()
if (presentation?.mealPickupMode == 0) {
lastWeight = weight
}
}
} else {
block()
}
lastWeight = weight
if (presentation?.mealPickupMode == 1) {
lastWeight = weight
}
}
private var startTime = 0L
@@ -291,14 +310,7 @@ class MainActivity : BaseActivity<ActivityMainBinding>() {
}.start()
failCount = 0
}, failureCallback = {
runOnUiThread {
if (failCount >= 10) {
ToastUtils.showToast("相机异常,请稍后重试")
shutdownCamera()
setupCamera()
return@runOnUiThread
}
}
//ToastUtils.showToast("拍照异常,请重试")
failCount++
hideWaitingDialog()
@@ -553,7 +565,7 @@ class MainActivity : BaseActivity<ActivityMainBinding>() {
} else {
//副屏未显示重新加载
isRecognitionFood = true
log("onResume-00001")
log("onResume-00001isRefreshPage=$isRefreshPage")
if (presentation == null || !presentation!!.isShowing) {
log("onResume-00002,副屏未显示,加载副屏")
lastWeight = 0.0
@@ -706,6 +718,11 @@ class MainActivity : BaseActivity<ActivityMainBinding>() {
})
}
@Subscribe(threadMode = ThreadMode.MAIN)
fun onUpdateRefreshEvent(event: UpdateRefreshEvent) {
isRefreshPage = true
}
@Subscribe(threadMode = ThreadMode.MAIN)
fun onPaySuccessEvent(event: PaySuccessEvent) {
isRefreshPage = true
@@ -938,7 +955,9 @@ class MainActivity : BaseActivity<ActivityMainBinding>() {
val faceEntity = FaceEntity(
model.userId, null, Base64.decode(model.faceFeatureStr)
).also {
it.userType = "1"
//1-会员、2-临时用户
it.userType = if (model.isMember) "1" else "2"
it.cardNo = model.cardNo
}
faceList.add(faceEntity)
}
@@ -9,6 +9,7 @@ import com.sw.dualscreen.activity.fragment.CollectFragment
import com.sw.dualscreen.databinding.ActivitySettingBinding
import com.sw.dualscreen.model.response.FoodInfo
import com.sw.dualscreen.model.response.ClickBackEvent
import com.sw.dualscreen.model.response.UpdateRefreshEvent
import com.sw.dualscreen.viewmodel.BaseViewModel
import com.sw.dualscreen.viewmodel.UserViewModel
import org.greenrobot.eventbus.EventBus
@@ -47,7 +48,7 @@ class SettingActivity : BaseActivity<ActivitySettingBinding>() {
return@setOnCheckedChangeListener
}
if (checkedId == R.id.rbCollect) {
EventBus.getDefault().post(UpdateRefreshEvent())
showFragment(fragmentList[1])
return@setOnCheckedChangeListener
}
@@ -176,14 +176,15 @@ class CollectFragment : BaseFragment<FragmentCollectBinding>() {
settingActivity?.showWaitingDialog("采集中……")
cameraUtils.takePhoto(cameraCallback) { errMsg ->
settingActivity?.hideWaitingDialog()
if (cameraErrorCount >= 10) {
ToastUtils.showToast("拍照异常,请重新操作")
settingActivity?.log("拍照异常,请重新操作:$errMsg")
cameraErrorCount = 0
return@takePhoto
}
cameraErrorCount++
takePhoto()
// ToastUtils.showToast("拍照异常,请重新操作")
// if (cameraErrorCount >= 10) {
// ToastUtils.showToast("拍照异常,请重新操作")
// settingActivity?.log("拍照异常,请重新操作:$errMsg")
// cameraErrorCount = 0
// return@takePhoto
// }
// cameraErrorCount++
// takePhoto()
}
}
@@ -120,6 +120,7 @@ data class RespCodeMsg(
data class PostEvent(var name: String = "")
data class UpdateRefreshEvent(var name:String = "")
data class PaySuccessEvent(
var name: String = ""
)
@@ -22,7 +22,17 @@ data class UserFaceModel(
val userId: String? = "",
val faceFeatureStr: String? = "",
val faceUpdateTimestamp:Long?=null,
val faceDeleted: Boolean? = false
val faceDeleted: Boolean? = false,
/**
* 会员编号
*/
val cardNo: String,
/**
* 是否会员
*/
val isMember: Boolean
) : Parcelable
@Parcelize
+8 -2
View File
@@ -44,11 +44,17 @@
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="50dp"
android:text="羊肉臊子荞面饸饹"
tools:text="羊肉臊子荞面饸饹"
android:textColor="#FF0A1428"
android:textSize="52sp"
android:textStyle="bold" />
<!-- <TextView-->
<!-- android:id="@+id/tvShowWeight"-->
<!-- android:layout_width="wrap_content"-->
<!-- android:layout_height="80dp"-->
<!-- android:textSize="30sp"-->
<!-- android:gravity="center"-->
<!-- tools:text="100克"/>-->
<FrameLayout
android:id="@+id/foodDisplayLayout"
android:layout_width="match_parent"
@@ -8,6 +8,9 @@ import android.os.Handler;
import android.text.TextUtils;
import android.view.KeyEvent;
import java.util.Arrays;
import java.util.List;
/**
* 扫描枪事件处理
*/
@@ -21,11 +24,17 @@ public class ScanGunKeyEventHelper {
private final Context mContext;
// private String mDeviceName = "TMC HIDKeyBoard";
private String mDeviceName = "Linux 3.4.35 with ak-hsudc Composite Gadget (ACM + HID)";
private String mDeviceName1 = "USBKey Chip USBKey Module";
//private String mDeviceName = "Linux 3.4.35 with ak-hsudc Composite Gadget (ACM + HID)";
//private String mDeviceName1 = "USBKey Chip USBKey Module";
private String[] deviceNameArray = new String[]{
"CROWN CROWN Barcode KeyBorad FS",
"Linux 3.4.35 with ak-hsudc Composite Gadget (ACM + HID)",
"USBKey Chip USBKey Module"
};
private long lastTime = 0L;
public ScanGunKeyEventHelper(Context context, OnScanSuccessListener onScanSuccessListener) {
mContext = context;
mOnScanSuccessListener = onScanSuccessListener;
mStringBufferResult = new StringBuffer();
@@ -38,6 +47,14 @@ public class ScanGunKeyEventHelper {
*/
private void performScanSuccess() {
String barcode = mStringBufferResult.toString();
L.d("performScanSuccess barcode = " + barcode);
long currentTime = System.currentTimeMillis();
if (currentTime - lastTime < 5 * 1000) {
L.d("performScanSuccess 操作太频繁");
mStringBufferResult.setLength(0);
return;
}
lastTime = currentTime;
if (mOnScanSuccessListener != null && !TextUtils.isEmpty(barcode))
mOnScanSuccessListener.onScanSuccess(barcode);
mStringBufferResult.setLength(0);
@@ -161,6 +178,8 @@ public class ScanGunKeyEventHelper {
L.e("event===" + deviceName +
"===Char===" + event.getCharacters() +
"===Action===" + event.getAction());
return deviceName.equals(mDeviceName) || deviceName.equals(mDeviceName1);
//return deviceName.equals(mDeviceName) || deviceName.equals(mDeviceName1);
List<String> devices = Arrays.asList(deviceNameArray);
return devices.contains(deviceName);
}
}
@@ -45,10 +45,15 @@ public class FaceEntity implements Parcelable {
@ColumnInfo(name = "register_time")
private long registerTime;
/**
* 用户类型:1-普通会员、2-临时用户、3-内部员工、或者其它待定类型
* 用户类型:1-普通会员、2-临时用户、或者其它待定类型
*/
@ColumnInfo(name = "user_type")
private String userType;
/**
* 会员编号
*/
@ColumnInfo(name = "cardNo")
private String cardNo;
@Ignore
private int trackId;//人脸追踪ID
@@ -66,6 +71,8 @@ public class FaceEntity implements Parcelable {
this.imagePath = faceEntity.imagePath;
this.featureData = faceEntity.featureData;
this.registerTime = faceEntity.registerTime;
this.userType = faceEntity.getUserType();
this.cardNo = faceEntity.getCardNo();
}
@@ -75,6 +82,8 @@ public class FaceEntity implements Parcelable {
userName = in.readString();
imagePath = in.readString();
featureData = in.createByteArray();
userType = in.readString();
cardNo = in.readString();
}
public static final Creator<FaceEntity> CREATOR = new Creator<FaceEntity>() {
@@ -145,6 +154,16 @@ public class FaceEntity implements Parcelable {
this.userType = userType;
}
public String getCardNo() {
return cardNo;
}
public void setCardNo(String cardNo) {
this.cardNo = cardNo;
}
@Override
public int describeContents() {
return 0;
@@ -158,10 +177,9 @@ public class FaceEntity implements Parcelable {
dest.writeString(imagePath);
dest.writeByteArray(featureData);
dest.writeString(userType);
dest.writeString(cardNo);
}
@Override
public boolean equals(Object o) {
if (this == o) {
@@ -176,12 +194,13 @@ public class FaceEntity implements Parcelable {
TextUtils.equals(this.userName, that.userName) &&
TextUtils.equals(this.imagePath, that.imagePath) &&
Arrays.equals(featureData, that.featureData) &&
TextUtils.equals(this.userType, that.userType);
TextUtils.equals(this.userType, that.userType) &&
TextUtils.equals(this.cardNo, that.cardNo);
}
@Override
public int hashCode() {
int result = Objects.hash(faceId, registerTime, userName, imagePath, userType);
int result = Objects.hash(faceId, registerTime, userName, imagePath, userType, cardNo);
result = 31 * result + Arrays.hashCode(featureData);
return result;
}