添加init界面,调整了认证后逻辑,调整了扫描枪扫描处理
This commit is contained in:
@@ -26,29 +26,40 @@
|
|||||||
android:supportsRtl="true"
|
android:supportsRtl="true"
|
||||||
android:theme="@style/Theme.SmartPlateCabinet"
|
android:theme="@style/Theme.SmartPlateCabinet"
|
||||||
tools:targetApi="31">
|
tools:targetApi="31">
|
||||||
|
<activity
|
||||||
|
android:name=".activity.InitActivity"
|
||||||
|
android:exported="true">
|
||||||
|
<intent-filter>
|
||||||
|
<action android:name="android.intent.action.MAIN" />
|
||||||
|
|
||||||
|
<category android:name="android.intent.category.LAUNCHER" />
|
||||||
|
</intent-filter>
|
||||||
|
</activity>
|
||||||
<activity
|
<activity
|
||||||
android:name=".activity.TestActivity"
|
android:name=".activity.TestActivity"
|
||||||
android:exported="true"></activity>
|
android:exported="true" />
|
||||||
<activity
|
<activity
|
||||||
android:name=".activity.LoginByPwdActivity"
|
android:name=".activity.LoginByPwdActivity"
|
||||||
android:exported="true"
|
android:exported="true"
|
||||||
android:launchMode="singleTask">
|
android:launchMode="singleTask">
|
||||||
|
|
||||||
|
<!-- <intent-filter> -->
|
||||||
|
<!-- <action android:name="android.intent.action.MAIN" /> -->
|
||||||
|
|
||||||
|
|
||||||
|
<!-- <category android:name="android.intent.category.LAUNCHER" /> -->
|
||||||
|
<!-- </intent-filter> -->
|
||||||
|
</activity>
|
||||||
|
<activity
|
||||||
|
android:name=".activity.LoginByFaceActivity"
|
||||||
|
android:exported="true"
|
||||||
|
android:launchMode="singleTask">
|
||||||
<!-- <intent-filter>-->
|
<!-- <intent-filter>-->
|
||||||
<!-- <action android:name="android.intent.action.MAIN" />-->
|
<!-- <action android:name="android.intent.action.MAIN" />-->
|
||||||
|
|
||||||
<!-- <category android:name="android.intent.category.LAUNCHER" />-->
|
<!-- <category android:name="android.intent.category.LAUNCHER" />-->
|
||||||
<!-- </intent-filter>-->
|
<!-- </intent-filter>-->
|
||||||
</activity>
|
</activity>
|
||||||
<activity
|
|
||||||
android:name=".activity.LoginByFaceActivity"
|
|
||||||
android:exported="true"
|
|
||||||
android:launchMode="singleTask">
|
|
||||||
<intent-filter>
|
|
||||||
<action android:name="android.intent.action.MAIN" />
|
|
||||||
|
|
||||||
<category android:name="android.intent.category.LAUNCHER" />
|
|
||||||
</intent-filter>
|
|
||||||
</activity>
|
|
||||||
<activity
|
<activity
|
||||||
android:name=".activity.MainActivity"
|
android:name=".activity.MainActivity"
|
||||||
android:exported="true">
|
android:exported="true">
|
||||||
|
|||||||
@@ -26,6 +26,9 @@ object GlobalData {
|
|||||||
*/
|
*/
|
||||||
var arrayMode: Int = 0
|
var arrayMode: Int = 0
|
||||||
|
|
||||||
|
var appId = "Hkz1rBk6PZXbS8KwKr67K2eZtsz8bRoMHLg64bUdgCZj"
|
||||||
|
var sdkKey = "AabXs3sHM8UhhE7oCGf4LVMLrdkGb1nJNksbjjTdVt7k"
|
||||||
|
var activeKey = "085F-118G-Q391-53YL"
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
@@ -318,7 +318,7 @@ abstract class BaseActivity<VB : ViewBinding> : AppCompatActivity() {
|
|||||||
}
|
}
|
||||||
if (equipmentUserInfo.equipmentBoxCode?.isNotEmpty() == true) {
|
if (equipmentUserInfo.equipmentBoxCode?.isNotEmpty() == true) {
|
||||||
SerialApi.openPlate(
|
SerialApi.openPlate(
|
||||||
equipmentUserInfo.equipmentBoxCode.toInt(),
|
equipmentUserInfo.equipmentBoxCode!!.toInt(),
|
||||||
object : SerialPortManager.SendCallback {
|
object : SerialPortManager.SendCallback {
|
||||||
override fun onSuccess() {
|
override fun onSuccess() {
|
||||||
MainActivity.start(context, pageType = PageType.PLATE_TIP)
|
MainActivity.start(context, pageType = PageType.PLATE_TIP)
|
||||||
@@ -343,6 +343,7 @@ abstract class BaseActivity<VB : ViewBinding> : AppCompatActivity() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
override fun onDestroy() {
|
override fun onDestroy() {
|
||||||
|
SerialApi.close()
|
||||||
timeJob?.cancel()
|
timeJob?.cancel()
|
||||||
keyEventHelper?.onDestroy()
|
keyEventHelper?.onDestroy()
|
||||||
super.onDestroy()
|
super.onDestroy()
|
||||||
|
|||||||
@@ -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<ActivityInitBinding>() {
|
||||||
|
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()
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
@@ -5,6 +5,7 @@ import android.content.Intent
|
|||||||
import android.graphics.Point
|
import android.graphics.Point
|
||||||
import android.hardware.Camera
|
import android.hardware.Camera
|
||||||
import android.os.Build
|
import android.os.Build
|
||||||
|
import android.os.CountDownTimer
|
||||||
import android.util.DisplayMetrics
|
import android.util.DisplayMetrics
|
||||||
import android.view.View
|
import android.view.View
|
||||||
import android.view.ViewGroup
|
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.R
|
||||||
import com.sw.platecabinet.databinding.ActivityLoginFaceBinding
|
import com.sw.platecabinet.databinding.ActivityLoginFaceBinding
|
||||||
import com.sw.platecabinet.databinding.ItemTitleTimeBinding
|
import com.sw.platecabinet.databinding.ItemTitleTimeBinding
|
||||||
|
import com.sw.platecabinet.model.response.EquipmentUserInfo
|
||||||
import com.sw.platecabinet.utils.PermissionHelper
|
import com.sw.platecabinet.utils.PermissionHelper
|
||||||
import com.sw.platecabinet.utils.ThreadUtils
|
|
||||||
import timber.log.Timber
|
import timber.log.Timber
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -39,6 +40,7 @@ import timber.log.Timber
|
|||||||
class LoginByFaceActivity : BaseActivity<ActivityLoginFaceBinding>(),
|
class LoginByFaceActivity : BaseActivity<ActivityLoginFaceBinding>(),
|
||||||
ViewTreeObserver.OnGlobalLayoutListener {
|
ViewTreeObserver.OnGlobalLayoutListener {
|
||||||
private val recognizeViewModel by viewModels<RecognizeViewModel>()
|
private val recognizeViewModel by viewModels<RecognizeViewModel>()
|
||||||
|
private var countDownTimer: CountDownTimer? = null
|
||||||
|
|
||||||
private val CAMERA_PERMISSION_REQUEST_CODE = 100
|
private val CAMERA_PERMISSION_REQUEST_CODE = 100
|
||||||
private val REQUIRED_PERMISSIONS: Array<String> = arrayOf(
|
private val REQUIRED_PERMISSIONS: Array<String> = arrayOf(
|
||||||
@@ -55,11 +57,19 @@ class LoginByFaceActivity : BaseActivity<ActivityLoginFaceBinding>(),
|
|||||||
return binding.includeHeader
|
return binding.includeHeader
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun initialize() {
|
companion object {
|
||||||
ThreadUtils.launch {
|
private var instance: LoginByFaceActivity? = null
|
||||||
viewModel.activeEngine()
|
|
||||||
}
|
|
||||||
|
|
||||||
|
fun finishActivity() {
|
||||||
|
instance?.finish()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun initialize() {
|
||||||
|
instance = this
|
||||||
|
viewModel.activeEngine()
|
||||||
|
|
||||||
|
initCountTime()
|
||||||
initArcViewModel()
|
initArcViewModel()
|
||||||
initArcView()
|
initArcView()
|
||||||
openRectInfoDraw = true
|
openRectInfoDraw = true
|
||||||
@@ -157,6 +167,7 @@ class LoginByFaceActivity : BaseActivity<ActivityLoginFaceBinding>(),
|
|||||||
}
|
}
|
||||||
|
|
||||||
override fun onDestroy() {
|
override fun onDestroy() {
|
||||||
|
instance = null
|
||||||
if (rgbCameraHelper != null) {
|
if (rgbCameraHelper != null) {
|
||||||
rgbCameraHelper!!.release()
|
rgbCameraHelper!!.release()
|
||||||
rgbCameraHelper = null
|
rgbCameraHelper = null
|
||||||
@@ -356,6 +367,10 @@ class LoginByFaceActivity : BaseActivity<ActivityLoginFaceBinding>(),
|
|||||||
super.onResume()
|
super.onResume()
|
||||||
resumeCamera()
|
resumeCamera()
|
||||||
viewModel.resetUserInfo()
|
viewModel.resetUserInfo()
|
||||||
|
countDownTimer?.let {
|
||||||
|
it.cancel()
|
||||||
|
it.start()
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
protected override fun onPause() {
|
protected override fun onPause() {
|
||||||
@@ -369,4 +384,21 @@ class LoginByFaceActivity : BaseActivity<ActivityLoginFaceBinding>(),
|
|||||||
recognizeViewModel.onPreviewFrame(ByteArray(1382400), true)
|
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()
|
||||||
|
}
|
||||||
}
|
}
|
||||||
@@ -41,6 +41,7 @@ class LoginByPwdActivity : BaseActivity<ActivityLoginByPwdBinding>() {
|
|||||||
|
|
||||||
override fun handleLoginSuccess(equipmentUserInfo: EquipmentUserInfo, isAdmin: Boolean) {
|
override fun handleLoginSuccess(equipmentUserInfo: EquipmentUserInfo, isAdmin: Boolean) {
|
||||||
super.handleLoginSuccess(equipmentUserInfo, isAdmin)
|
super.handleLoginSuccess(equipmentUserInfo, isAdmin)
|
||||||
|
LoginByFaceActivity.finishActivity()
|
||||||
finish()
|
finish()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1,16 +1,17 @@
|
|||||||
package com.sw.platecabinet.fragment
|
package com.sw.platecabinet.fragment
|
||||||
|
|
||||||
import android.os.Bundle
|
import android.os.Bundle
|
||||||
import android.os.Handler
|
|
||||||
import android.os.Looper
|
|
||||||
import android.text.Editable
|
import android.text.Editable
|
||||||
import android.text.TextUtils
|
import android.text.TextUtils
|
||||||
import android.text.TextWatcher
|
import android.text.TextWatcher
|
||||||
|
import android.view.inputmethod.EditorInfo
|
||||||
import androidx.lifecycle.lifecycleScope
|
import androidx.lifecycle.lifecycleScope
|
||||||
import androidx.recyclerview.widget.GridLayoutManager
|
import androidx.recyclerview.widget.GridLayoutManager
|
||||||
import androidx.recyclerview.widget.LinearLayoutManager
|
import androidx.recyclerview.widget.LinearLayoutManager
|
||||||
import androidx.recyclerview.widget.RecyclerView
|
import androidx.recyclerview.widget.RecyclerView
|
||||||
import com.sw.plate.utils.ToastUtils
|
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.R
|
||||||
import com.sw.platecabinet.activity.MainActivity
|
import com.sw.platecabinet.activity.MainActivity
|
||||||
import com.sw.platecabinet.activity.PageType
|
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.ext.maskPhone
|
||||||
import com.sw.platecabinet.model.response.EquipmentUserInfo
|
import com.sw.platecabinet.model.response.EquipmentUserInfo
|
||||||
import com.sw.platecabinet.model.response.SearchResult
|
import com.sw.platecabinet.model.response.SearchResult
|
||||||
|
import com.sw.platecabinet.utils.Debouncer
|
||||||
import com.sw.platecabinet.utils.KeyboardUtils
|
import com.sw.platecabinet.utils.KeyboardUtils
|
||||||
import kotlinx.coroutines.flow.drop
|
import kotlinx.coroutines.flow.drop
|
||||||
import kotlinx.coroutines.launch
|
import kotlinx.coroutines.launch
|
||||||
@@ -39,6 +41,7 @@ class BindPlateFragment : BaseFragment<FragmentBindPlateBinding>(
|
|||||||
private var info: EquipmentUserInfo? = null
|
private var info: EquipmentUserInfo? = null
|
||||||
private var checkedItem: SearchResult.Member? = null
|
private var checkedItem: SearchResult.Member? = null
|
||||||
private var lastText = ""
|
private var lastText = ""
|
||||||
|
private val debouncer = Debouncer(2000)
|
||||||
|
|
||||||
companion object {
|
companion object {
|
||||||
@JvmStatic
|
@JvmStatic
|
||||||
@@ -94,21 +97,25 @@ class BindPlateFragment : BaseFragment<FragmentBindPlateBinding>(
|
|||||||
}
|
}
|
||||||
})
|
})
|
||||||
(activity as MainActivity).registerKeyEventInfo {
|
(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() {
|
private fun initListener() {
|
||||||
binding.etUserInfo.addTextChangedListener(object : TextWatcher {
|
binding.etCode.addTextChangedListener(object : TextWatcher {
|
||||||
private val handler = Handler(Looper.getMainLooper())
|
|
||||||
private val debounceDelay = 500L // 延迟 500 毫秒
|
|
||||||
|
|
||||||
override fun beforeTextChanged(
|
override fun beforeTextChanged(
|
||||||
s: CharSequence?,
|
s: CharSequence?,
|
||||||
start: Int,
|
start: Int,
|
||||||
count: Int,
|
count: Int,
|
||||||
after: Int
|
after: Int
|
||||||
) {
|
) {
|
||||||
|
Timber.d("beforeTextChanged s = ${s.toString()}, start = $start, count = $count, after = $after")
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun onTextChanged(
|
override fun onTextChanged(
|
||||||
@@ -117,20 +124,32 @@ class BindPlateFragment : BaseFragment<FragmentBindPlateBinding>(
|
|||||||
before: Int,
|
before: Int,
|
||||||
count: Int
|
count: Int
|
||||||
) {
|
) {
|
||||||
|
Timber.d("onTextChanged s = ${s.toString()}, start = $start, count = $count, before = $before")
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun afterTextChanged(s: Editable?) {
|
override fun afterTextChanged(s: Editable?) {
|
||||||
val currentText = s.toString()
|
Timber.d("afterTextChanged s = ${s.toString()}")
|
||||||
if (currentText == lastText) return // 内容未变化时不处理
|
|
||||||
lastText = currentText
|
|
||||||
handler.removeCallbacksAndMessages(null) // 取消之前的延迟任务
|
|
||||||
handler.postDelayed({
|
|
||||||
// if (currentText.isNotEmpty()) {
|
|
||||||
viewModel.getSearchMemberList(param = currentText, pageNum = 1)
|
|
||||||
// }
|
|
||||||
}, debounceDelay)
|
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
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 {
|
binding.llBind.setOnClickListener {
|
||||||
if (info == null || info!!.equipmentCode?.isEmpty() == true || info!!.equipmentBoxCode?.isEmpty() == true) {
|
if (info == null || info!!.equipmentCode?.isEmpty() == true || info!!.equipmentBoxCode?.isEmpty() == true) {
|
||||||
ToastUtils.showToast("传入的设备信息异常")
|
ToastUtils.showToast("传入的设备信息异常")
|
||||||
@@ -176,15 +195,29 @@ class BindPlateFragment : BaseFragment<FragmentBindPlateBinding>(
|
|||||||
if (it.first == null) return@collect // 解绑状态过滤
|
if (it.first == null) return@collect // 解绑状态过滤
|
||||||
val errorInfo = it.second
|
val errorInfo = it.second
|
||||||
if (errorInfo.isSuccess()) {
|
if (errorInfo.isSuccess()) {
|
||||||
if (errorInfo.equipmentUserInfo?.isOtherEquipment() == true) {
|
if (errorInfo.equipmentUserInfo == null) {
|
||||||
|
ToastUtils.showToast("数据异常")
|
||||||
|
return@collect
|
||||||
|
}
|
||||||
|
if (errorInfo.equipmentUserInfo.isOtherEquipment() == true) {
|
||||||
MainActivity.start(
|
MainActivity.start(
|
||||||
requireContext(),
|
requireContext(),
|
||||||
pageType = PageType.PLATE_TIP,
|
pageType = PageType.PLATE_TIP,
|
||||||
equipmentUserInfo = errorInfo.equipmentUserInfo
|
equipmentUserInfo = errorInfo.equipmentUserInfo
|
||||||
)
|
)
|
||||||
} else {
|
} else {
|
||||||
ToastUtils.showToast("绑定成功")
|
SerialApi.openPlate(
|
||||||
activity?.finish()
|
errorInfo.equipmentUserInfo.equipmentBoxCode!!.toInt(),
|
||||||
|
object : SerialPortManager.SendCallback {
|
||||||
|
override fun onSuccess() {
|
||||||
|
ToastUtils.showToast("绑定成功")
|
||||||
|
activity?.finish()
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun onFail(e: Exception?) {
|
||||||
|
ToastUtils.showToast("绑定失败")
|
||||||
|
}
|
||||||
|
})
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
ToastUtils.showToast(errorInfo.msg)
|
ToastUtils.showToast(errorInfo.msg)
|
||||||
|
|||||||
@@ -15,12 +15,12 @@ data class EquipmentUserInfo(
|
|||||||
* 设备盒子编号
|
* 设备盒子编号
|
||||||
*/
|
*/
|
||||||
@SerializedName("equipmentBoxCode")
|
@SerializedName("equipmentBoxCode")
|
||||||
val equipmentBoxCode: String? = "",
|
var equipmentBoxCode: String? = "",
|
||||||
/**
|
/**
|
||||||
* 设备编号
|
* 设备编号
|
||||||
*/
|
*/
|
||||||
@SerializedName("equipmentCode")
|
@SerializedName("equipmentCode")
|
||||||
val equipmentCode: String? = "",
|
var equipmentCode: String? = "",
|
||||||
/**
|
/**
|
||||||
*
|
*
|
||||||
* 设备Id
|
* 设备Id
|
||||||
@@ -71,7 +71,7 @@ data class EquipmentUserInfo(
|
|||||||
* 是否是其他设备
|
* 是否是其他设备
|
||||||
*/
|
*/
|
||||||
fun isOtherEquipment(): Boolean {
|
fun isOtherEquipment(): Boolean {
|
||||||
return GlobalData.globalEquipmentCode != equipmentCode
|
return equipmentCode != null && equipmentCode != "" && GlobalData.globalEquipmentCode != equipmentCode
|
||||||
}
|
}
|
||||||
|
|
||||||
fun isPlaceholder(): Boolean {
|
fun isPlaceholder(): Boolean {
|
||||||
|
|||||||
@@ -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
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -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 <T> switchToMain(block: suspend CoroutineScope.() -> T): T {
|
|
||||||
return withContext(Dispatchers.Main, block)
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 切换到IO线程(协程环境)
|
|
||||||
*/
|
|
||||||
suspend fun <T> 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()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -99,7 +99,13 @@ class SettingViewModel : BaseViewModel() {
|
|||||||
)
|
)
|
||||||
val response = repository.bindEquipment(bindParam)
|
val response = repository.bindEquipment(bindParam)
|
||||||
if (parseResponse(response)) {
|
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)
|
_bindStateChange.value = true to ErrorInfo(equipmentUserInfo = userInfo)
|
||||||
} else {
|
} else {
|
||||||
_bindStateChange.value = true to ErrorInfo(response.code, response.msg.toString())
|
_bindStateChange.value = true to ErrorInfo(response.code, response.msg.toString())
|
||||||
|
|||||||
@@ -1,5 +1,6 @@
|
|||||||
package com.sw.platecabinet.viewmodel
|
package com.sw.platecabinet.viewmodel
|
||||||
|
|
||||||
|
import androidx.lifecycle.viewModelScope
|
||||||
import com.arcsoft.face.ErrorInfo
|
import com.arcsoft.face.ErrorInfo
|
||||||
import com.sw.inbound.utils.SPUtil
|
import com.sw.inbound.utils.SPUtil
|
||||||
import com.sw.plate.App
|
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.request.LoginParam
|
||||||
import com.sw.platecabinet.model.response.EquipmentUserInfo
|
import com.sw.platecabinet.model.response.EquipmentUserInfo
|
||||||
import com.sw.platecabinet.model.response.UserFaceModel
|
import com.sw.platecabinet.model.response.UserFaceModel
|
||||||
import com.sw.platecabinet.utils.ThreadUtils
|
|
||||||
import kotlinx.coroutines.Dispatchers
|
import kotlinx.coroutines.Dispatchers
|
||||||
import kotlinx.coroutines.flow.MutableStateFlow
|
import kotlinx.coroutines.flow.MutableStateFlow
|
||||||
import kotlinx.coroutines.flow.StateFlow
|
import kotlinx.coroutines.flow.StateFlow
|
||||||
|
import kotlinx.coroutines.launch
|
||||||
import kotlinx.coroutines.withContext
|
import kotlinx.coroutines.withContext
|
||||||
import timber.log.Timber
|
import timber.log.Timber
|
||||||
|
|
||||||
@@ -70,18 +71,17 @@ class UserViewModel : BaseViewModel() {
|
|||||||
*/
|
*/
|
||||||
fun activeEngine() {
|
fun activeEngine() {
|
||||||
Timber.d("activeEngine")
|
Timber.d("activeEngine")
|
||||||
var appId = "Hkz1rBk6PZXbS8KwKr67K2eZtsz8bRoMHLg64bUdgCZj"
|
|
||||||
var sdkKey = "AabXs3sHM8UhhE7oCGf4LVMLrdkGb1nJNksbjjTdVt7k"
|
|
||||||
var activeKey = "085F-118G-Q391-53YL"
|
|
||||||
faceApi.activeEngine(
|
faceApi.activeEngine(
|
||||||
App.getContext(),
|
App.getContext(),
|
||||||
appId,
|
GlobalData.appId,
|
||||||
sdkKey,
|
GlobalData.sdkKey,
|
||||||
activeKey,
|
GlobalData.activeKey,
|
||||||
object : FaceApi.ActiveCallback {
|
object : FaceApi.ActiveCallback {
|
||||||
override fun onSuccess(activeCode: Int) {
|
override fun onSuccess(activeCode: Int) {
|
||||||
Timber.d("activeEngine activeCode = $activeCode")
|
Timber.d("activeEngine activeCode = $activeCode")
|
||||||
ThreadUtils.launch {
|
// ThreadUtils.launch {
|
||||||
|
viewModelScope.launch(Dispatchers.Main) {
|
||||||
when (activeCode) {
|
when (activeCode) {
|
||||||
ErrorInfo.MOK -> {
|
ErrorInfo.MOK -> {
|
||||||
ToastUtils.showToast("激活引擎成功")
|
ToastUtils.showToast("激活引擎成功")
|
||||||
@@ -99,7 +99,7 @@ class UserViewModel : BaseViewModel() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
override fun onFail(e: Exception?) {
|
override fun onFail(e: Exception?) {
|
||||||
ThreadUtils.launch {
|
viewModelScope.launch(Dispatchers.Main) {
|
||||||
ToastUtils.showToast("激活引擎异常,${e?.message}")
|
ToastUtils.showToast("激活引擎异常,${e?.message}")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Binary file not shown.
|
Before Width: | Height: | Size: 94 KiB After Width: | Height: | Size: 113 KiB |
Binary file not shown.
|
After Width: | Height: | Size: 100 KiB |
Binary file not shown.
|
After Width: | Height: | Size: 2.2 KiB |
Binary file not shown.
|
After Width: | Height: | Size: 12 KiB |
@@ -0,0 +1,40 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
|
xmlns:tools="http://schemas.android.com/tools"
|
||||||
|
android:id="@+id/main"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="match_parent"
|
||||||
|
android:background="@drawable/bg"
|
||||||
|
android:orientation="vertical"
|
||||||
|
tools:context=".activity.InitActivity">
|
||||||
|
|
||||||
|
<include
|
||||||
|
android:id="@+id/includeHeader"
|
||||||
|
layout="@layout/item_title_time" />
|
||||||
|
|
||||||
|
<LinearLayout
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_marginTop="260dp"
|
||||||
|
android:gravity="center_horizontal"
|
||||||
|
android:orientation="vertical">
|
||||||
|
|
||||||
|
<ImageView
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:src="@drawable/ic_init_text" />
|
||||||
|
|
||||||
|
<ImageView
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_marginTop="90dp"
|
||||||
|
android:src="@drawable/ic_init_img" />
|
||||||
|
|
||||||
|
<ImageView
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_marginTop="20dp"
|
||||||
|
android:src="@drawable/ic_init_press" />
|
||||||
|
</LinearLayout>
|
||||||
|
|
||||||
|
</LinearLayout>
|
||||||
@@ -4,9 +4,9 @@
|
|||||||
android:id="@+id/main"
|
android:id="@+id/main"
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="match_parent"
|
android:layout_height="match_parent"
|
||||||
|
android:background="@drawable/bg"
|
||||||
android:fitsSystemWindows="false"
|
android:fitsSystemWindows="false"
|
||||||
android:orientation="vertical"
|
android:orientation="vertical"
|
||||||
android:background="@drawable/bg"
|
|
||||||
tools:context=".activity.LoginByFaceActivity">
|
tools:context=".activity.LoginByFaceActivity">
|
||||||
|
|
||||||
<include
|
<include
|
||||||
@@ -19,20 +19,9 @@
|
|||||||
android:gravity="center_horizontal"
|
android:gravity="center_horizontal"
|
||||||
android:orientation="vertical">
|
android:orientation="vertical">
|
||||||
|
|
||||||
<TextView
|
|
||||||
android:id="@+id/tv_tip"
|
|
||||||
android:layout_width="wrap_content"
|
|
||||||
android:layout_height="wrap_content"
|
|
||||||
android:layout_marginTop="129dp"
|
|
||||||
android:text="请正视屏幕"
|
|
||||||
android:textColor="#fff0c8b4"
|
|
||||||
android:textSize="36sp" />
|
|
||||||
|
|
||||||
|
|
||||||
<FrameLayout
|
<FrameLayout
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:layout_marginTop="129dp"
|
|
||||||
android:gravity="center_vertical"
|
android:gravity="center_vertical"
|
||||||
android:visibility="visible">
|
android:visibility="visible">
|
||||||
|
|
||||||
@@ -40,33 +29,46 @@
|
|||||||
android:layout_width="380dp"
|
android:layout_width="380dp"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:layout_gravity="center"
|
android:layout_gravity="center"
|
||||||
|
android:layout_marginTop="0dp"
|
||||||
android:paddingTop="1dp">
|
android:paddingTop="1dp">
|
||||||
|
|
||||||
<TextureView
|
<TextureView
|
||||||
android:id="@+id/dual_camera_texture_preview_rgb"
|
android:id="@+id/dual_camera_texture_preview_rgb"
|
||||||
android:layout_width="380dp"
|
android:layout_width="380dp"
|
||||||
android:visibility="visible"
|
android:layout_height="wrap_content"
|
||||||
android:layout_height="wrap_content" />
|
android:visibility="visible" />
|
||||||
|
|
||||||
|
|
||||||
<com.sw.plate.utils.arcface.FaceRectView
|
<com.sw.plate.utils.arcface.FaceRectView
|
||||||
android:id="@+id/dual_camera_face_rect_view"
|
android:id="@+id/dual_camera_face_rect_view"
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="380dp" />
|
android:layout_height="380dp"
|
||||||
|
android:visibility="gone" />
|
||||||
</FrameLayout>
|
</FrameLayout>
|
||||||
|
|
||||||
<ImageView
|
<ImageView
|
||||||
android:layout_width="wrap_content"
|
android:layout_width="wrap_content"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="match_parent"
|
||||||
android:background="@drawable/bg_face" />
|
android:layout_marginTop="0dp"
|
||||||
|
android:background="@drawable/bg_face"
|
||||||
|
android:visibility="visible" />
|
||||||
|
|
||||||
|
<TextView
|
||||||
|
android:id="@+id/tv_tip"
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_gravity="center_horizontal"
|
||||||
|
android:layout_marginTop="129dp"
|
||||||
|
android:text="请正视屏幕"
|
||||||
|
android:textStyle="bold"
|
||||||
|
android:textColor="#fff0c8b4"
|
||||||
|
android:textSize="36sp" />
|
||||||
|
|
||||||
<LinearLayout
|
<LinearLayout
|
||||||
android:id="@+id/ll_to_pwd"
|
android:id="@+id/ll_to_pwd"
|
||||||
android:layout_width="wrap_content"
|
android:layout_width="wrap_content"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:layout_marginStart="208dp"
|
android:layout_marginStart="208dp"
|
||||||
android:layout_marginTop="500dp"
|
android:layout_marginTop="730dp"
|
||||||
android:background="@drawable/btn_outline_887872"
|
android:background="@drawable/btn_outline_887872"
|
||||||
android:gravity="center"
|
android:gravity="center"
|
||||||
android:paddingHorizontal="45dp"
|
android:paddingHorizontal="45dp"
|
||||||
@@ -80,8 +82,17 @@
|
|||||||
android:textSize="24sp" />
|
android:textSize="24sp" />
|
||||||
</LinearLayout>
|
</LinearLayout>
|
||||||
|
|
||||||
|
<TextView
|
||||||
|
android:id="@+id/tv_to_init"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
tools:text="30"
|
||||||
|
android:padding="12dp"
|
||||||
|
android:gravity="center"
|
||||||
|
android:layout_marginTop="185dp"
|
||||||
|
android:textColor="#F0C8B4"
|
||||||
|
android:textSize="36sp" />
|
||||||
|
|
||||||
</FrameLayout>
|
</FrameLayout>
|
||||||
|
|
||||||
|
|
||||||
</LinearLayout>
|
</LinearLayout>
|
||||||
</LinearLayout>
|
</LinearLayout>
|
||||||
@@ -122,7 +122,7 @@
|
|||||||
android:background="@color/transparent"
|
android:background="@color/transparent"
|
||||||
android:gravity="center"
|
android:gravity="center"
|
||||||
android:hint="请输入会员姓名或手机号"
|
android:hint="请输入会员姓名或手机号"
|
||||||
android:imeOptions="actionDone"
|
android:imeOptions="actionSearch"
|
||||||
android:inputType="text"
|
android:inputType="text"
|
||||||
android:maxLines="1"
|
android:maxLines="1"
|
||||||
android:textColor="#F0C8B4"
|
android:textColor="#F0C8B4"
|
||||||
|
|||||||
Vendored
+1
@@ -19,3 +19,4 @@
|
|||||||
# If you keep the line number information, uncomment this to
|
# If you keep the line number information, uncomment this to
|
||||||
# hide the original source file name.
|
# hide the original source file name.
|
||||||
#-renamesourcefileattribute SourceFile
|
#-renamesourcefileattribute SourceFile
|
||||||
|
-keep class androidx.core.app.CoreComponentFactory { *; }
|
||||||
|
|||||||
@@ -23,9 +23,9 @@ public class ScanGunKeyEventHelper {
|
|||||||
// private String mDeviceName = "TMC HIDKeyBoard";
|
// private String mDeviceName = "TMC HIDKeyBoard";
|
||||||
private String mDeviceName = "Linux 3.4.35 with ak-hsudc Composite Gadget (ACM + HID)";
|
private String mDeviceName = "Linux 3.4.35 with ak-hsudc Composite Gadget (ACM + HID)";
|
||||||
private String mDeviceName1 = "USBKey Chip USBKey Module";
|
private String mDeviceName1 = "USBKey Chip USBKey Module";
|
||||||
|
private long lastTime = 0L;
|
||||||
|
|
||||||
public ScanGunKeyEventHelper(Context context, OnScanSuccessListener onScanSuccessListener) {
|
public ScanGunKeyEventHelper(Context context, OnScanSuccessListener onScanSuccessListener) {
|
||||||
|
|
||||||
mContext = context;
|
mContext = context;
|
||||||
mOnScanSuccessListener = onScanSuccessListener;
|
mOnScanSuccessListener = onScanSuccessListener;
|
||||||
mStringBufferResult = new StringBuffer();
|
mStringBufferResult = new StringBuffer();
|
||||||
@@ -38,6 +38,14 @@ public class ScanGunKeyEventHelper {
|
|||||||
*/
|
*/
|
||||||
private void performScanSuccess() {
|
private void performScanSuccess() {
|
||||||
String barcode = mStringBufferResult.toString();
|
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))
|
if (mOnScanSuccessListener != null && !TextUtils.isEmpty(barcode))
|
||||||
mOnScanSuccessListener.onScanSuccess(barcode);
|
mOnScanSuccessListener.onScanSuccess(barcode);
|
||||||
mStringBufferResult.setLength(0);
|
mStringBufferResult.setLength(0);
|
||||||
|
|||||||
@@ -34,4 +34,10 @@ public class SerialApi {
|
|||||||
}
|
}
|
||||||
serialPortManager.sendCommand(generateOpenCommand(boxNumber), callback);
|
serialPortManager.sendCommand(generateOpenCommand(boxNumber), callback);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static void close() {
|
||||||
|
if (serialPortManager != null) {
|
||||||
|
serialPortManager.close();
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user