diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml index c9400bd..7ab7d9f 100644 --- a/app/src/main/AndroidManifest.xml +++ b/app/src/main/AndroidManifest.xml @@ -26,29 +26,40 @@ android:supportsRtl="true" android:theme="@style/Theme.SmartPlateCabinet" tools:targetApi="31"> + + + + + + + + android:exported="true" /> + + + + + + + + + - - - - - - - diff --git a/app/src/main/java/com/sw/platecabinet/GlobalData.kt b/app/src/main/java/com/sw/platecabinet/GlobalData.kt index 470e3e9..90033d6 100644 --- a/app/src/main/java/com/sw/platecabinet/GlobalData.kt +++ b/app/src/main/java/com/sw/platecabinet/GlobalData.kt @@ -26,6 +26,9 @@ object GlobalData { */ var arrayMode: Int = 0 + var appId = "Hkz1rBk6PZXbS8KwKr67K2eZtsz8bRoMHLg64bUdgCZj" + var sdkKey = "AabXs3sHM8UhhE7oCGf4LVMLrdkGb1nJNksbjjTdVt7k" + var activeKey = "085F-118G-Q391-53YL" } /** diff --git a/app/src/main/java/com/sw/platecabinet/activity/BaseActivity.kt b/app/src/main/java/com/sw/platecabinet/activity/BaseActivity.kt index 5026c93..755b94f 100644 --- a/app/src/main/java/com/sw/platecabinet/activity/BaseActivity.kt +++ b/app/src/main/java/com/sw/platecabinet/activity/BaseActivity.kt @@ -318,7 +318,7 @@ abstract class BaseActivity : AppCompatActivity() { } if (equipmentUserInfo.equipmentBoxCode?.isNotEmpty() == true) { SerialApi.openPlate( - equipmentUserInfo.equipmentBoxCode.toInt(), + equipmentUserInfo.equipmentBoxCode!!.toInt(), object : SerialPortManager.SendCallback { override fun onSuccess() { MainActivity.start(context, pageType = PageType.PLATE_TIP) @@ -343,6 +343,7 @@ abstract class BaseActivity : AppCompatActivity() { } override fun onDestroy() { + SerialApi.close() timeJob?.cancel() keyEventHelper?.onDestroy() super.onDestroy() diff --git a/app/src/main/java/com/sw/platecabinet/activity/InitActivity.kt b/app/src/main/java/com/sw/platecabinet/activity/InitActivity.kt new file mode 100644 index 0000000..d49a9fb --- /dev/null +++ b/app/src/main/java/com/sw/platecabinet/activity/InitActivity.kt @@ -0,0 +1,28 @@ +package com.sw.platecabinet.activity + +import android.content.Intent +import com.sw.platecabinet.databinding.ActivityInitBinding +import com.sw.platecabinet.databinding.ItemTitleTimeBinding + +class InitActivity : BaseActivity() { + override fun inflateViewBinding(): ActivityInitBinding { + return ActivityInitBinding.inflate(layoutInflater) + } + + override fun inflateTitleBinding(): ItemTitleTimeBinding? { + return binding.includeHeader + } + + override fun initialize() { + binding.main.setOnClickListener { + val intent = Intent(this, LoginByFaceActivity::class.java) + startActivity(intent) + } + } + + + override fun onLeftDoubleClick() { + finish() + } + +} \ No newline at end of file diff --git a/app/src/main/java/com/sw/platecabinet/activity/LoginByFaceActivity.kt b/app/src/main/java/com/sw/platecabinet/activity/LoginByFaceActivity.kt index 5912f31..4db2c53 100644 --- a/app/src/main/java/com/sw/platecabinet/activity/LoginByFaceActivity.kt +++ b/app/src/main/java/com/sw/platecabinet/activity/LoginByFaceActivity.kt @@ -5,6 +5,7 @@ import android.content.Intent import android.graphics.Point import android.hardware.Camera import android.os.Build +import android.os.CountDownTimer import android.util.DisplayMetrics import android.view.View import android.view.ViewGroup @@ -29,8 +30,8 @@ import com.sw.plate.utils.arcface.viewmodel.RecognizeViewModel import com.sw.platecabinet.R import com.sw.platecabinet.databinding.ActivityLoginFaceBinding import com.sw.platecabinet.databinding.ItemTitleTimeBinding +import com.sw.platecabinet.model.response.EquipmentUserInfo import com.sw.platecabinet.utils.PermissionHelper -import com.sw.platecabinet.utils.ThreadUtils import timber.log.Timber /** @@ -39,6 +40,7 @@ import timber.log.Timber class LoginByFaceActivity : BaseActivity(), ViewTreeObserver.OnGlobalLayoutListener { private val recognizeViewModel by viewModels() + private var countDownTimer: CountDownTimer? = null private val CAMERA_PERMISSION_REQUEST_CODE = 100 private val REQUIRED_PERMISSIONS: Array = arrayOf( @@ -55,11 +57,19 @@ class LoginByFaceActivity : BaseActivity(), return binding.includeHeader } - override fun initialize() { - ThreadUtils.launch { - viewModel.activeEngine() - } + companion object { + private var instance: LoginByFaceActivity? = null + fun finishActivity() { + instance?.finish() + } + } + + override fun initialize() { + instance = this + viewModel.activeEngine() + + initCountTime() initArcViewModel() initArcView() openRectInfoDraw = true @@ -157,6 +167,7 @@ class LoginByFaceActivity : BaseActivity(), } override fun onDestroy() { + instance = null if (rgbCameraHelper != null) { rgbCameraHelper!!.release() rgbCameraHelper = null @@ -356,6 +367,10 @@ class LoginByFaceActivity : BaseActivity(), super.onResume() resumeCamera() viewModel.resetUserInfo() + countDownTimer?.let { + it.cancel() + it.start() + } } protected override fun onPause() { @@ -369,4 +384,21 @@ class LoginByFaceActivity : BaseActivity(), recognizeViewModel.onPreviewFrame(ByteArray(1382400), true) } + override fun handleLoginSuccess(equipmentUserInfo: EquipmentUserInfo, isAdmin: Boolean) { + super.handleLoginSuccess(equipmentUserInfo, isAdmin) + finish() + } + + fun initCountTime() { + val totalTimeInMillis = 30L * 1000 + countDownTimer = object : CountDownTimer(totalTimeInMillis, 1000) { + override fun onTick(millisUntilFinished: Long) { + binding.tvToInit.text = "${(millisUntilFinished / 1000).toInt() + 1}" + } + + override fun onFinish() { + finish() + } + }.start() + } } \ No newline at end of file diff --git a/app/src/main/java/com/sw/platecabinet/activity/LoginByPwdActivity.kt b/app/src/main/java/com/sw/platecabinet/activity/LoginByPwdActivity.kt index dd35e3c..137f498 100644 --- a/app/src/main/java/com/sw/platecabinet/activity/LoginByPwdActivity.kt +++ b/app/src/main/java/com/sw/platecabinet/activity/LoginByPwdActivity.kt @@ -41,6 +41,7 @@ class LoginByPwdActivity : BaseActivity() { override fun handleLoginSuccess(equipmentUserInfo: EquipmentUserInfo, isAdmin: Boolean) { super.handleLoginSuccess(equipmentUserInfo, isAdmin) + LoginByFaceActivity.finishActivity() finish() } } \ No newline at end of file diff --git a/app/src/main/java/com/sw/platecabinet/fragment/BindPlateFragment.kt b/app/src/main/java/com/sw/platecabinet/fragment/BindPlateFragment.kt index 2130a82..b47fd62 100644 --- a/app/src/main/java/com/sw/platecabinet/fragment/BindPlateFragment.kt +++ b/app/src/main/java/com/sw/platecabinet/fragment/BindPlateFragment.kt @@ -1,16 +1,17 @@ package com.sw.platecabinet.fragment import android.os.Bundle -import android.os.Handler -import android.os.Looper import android.text.Editable import android.text.TextUtils import android.text.TextWatcher +import android.view.inputmethod.EditorInfo import androidx.lifecycle.lifecycleScope import androidx.recyclerview.widget.GridLayoutManager import androidx.recyclerview.widget.LinearLayoutManager import androidx.recyclerview.widget.RecyclerView import com.sw.plate.utils.ToastUtils +import com.sw.plate.utils.comn.SerialApi +import com.sw.plate.utils.comn.SerialPortManager import com.sw.platecabinet.R import com.sw.platecabinet.activity.MainActivity import com.sw.platecabinet.activity.PageType @@ -23,6 +24,7 @@ import com.sw.platecabinet.ext.maskName import com.sw.platecabinet.ext.maskPhone import com.sw.platecabinet.model.response.EquipmentUserInfo import com.sw.platecabinet.model.response.SearchResult +import com.sw.platecabinet.utils.Debouncer import com.sw.platecabinet.utils.KeyboardUtils import kotlinx.coroutines.flow.drop import kotlinx.coroutines.launch @@ -39,6 +41,7 @@ class BindPlateFragment : BaseFragment( private var info: EquipmentUserInfo? = null private var checkedItem: SearchResult.Member? = null private var lastText = "" + private val debouncer = Debouncer(2000) companion object { @JvmStatic @@ -94,21 +97,25 @@ class BindPlateFragment : BaseFragment( } }) (activity as MainActivity).registerKeyEventInfo { - binding.etCode.text = Editable.Factory.getInstance().newEditable(it) + if (binding.etUserInfo.isFocused) return@registerKeyEventInfo + binding.etCode.text.clear() + binding.etCode.postDelayed({ + binding.etCode.text.clear() + binding.etCode.text = Editable.Factory.getInstance().newEditable(it) + binding.etUserInfo.requestFocus() + }, 50) } } private fun initListener() { - binding.etUserInfo.addTextChangedListener(object : TextWatcher { - private val handler = Handler(Looper.getMainLooper()) - private val debounceDelay = 500L // 延迟 500 毫秒 - + binding.etCode.addTextChangedListener(object : TextWatcher { override fun beforeTextChanged( s: CharSequence?, start: Int, count: Int, after: Int ) { + Timber.d("beforeTextChanged s = ${s.toString()}, start = $start, count = $count, after = $after") } override fun onTextChanged( @@ -117,20 +124,32 @@ class BindPlateFragment : BaseFragment( before: Int, count: Int ) { + Timber.d("onTextChanged s = ${s.toString()}, start = $start, count = $count, before = $before") } override fun afterTextChanged(s: Editable?) { - val currentText = s.toString() - if (currentText == lastText) return // 内容未变化时不处理 - lastText = currentText - handler.removeCallbacksAndMessages(null) // 取消之前的延迟任务 - handler.postDelayed({ -// if (currentText.isNotEmpty()) { - viewModel.getSearchMemberList(param = currentText, pageNum = 1) -// } - }, debounceDelay) + Timber.d("afterTextChanged s = ${s.toString()}") } }) + binding.etUserInfo.setOnEditorActionListener { _, actionId, keyEvent -> + if (actionId == EditorInfo.IME_ACTION_SEARCH) { + val currentText = binding.etUserInfo.text.toString() + val containsNewlines = currentText.contains('\n') || currentText.contains('\r') + if (containsNewlines) { + Timber.d("非用户主动搜索") + true + } + debouncer.debounce { + // 执行搜索操作 + viewModel.getSearchMemberList(param = currentText, pageNum = 1) + // 隐藏键盘 + KeyboardUtils.hideKeyboard(requireActivity()) + } + true // 表示已处理该事件 + } else { + false // 未处理其他动作 + } + } binding.llBind.setOnClickListener { if (info == null || info!!.equipmentCode?.isEmpty() == true || info!!.equipmentBoxCode?.isEmpty() == true) { ToastUtils.showToast("传入的设备信息异常") @@ -176,15 +195,29 @@ class BindPlateFragment : BaseFragment( if (it.first == null) return@collect // 解绑状态过滤 val errorInfo = it.second if (errorInfo.isSuccess()) { - if (errorInfo.equipmentUserInfo?.isOtherEquipment() == true) { + if (errorInfo.equipmentUserInfo == null) { + ToastUtils.showToast("数据异常") + return@collect + } + if (errorInfo.equipmentUserInfo.isOtherEquipment() == true) { MainActivity.start( requireContext(), pageType = PageType.PLATE_TIP, equipmentUserInfo = errorInfo.equipmentUserInfo ) } else { - ToastUtils.showToast("绑定成功") - activity?.finish() + SerialApi.openPlate( + errorInfo.equipmentUserInfo.equipmentBoxCode!!.toInt(), + object : SerialPortManager.SendCallback { + override fun onSuccess() { + ToastUtils.showToast("绑定成功") + activity?.finish() + } + + override fun onFail(e: Exception?) { + ToastUtils.showToast("绑定失败") + } + }) } } else { ToastUtils.showToast(errorInfo.msg) diff --git a/app/src/main/java/com/sw/platecabinet/model/response/EquipmentUserInfo.kt b/app/src/main/java/com/sw/platecabinet/model/response/EquipmentUserInfo.kt index 5325c50..83e8067 100644 --- a/app/src/main/java/com/sw/platecabinet/model/response/EquipmentUserInfo.kt +++ b/app/src/main/java/com/sw/platecabinet/model/response/EquipmentUserInfo.kt @@ -15,12 +15,12 @@ data class EquipmentUserInfo( * 设备盒子编号 */ @SerializedName("equipmentBoxCode") - val equipmentBoxCode: String? = "", + var equipmentBoxCode: String? = "", /** * 设备编号 */ @SerializedName("equipmentCode") - val equipmentCode: String? = "", + var equipmentCode: String? = "", /** * * 设备Id @@ -71,7 +71,7 @@ data class EquipmentUserInfo( * 是否是其他设备 */ fun isOtherEquipment(): Boolean { - return GlobalData.globalEquipmentCode != equipmentCode + return equipmentCode != null && equipmentCode != "" && GlobalData.globalEquipmentCode != equipmentCode } fun isPlaceholder(): Boolean { diff --git a/app/src/main/java/com/sw/platecabinet/utils/Debouncer.kt b/app/src/main/java/com/sw/platecabinet/utils/Debouncer.kt new file mode 100644 index 0000000..3c36921 --- /dev/null +++ b/app/src/main/java/com/sw/platecabinet/utils/Debouncer.kt @@ -0,0 +1,25 @@ +package com.sw.platecabinet.utils + +class Debouncer(private val delayMillis: Long) { + private var lastActionTime = 0L + + /** + * 执行防抖操作 + * @param action 要执行的操作 + * @return Boolean 是否执行了操作 (true=已执行, false=被防抖) + */ + fun debounce(action: () -> Unit): Boolean { + val currentTime = System.currentTimeMillis() + if (currentTime - lastActionTime >= delayMillis) { + lastActionTime = currentTime + action() + return true + } + return false + } + + // 重置防抖计时 + fun reset() { + lastActionTime = 0L + } +} \ No newline at end of file diff --git a/app/src/main/java/com/sw/platecabinet/utils/ThreadUtils.kt b/app/src/main/java/com/sw/platecabinet/utils/ThreadUtils.kt deleted file mode 100644 index 9fed1bd..0000000 --- a/app/src/main/java/com/sw/platecabinet/utils/ThreadUtils.kt +++ /dev/null @@ -1,124 +0,0 @@ -package com.sw.platecabinet.utils - -import android.os.Handler -import android.os.Looper -import kotlinx.coroutines.CoroutineScope -import kotlinx.coroutines.Dispatchers -import kotlinx.coroutines.Job -import kotlinx.coroutines.launch -import kotlinx.coroutines.withContext -import java.util.concurrent.ExecutorService -import java.util.concurrent.Executors -import kotlin.coroutines.CoroutineContext - -/** - * 多功能线程工具类 - * 结合协程、Handler和线程池实现线程切换 - */ -object ThreadUtils : CoroutineScope { - // 主线程Handler - private val mainHandler by lazy { Handler(Looper.getMainLooper()) } - - // 后台线程池(IO密集型任务) - private val ioThreadPool: ExecutorService by lazy { - Executors.newFixedThreadPool(Runtime.getRuntime().availableProcessors() * 2) - } - - // CPU密集型线程池 - private val cpuThreadPool: ExecutorService by lazy { - Executors.newFixedThreadPool(Runtime.getRuntime().availableProcessors()) - } - - // 协程Job管理 - private val job = Job() - - override val coroutineContext: CoroutineContext - get() = Dispatchers.Main + job - - // ========== Handler相关方法 ========== - - /** - * 在主线程执行任务 - * @param delayMillis 延迟时间(毫秒) - */ - fun runOnUiThread(delayMillis: Long = 0, block: () -> Unit) { - if (delayMillis > 0) { - mainHandler.postDelayed(block, delayMillis) - } else { - if (isOnMainThread()) { - block() - } else { - mainHandler.post(block) - } - } - } - - /** - * 移除主线程任务 - */ - fun removeUiThreadTask(block: () -> Unit) { - mainHandler.removeCallbacks(block) - } - - // ========== 线程池相关方法 ========== - - /** - * 在IO线程执行任务 - */ - fun runOnIoThread(block: () -> Unit) { - ioThreadPool.execute(block) - } - - /** - * 在CPU计算线程执行任务 - */ - fun runOnCpuThread(block: () -> Unit) { - cpuThreadPool.execute(block) - } - - // ========== 协程相关方法 ========== - - /** - * 启动协程(默认在主线程) - */ - fun launch(block: suspend CoroutineScope.() -> Unit): Job { - return launch(coroutineContext, block = block) - } - - /** - * 在IO线程启动协程 - */ - fun launchOnIo(block: suspend CoroutineScope.() -> Unit): Job { - return launch(Dispatchers.IO, block = block) - } - - /** - * 切换到主线程(协程环境) - */ - suspend fun switchToMain(block: suspend CoroutineScope.() -> T): T { - return withContext(Dispatchers.Main, block) - } - - /** - * 切换到IO线程(协程环境) - */ - suspend fun switchToIo(block: suspend CoroutineScope.() -> T): T { - return withContext(Dispatchers.IO, block) - } - - /** - * 是否在主线程 - */ - fun isOnMainThread(): Boolean { - return Looper.myLooper() == Looper.getMainLooper() - } - - /** - * 释放资源 - */ - fun release() { - job.cancel() - ioThreadPool.shutdown() - cpuThreadPool.shutdown() - } -} \ No newline at end of file diff --git a/app/src/main/java/com/sw/platecabinet/viewmodel/SettingViewModel.kt b/app/src/main/java/com/sw/platecabinet/viewmodel/SettingViewModel.kt index 395cb86..2e03f23 100644 --- a/app/src/main/java/com/sw/platecabinet/viewmodel/SettingViewModel.kt +++ b/app/src/main/java/com/sw/platecabinet/viewmodel/SettingViewModel.kt @@ -99,7 +99,13 @@ class SettingViewModel : BaseViewModel() { ) val response = repository.bindEquipment(bindParam) if (parseResponse(response)) { - val userInfo = response.data + var userInfo = response.data + if (userInfo == null) { + userInfo = EquipmentUserInfo() + userInfo.equipmentBoxCode = equipmentBoxCode + userInfo.plateNumber = plateNumber + userInfo.equipmentCode = equipmentCode + } _bindStateChange.value = true to ErrorInfo(equipmentUserInfo = userInfo) } else { _bindStateChange.value = true to ErrorInfo(response.code, response.msg.toString()) diff --git a/app/src/main/java/com/sw/platecabinet/viewmodel/UserViewModel.kt b/app/src/main/java/com/sw/platecabinet/viewmodel/UserViewModel.kt index 7a3e8c3..80e3fef 100644 --- a/app/src/main/java/com/sw/platecabinet/viewmodel/UserViewModel.kt +++ b/app/src/main/java/com/sw/platecabinet/viewmodel/UserViewModel.kt @@ -1,5 +1,6 @@ package com.sw.platecabinet.viewmodel +import androidx.lifecycle.viewModelScope import com.arcsoft.face.ErrorInfo import com.sw.inbound.utils.SPUtil import com.sw.plate.App @@ -13,10 +14,10 @@ import com.sw.platecabinet.GlobalKey import com.sw.platecabinet.model.request.LoginParam import com.sw.platecabinet.model.response.EquipmentUserInfo import com.sw.platecabinet.model.response.UserFaceModel -import com.sw.platecabinet.utils.ThreadUtils import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.flow.MutableStateFlow import kotlinx.coroutines.flow.StateFlow +import kotlinx.coroutines.launch import kotlinx.coroutines.withContext import timber.log.Timber @@ -70,18 +71,17 @@ class UserViewModel : BaseViewModel() { */ fun activeEngine() { Timber.d("activeEngine") - var appId = "Hkz1rBk6PZXbS8KwKr67K2eZtsz8bRoMHLg64bUdgCZj" - var sdkKey = "AabXs3sHM8UhhE7oCGf4LVMLrdkGb1nJNksbjjTdVt7k" - var activeKey = "085F-118G-Q391-53YL" + faceApi.activeEngine( App.getContext(), - appId, - sdkKey, - activeKey, + GlobalData.appId, + GlobalData.sdkKey, + GlobalData.activeKey, object : FaceApi.ActiveCallback { override fun onSuccess(activeCode: Int) { Timber.d("activeEngine activeCode = $activeCode") - ThreadUtils.launch { +// ThreadUtils.launch { + viewModelScope.launch(Dispatchers.Main) { when (activeCode) { ErrorInfo.MOK -> { ToastUtils.showToast("激活引擎成功") @@ -99,7 +99,7 @@ class UserViewModel : BaseViewModel() { } override fun onFail(e: Exception?) { - ThreadUtils.launch { + viewModelScope.launch(Dispatchers.Main) { ToastUtils.showToast("激活引擎异常,${e?.message}") } } diff --git a/app/src/main/res/drawable/bg_face.png b/app/src/main/res/drawable/bg_face.png index b280fc3..8bb773e 100644 Binary files a/app/src/main/res/drawable/bg_face.png and b/app/src/main/res/drawable/bg_face.png differ diff --git a/app/src/main/res/drawable/ic_init_img.png b/app/src/main/res/drawable/ic_init_img.png new file mode 100644 index 0000000..6eec96a Binary files /dev/null and b/app/src/main/res/drawable/ic_init_img.png differ diff --git a/app/src/main/res/drawable/ic_init_press.png b/app/src/main/res/drawable/ic_init_press.png new file mode 100644 index 0000000..a9ede57 Binary files /dev/null and b/app/src/main/res/drawable/ic_init_press.png differ diff --git a/app/src/main/res/drawable/ic_init_text.png b/app/src/main/res/drawable/ic_init_text.png new file mode 100644 index 0000000..284c0c0 Binary files /dev/null and b/app/src/main/res/drawable/ic_init_text.png differ diff --git a/app/src/main/res/layout/activity_init.xml b/app/src/main/res/layout/activity_init.xml new file mode 100644 index 0000000..5335372 --- /dev/null +++ b/app/src/main/res/layout/activity_init.xml @@ -0,0 +1,40 @@ + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/app/src/main/res/layout/activity_login_face.xml b/app/src/main/res/layout/activity_login_face.xml index 12bb722..6e3de7b 100644 --- a/app/src/main/res/layout/activity_login_face.xml +++ b/app/src/main/res/layout/activity_login_face.xml @@ -4,9 +4,9 @@ android:id="@+id/main" android:layout_width="match_parent" android:layout_height="match_parent" + android:background="@drawable/bg" android:fitsSystemWindows="false" android:orientation="vertical" - android:background="@drawable/bg" tools:context=".activity.LoginByFaceActivity"> - - - @@ -40,33 +29,46 @@ android:layout_width="380dp" android:layout_height="wrap_content" android:layout_gravity="center" + android:layout_marginTop="0dp" android:paddingTop="1dp"> - + android:layout_height="wrap_content" + android:visibility="visible" /> + android:layout_height="380dp" + android:visibility="gone" /> + android:layout_height="match_parent" + android:layout_marginTop="0dp" + android:background="@drawable/bg_face" + android:visibility="visible" /> + + + - - \ No newline at end of file diff --git a/app/src/main/res/layout/fragment_bind_plate.xml b/app/src/main/res/layout/fragment_bind_plate.xml index b166895..6046e71 100644 --- a/app/src/main/res/layout/fragment_bind_plate.xml +++ b/app/src/main/res/layout/fragment_bind_plate.xml @@ -122,7 +122,7 @@ android:background="@color/transparent" android:gravity="center" android:hint="请输入会员姓名或手机号" - android:imeOptions="actionDone" + android:imeOptions="actionSearch" android:inputType="text" android:maxLines="1" android:textColor="#F0C8B4" diff --git a/lib_face/proguard-rules.pro b/lib_face/proguard-rules.pro index 481bb43..6d7e2f3 100644 --- a/lib_face/proguard-rules.pro +++ b/lib_face/proguard-rules.pro @@ -18,4 +18,5 @@ # If you keep the line number information, uncomment this to # hide the original source file name. -#-renamesourcefileattribute SourceFile \ No newline at end of file +#-renamesourcefileattribute SourceFile + -keep class androidx.core.app.CoreComponentFactory { *; } diff --git a/lib_face/src/main/java/com/sw/plate/utils/ScanGunKeyEventHelper.java b/lib_face/src/main/java/com/sw/plate/utils/ScanGunKeyEventHelper.java index 2b64fd0..18720d2 100644 --- a/lib_face/src/main/java/com/sw/plate/utils/ScanGunKeyEventHelper.java +++ b/lib_face/src/main/java/com/sw/plate/utils/ScanGunKeyEventHelper.java @@ -23,9 +23,9 @@ public class ScanGunKeyEventHelper { // 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 long lastTime = 0L; public ScanGunKeyEventHelper(Context context, OnScanSuccessListener onScanSuccessListener) { - mContext = context; mOnScanSuccessListener = onScanSuccessListener; mStringBufferResult = new StringBuffer(); @@ -38,6 +38,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); diff --git a/lib_face/src/main/java/com/sw/plate/utils/comn/SerialApi.java b/lib_face/src/main/java/com/sw/plate/utils/comn/SerialApi.java index e77d218..0c28597 100644 --- a/lib_face/src/main/java/com/sw/plate/utils/comn/SerialApi.java +++ b/lib_face/src/main/java/com/sw/plate/utils/comn/SerialApi.java @@ -34,4 +34,10 @@ public class SerialApi { } serialPortManager.sendCommand(generateOpenCommand(boxNumber), callback); } + + public static void close() { + if (serialPortManager != null) { + serialPortManager.close(); + } + } }