refactor(login): 优化人脸登录与设备初始化环境切换逻辑

- 移除DeviceInitActivity中的多点触控环境切换功能及相关依赖,简化代码结构
- 调整登录页连点触发环境切换逻辑,新增环境弹窗显示及倒计时暂停机制
- 实现登录页环境切换后自动重启应用,提升用户体验和状态一致性
- 修改NetViewModelV2分页大小从100至500,提高批量请求效率
- 注释MyApp中deviceId硬编码,恢复动态获取设备ID
- 清理UserViewModel中已废弃的人脸引擎激活代码,保持代码整洁
This commit is contained in:
mazengfei
2026-09-02 11:11:34 +08:00
parent 57345f8750
commit 04b0c85482
5 changed files with 104 additions and 111 deletions
@@ -27,7 +27,7 @@ class MyApp : App() {
*/ */
private fun initGlobalData() { private fun initGlobalData() {
var deviceId = AppUtil.getUDID(this) var deviceId = AppUtil.getUDID(this)
deviceId = "be154831-3466-3ba2-a2ea-57652c919fed" // deviceId = "be154831-3466-3ba2-a2ea-57652c919fed"
Log.d("MyApp", "initialize: deviceId=$deviceId") Log.d("MyApp", "initialize: deviceId=$deviceId")
GlobalData.deviceId = deviceId GlobalData.deviceId = deviceId
@@ -1,22 +1,11 @@
package com.sw.platecabinet.activity package com.sw.platecabinet.activity
import android.content.Intent import android.content.Intent
import android.os.Handler
import android.os.Looper
import android.view.MotionEvent
import android.view.WindowManager
import androidx.lifecycle.lifecycleScope
import com.sw.plate.utils.ToastUtils import com.sw.plate.utils.ToastUtils
import com.sw.plate.utils.arcface.facedb.FaceDatabase
import com.sw.platecabinet.Environment
import com.sw.platecabinet.GlobalData import com.sw.platecabinet.GlobalData
import com.sw.platecabinet.dialog.EnvironmentSelectDialog
import com.sw.platecabinet.member.databinding.ActivityDeviceInitBinding import com.sw.platecabinet.member.databinding.ActivityDeviceInitBinding
import com.sw.platecabinet.member.databinding.ItemTitleTimeBinding import com.sw.platecabinet.member.databinding.ItemTitleTimeBinding
import com.sw.platecabinet.utils.SpTool import com.sw.platecabinet.utils.SpTool
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.launch
import kotlinx.coroutines.withContext
import timber.log.Timber import timber.log.Timber
/** /**
@@ -24,11 +13,6 @@ import timber.log.Timber
*/ */
class DeviceInitActivity : BaseActivity<ActivityDeviceInitBinding>() { class DeviceInitActivity : BaseActivity<ActivityDeviceInitBinding>() {
// 连点切换环境的计数与复位
private var tapCount = 0
private val tapHandler = Handler(Looper.getMainLooper())
private val resetTapRunnable = Runnable { tapCount = 0 }
override fun inflateViewBinding(): ActivityDeviceInitBinding { override fun inflateViewBinding(): ActivityDeviceInitBinding {
return ActivityDeviceInitBinding.inflate(layoutInflater) return ActivityDeviceInitBinding.inflate(layoutInflater)
} }
@@ -38,8 +22,7 @@ class DeviceInitActivity : BaseActivity<ActivityDeviceInitBinding>() {
} }
override fun initialize() { override fun initialize() {
// 等待框设为不拦截触摸,确保连点手势可达 showWaitingDialog("加载中……")
showWaitingDialog("加载中……")?.window?.addFlags(WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE)
// 首次启动先全量拉取人脸缓存,后续走增量同步 // 首次启动先全量拉取人脸缓存,后续走增量同步
if (SpTool.getFirstGetFace()) { if (SpTool.getFirstGetFace()) {
netViewModelV2.getUserFaceCache { status, msg -> netViewModelV2.getUserFaceCache { status, msg ->
@@ -51,50 +34,6 @@ class DeviceInitActivity : BaseActivity<ActivityDeviceInitBinding>() {
} }
} }
/**
* 连续点击 3 次(500ms 内)触发环境切换弹窗
*/
override fun dispatchTouchEvent(ev: MotionEvent): Boolean {
if (ev.action == MotionEvent.ACTION_DOWN) {
tapCount++
tapHandler.removeCallbacks(resetTapRunnable)
tapHandler.postDelayed(resetTapRunnable, 500)
if (tapCount >= 3) {
tapCount = 0
tapHandler.removeCallbacks(resetTapRunnable)
showEnvironmentDialog()
return true
}
}
return super.dispatchTouchEvent(ev)
}
/**
* 弹出环境选择弹窗
*/
private fun showEnvironmentDialog() {
EnvironmentSelectDialog(this) { env ->
switchEnvironment(env)
}.show()
}
/**
* 切换环境:持久化 + 清空本地人脸库 + 重置增量同步状态
*/
private fun switchEnvironment(env: Environment) {
SpTool.setBaseUrl(env.url)
lifecycleScope.launch(Dispatchers.IO) {
val faceDao = FaceDatabase.getInstance(this@DeviceInitActivity).faceDao()
faceDao.deleteAll()
faceDao.resetId()
SpTool.setLastFaceTimestamp(0L)
SpTool.setFirstGetFace(true)
withContext(Dispatchers.Main) {
ToastUtils.showToast("已切换到${env.name},重启后生效")
}
}
}
/** /**
* 获取设备配置(V2),并初始化虹软 SDK 激活参数 * 获取设备配置(V2),并初始化虹软 SDK 激活参数
*/ */
@@ -103,24 +42,22 @@ class DeviceInitActivity : BaseActivity<ActivityDeviceInitBinding>() {
runOnUiThread { runOnUiThread {
if (deviceConfig == null) { if (deviceConfig == null) {
hideWaitingDialog() hideWaitingDialog()
ToastUtils.showToast("获取设备配置失败,请连点屏幕3次切换环境") ToastUtils.showToast("获取设备配置失败,请到登录页连点 3 次切换环境")
// goLoginActivity() goLoginActivity()
return@runOnUiThread return@runOnUiThread
} }
GlobalData.appId = deviceConfig.arcsoftAppId ?: "" GlobalData.appId = deviceConfig.arcsoftAppId ?: ""
GlobalData.sdkKey = deviceConfig.arcsoftSdkKey ?: "" GlobalData.sdkKey = deviceConfig.arcsoftSdkKey ?: ""
GlobalData.activeKey = deviceConfig.arcsoftActiveKey ?: "" GlobalData.activeKey = deviceConfig.arcsoftActiveKey ?: ""
binding.root.postDelayed({
hideWaitingDialog() hideWaitingDialog()
goLoginActivity() goLoginActivity()
}, 500)
} }
}, onFailure = { errMsg -> }, onFailure = { errMsg ->
runOnUiThread { runOnUiThread {
hideWaitingDialog() hideWaitingDialog()
Timber.e("getDeviceConfig onFailure: $errMsg") Timber.e("getDeviceConfig onFailure: $errMsg")
ToastUtils.showToast("服务连接失败,请连点屏幕3次切换环境") ToastUtils.showToast("服务连接失败,请到登录页连点 3 次切换环境")
// goLoginActivity() goLoginActivity()
} }
}) })
} }
@@ -41,6 +41,23 @@ import org.greenrobot.eventbus.EventBus
import org.greenrobot.eventbus.Subscribe import org.greenrobot.eventbus.Subscribe
import org.greenrobot.eventbus.ThreadMode import org.greenrobot.eventbus.ThreadMode
import timber.log.Timber import timber.log.Timber
import android.app.AlarmManager
import android.app.PendingIntent
import android.content.Context
import android.os.Handler
import android.os.Looper
import android.os.Process
import android.view.MotionEvent
import androidx.lifecycle.lifecycleScope
import com.sw.plate.utils.arcface.facedb.FaceDatabase
import com.sw.platecabinet.Environment
import com.sw.platecabinet.GlobalData
import com.sw.platecabinet.GlobalKey
import com.sw.platecabinet.dialog.EnvironmentSelectDialog
import com.sw.platecabinet.utils.SpTool
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.launch
import kotlinx.coroutines.withContext
/** /**
* 人脸识别 * 人脸识别
@@ -49,6 +66,12 @@ class LoginByFaceActivity : BaseActivity<ActivityLoginFaceBinding>(),
ViewTreeObserver.OnGlobalLayoutListener { ViewTreeObserver.OnGlobalLayoutListener {
private var countDownTimer: CountDownTimer? = null private var countDownTimer: CountDownTimer? = null
// 连点切换环境计数与复位
private var tapCount = 0
private var switchedEnvironment = false
private val tapHandler = Handler(Looper.getMainLooper())
private val resetTapRunnable = Runnable { tapCount = 0 }
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(
Manifest.permission.CAMERA, Manifest.permission.CAMERA,
@@ -516,5 +539,77 @@ class LoginByFaceActivity : BaseActivity<ActivityLoginFaceBinding>(),
startActivity(intent) startActivity(intent)
} }
/**
* 连续点击 3 次(500ms 内)触发环境切换弹窗
*/
override fun dispatchTouchEvent(ev: MotionEvent): Boolean {
if (ev.action == MotionEvent.ACTION_DOWN) {
tapCount++
tapHandler.removeCallbacks(resetTapRunnable)
tapHandler.postDelayed(resetTapRunnable, 500)
if (tapCount >= 3) {
tapCount = 0
tapHandler.removeCallbacks(resetTapRunnable)
showEnvironmentDialog()
return true
}
}
return super.dispatchTouchEvent(ev)
}
/**
* 弹出环境选择弹窗,弹窗期间暂停 30s 倒计时,避免被自动跳转打断
*/
private fun showEnvironmentDialog() {
countDownTimer?.cancel()
val dialog = EnvironmentSelectDialog(this) { env ->
switchedEnvironment = true
switchEnvironment(env)
}
dialog.setOnDismissListener {
// 未切换(点外部取消)时恢复倒计时;切换后走自动重启,无需恢复
if (!switchedEnvironment) countDownTimer?.start()
}
dialog.show()
}
/**
* 切换环境:同步落盘 + 清空本地人脸库 + 重置增量同步状态 + 自动重启
*/
private fun switchEnvironment(env: Environment) {
// 用 commit 同步写盘,确保自动重启前状态已持久化(apply 是异步的,重启会丢)
getSharedPreferences("default_sp", Context.MODE_PRIVATE).edit()
.putString(GlobalKey.KEY_BASE_URL, env.url)
.putLong(SpTool.LAST_FACE_TIMESTAMP, 0L)
.putBoolean(SpTool.IS_FIRST_GET_FACE, true)
.commit()
GlobalData.appBaseUrl = env.url
lifecycleScope.launch(Dispatchers.IO) {
val faceDao = FaceDatabase.getInstance(this@LoginByFaceActivity).faceDao()
faceDao.deleteAll()
faceDao.resetId()
withContext(Dispatchers.Main) {
ToastUtils.showToast("已切换到${env.name},正在重启")
restartApp()
}
}
}
/**
* 自动重启:用 AlarmManager 拉起启动页后杀进程,实现应用自重启
*/
private fun restartApp() {
val intent = packageManager.getLaunchIntentForPackage(packageName)?.apply {
addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP or Intent.FLAG_ACTIVITY_NEW_TASK or Intent.FLAG_ACTIVITY_CLEAR_TASK)
} ?: return
val pending = PendingIntent.getActivity(
this, 0, intent,
PendingIntent.FLAG_ONE_SHOT or PendingIntent.FLAG_IMMUTABLE
)
val alarmManager = getSystemService(Context.ALARM_SERVICE) as AlarmManager
alarmManager.set(AlarmManager.RTC, System.currentTimeMillis() + 500, pending)
Process.killProcess(Process.myPid())
}
} }
@@ -30,7 +30,7 @@ import java.io.File
class NetViewModelV2 : ViewModel() { class NetViewModelV2 : ViewModel() {
companion object { companion object {
const val PAGE_SIZE = 100 const val PAGE_SIZE = 500
} }
private val faceApi: FaceApi = FaceApi() private val faceApi: FaceApi = FaceApi()
@@ -92,45 +92,6 @@ class UserViewModel : BaseViewModel() {
private var faceTimestamp = 0L private var faceTimestamp = 0L
/**
* 激活人脸识别引擎
*/
fun activeEngine() {
Timber.d("activeEngine")
faceApi.activeEngine(
App.getContext(),
GlobalData.appId,
GlobalData.sdkKey,
GlobalData.activeKey,
object : FaceApi.ActiveCallback {
override fun onSuccess(activeCode: Int) {
Timber.d("activeEngine activeCode = $activeCode")
// ThreadUtils.launch {
viewModelScope.launch(Dispatchers.Main) {
when (activeCode) {
ErrorInfo.MOK -> {
ToastUtils.showToast("激活引擎成功")
}
ErrorInfo.MERR_ASF_ALREADY_ACTIVATED -> {
// ToastUtils.showToast("引擎已激活,无需再次激活")
}
else -> {
ToastUtils.showToast("激活引擎失败($activeCode)")
}
}
}
}
override fun onFail(e: Exception?) {
viewModelScope.launch(Dispatchers.Main) {
ToastUtils.showToast("激活引擎异常,${e?.message}")
}
}
})
}
/** /**
* 校验码登录 * 校验码登录