打开app不再清除本地数据,不再发送数据到结算终端,改为新增人脸采集接口,全量增量接口优化

This commit is contained in:
2026-02-03 14:59:22 +08:00
parent c5325f6ad6
commit 9fea23303c
23 changed files with 857 additions and 363 deletions
@@ -2,6 +2,7 @@ package com.sw.platecabinet.activity
import android.Manifest
import android.content.Intent
import android.graphics.Bitmap
import android.graphics.Point
import android.hardware.Camera
import android.os.Build
@@ -14,7 +15,6 @@ import androidx.annotation.RequiresApi
import androidx.lifecycle.Observer
import com.arcsoft.face.ErrorInfo
import com.google.gson.Gson
import com.sw.platecabinet.socket.TcpClientListenerImpl
import com.sw.inbound.utils.DateTimeUtils
import com.sw.plate.utils.Base64
import com.sw.plate.utils.ToastUtils
@@ -35,17 +35,15 @@ import com.sw.plate.utils.arcface.facedb.entity.FaceEntity
import com.sw.plate.utils.arcface.model.UserFaceInfo
import com.sw.plate.utils.arcface.viewmodel.RecognizeViewModel
import com.sw.plate.utils.arcface.viewmodel.RecognizeViewModel.REGISTER_STATUS_READY
import com.sw.platecabinet.GlobalData
import com.sw.platecabinet.MyApp
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.socket.LanServer
import com.sw.platecabinet.socket.LanServerListenerImpl
import com.sw.platecabinet.socket.TcpClient
import com.sw.platecabinet.model.response.UserFaceModel
import com.sw.platecabinet.utils.BitmapSaver
import com.sw.platecabinet.utils.Debouncer
import com.sw.platecabinet.utils.FileUtil
import com.sw.platecabinet.utils.LogFileUtil
import com.sw.platecabinet.utils.PermissionHelper
import com.sw.platecabinet.utils.PlateUtils
import com.sw.platecabinet.utils.SoundPoolUtil
@@ -53,7 +51,6 @@ import com.sw.platecabinet.utils.SpTool
import org.greenrobot.eventbus.EventBus
import org.greenrobot.eventbus.Subscribe
import org.greenrobot.eventbus.ThreadMode
import org.json.JSONObject
import timber.log.Timber
import java.util.concurrent.atomic.AtomicBoolean
@@ -98,15 +95,14 @@ class LoginByFaceActivity : BaseActivity<ActivityLoginFaceBinding>(),
override fun initialize() {
instance = this
viewModel.activeEngine()
addSocketListener()
userViewModel.activeEngine()
// addSocketListener()
initCountTime()
initArcViewModel()
initArcView()
openRectInfoDraw = true
recognizeViewModel.setDrawRectInfoTextValue(true)
//viewModel.generateToken()
// viewModel.activeEngine()
// binding.llToPwd.setOnClickListener {
// val intent = Intent(this, LoginByPwdActivity::class.java)
@@ -141,6 +137,8 @@ class LoginByFaceActivity : BaseActivity<ActivityLoginFaceBinding>(),
// }
// }
//开启人脸增量数据定时任务
startFaceTask()
val soundMap = hashMapOf<String, Int>()
soundMap[COLLECT_SUCCESS] = R.raw.collect_success
@@ -193,11 +191,11 @@ class LoginByFaceActivity : BaseActivity<ActivityLoginFaceBinding>(),
if (this.userFaceInfo == null && userFaceInfo != null) {
recognizeViewModel.updateRegisterStatus(RecognizeViewModel.REGISTER_STATUS_DONE)
this.userFaceInfo = userFaceInfo
getFaceDataBlock { faceData ->
getFaceDataBlock { faceData, headBmp ->
isCollecting.set(false)
isCollectFace = false
Thread {
saveFaceInfo(faceData)
sendFaceData(faceData, headBmp)
}.start()
}
return@setOnRegisterFinishedCallback
@@ -476,8 +474,6 @@ class LoginByFaceActivity : BaseActivity<ActivityLoginFaceBinding>(),
recognizeViewModel.destroy()
EventBus.getDefault().unregister(this)
// getFaceScheduler?.shutdown()
// checkFaceScheduler?.shutdown()
super.onDestroy()
}
@@ -705,7 +701,7 @@ class LoginByFaceActivity : BaseActivity<ActivityLoginFaceBinding>(),
collectCount = 0
tempUserId = "${System.currentTimeMillis()}"
resumeCamera()
viewModel.resetUserInfo()
userViewModel.resetUserInfo()
countDownTimer?.let {
it.cancel()
it.start()
@@ -754,6 +750,9 @@ class LoginByFaceActivity : BaseActivity<ActivityLoginFaceBinding>(),
startActivity(intent)
}
/**
* 采集人脸
*/
private fun collectFace() {
loadLogInfo("collectFace: -----------1,开始采集人脸,开始时间:${DateTimeUtils.getDateTimeString()}----------")
if (isFirstOpen) return
@@ -765,25 +764,43 @@ class LoginByFaceActivity : BaseActivity<ActivityLoginFaceBinding>(),
loadLogInfo("collectFace: ----------5,人脸采集中-----------")
}
private fun sendFaceData(faceData: String) {
/**
* 改为上传人脸数据,不需要发生人脸数据到收银端
*/
private fun sendFaceData(faceData: String, headBmp: Bitmap) {
loadLogInfo("collectFace,sendFaceData: ----------11,发送人脸数据-----------")
// 给某个客户端发送
val jsonObject = JSONObject().also {
it.put("type", "faceFeature")
it.put("content", faceData)
val imageFile = BitmapSaver.saveToAppFilesDir(
headBmp, this, "IMG_CROP_${System.currentTimeMillis()}.jpg"
)
loadLogInfo("collectFace,sendFaceData:${imageFile?.absolutePath}")
if (imageFile == null) {
ToastUtils.showToast("获取人脸照片失败")
return
}
tcpClient?.send(jsonObject)
settingViewModel.addUserFace(faceData, imageFile) { status, faceModel ->
loadLogInfo("collectFace,saveFaceInfo: ----------12,人脸数据发送完成时间:${DateTimeUtils.getDateTimeString()},结果:$status-----------")
if (status.not()) {
ToastUtils.showToast("新增数据失败")
loadLogInfo("collectFace,sendFaceData: ----------12,发送人脸数据失败,faceData=${faceData}")
return@addUserFace
}
if (faceModel == null) {
ToastUtils.showToast("新增数据成功,但未拿到接口数据")
loadLogInfo("collectFace,sendFaceData: ----------12,发送人脸数据成功但接口返回为null,faceData=${faceData}")
return@addUserFace
}
saveFaceInfo(faceModel)
}
// // 给某个客户端发送
// val jsonObject = JSONObject().also {
// it.put("type", "faceFeature")
// it.put("content", faceData)
// }
// tcpClient?.send(jsonObject)
}
// private var getFaceScheduler: ScheduledExecutorService? = null
// private var checkFaceScheduler: ScheduledExecutorService? = null
//
// private fun initFaceScheduler() {
//// getFaceScheduler = Executors.newScheduledThreadPool(1)
// checkFaceScheduler = Executors.newScheduledThreadPool(1)
// }
private fun getFaceDataBlock(block: (String) -> Unit) {
private fun getFaceDataBlock(block: (String, Bitmap) -> Unit) {
if (userFaceInfo == null || userFaceInfo?.faceFeature?.featureData == null) {
return
}
@@ -792,7 +809,7 @@ class LoginByFaceActivity : BaseActivity<ActivityLoginFaceBinding>(),
return
}
loadLogInfo("collectFace,getFaceData: ----------7,拿到人脸提取特征数据时间:${DateTimeUtils.getDateTimeString()}-----------")
block(faceData)
block(faceData, userFaceInfo!!.headBmp)
}
/**
@@ -801,7 +818,7 @@ class LoginByFaceActivity : BaseActivity<ActivityLoginFaceBinding>(),
*/
private fun loadLogInfo(msg: String) {
Timber.tag(TAG).d(msg)
FileUtil.saveLog(msg)
LogFileUtil.saveLog(msg)
}
private var facePreviewInfoList: MutableList<FacePreviewInfo>? = null
@@ -809,23 +826,17 @@ class LoginByFaceActivity : BaseActivity<ActivityLoginFaceBinding>(),
private var currentUserId: String? = null
private fun saveFaceInfo(faceData: String) {
private fun saveFaceInfo(faceModel: UserFaceModel) {
try {
sendFaceData(faceData)
loadLogInfo("collectFace,saveFaceInfo: ----------12,人脸数据发送完成时间:${DateTimeUtils.getDateTimeString()}-----------")
// runOnUiThread {
// openPlate(tempUserId)
// }
loadLogInfo("collectFace,saveFaceInfo: ----------8,保存人脸取特征数据-----------")
val faceDao = FaceDatabase.getInstance(this).faceDao()
val faceEntity = FaceEntity(
tempUserId,
faceModel.userId,
null,
Base64.decode(faceData)
Base64.decode(faceModel.faceFeatureStr)
).also {
it.userType = "2"
//1-会员、2-临时用户
it.userType = if (faceModel.isMember) "1" else "2"
}
faceDao.insert(faceEntity)
loadLogInfo("collectFace,saveFaceInfo: ----------10,人脸数据保存完成-----------")
@@ -843,70 +854,70 @@ class LoginByFaceActivity : BaseActivity<ActivityLoginFaceBinding>(),
}
}
private var collectCount = 0;
private var collectCount = 0
private var tcpClient: TcpClient? = null
private fun addSocketListener() {
// val ipAddress = NetworkUtils.getIPAddress(true)
// loadLogInfo( "addSocketListener,ipAddress: $ipAddress");
tcpClient = TcpClient(
"192.168.1.95",
5000,
GlobalData.deviceId, // clientId
5000, // connectTimeoutMs
10 * 1000, // heartbeatIntervalMs
30 * 1000 // heartbeatTimeoutMs
)
tcpClient?.setListener(object : TcpClientListenerImpl() {
override fun onSendSuccess(json: JSONObject?) {
super.onSendSuccess(json)
loadLogInfo("collectFace,TcpClientListener发送成功:$json")
// toast("发送成功")
}
override fun onSendFailed(json: JSONObject?, e: java.lang.Exception?) {
super.onSendFailed(json, e)
ToastUtils.showToast("发送失败${e?.message}")
loadLogInfo("collectFace,TcpClientListener人脸数据发送失败:${e?.message}")
}
override fun onMessage(json: JSONObject?) {
super.onMessage(json)
loadLogInfo("collectFace,TcpClientListener收到消息:$json")
val type = json?.getInt("type")
// 根据服务端消息类型处理删除新增临时用户人脸数据---------------------
when (type) {
LanServer.TYPE_ADD_FACE_DATA -> {
//采集设备id自己生成,不接收服务端的,在本地只判断是否存在同一人脸数据
loadLogInfo("collectFace,TcpClientListener收到消息,新增用户:采集设备id自己生成,不接收服务端的,在本地只判断是否存在同一人脸数据")
}
LanServer.TYPE_CLEAR_FACE_DATA -> {
clearFaceData()
}
else -> {}
}
}
})
tcpClient?.start()
try {
LanServer.getInstance().let {
it.setListener(object : LanServerListenerImpl() {
override fun onMessageReceived(clientId: String?, message: JSONObject?) {
super.onMessageReceived(clientId, message)
ToastUtils.showToast("收到消息clientId=$clientId")
}
})
it.start()
}
} catch (e: Exception) {
e.printStackTrace()
}
}
// private var tcpClient: TcpClient? = null
//
// private fun addSocketListener() {
//// val ipAddress = NetworkUtils.getIPAddress(true)
//// loadLogInfo( "addSocketListener,ipAddress: $ipAddress");
// tcpClient = TcpClient(
// "192.168.1.95",
// 5000,
// GlobalData.deviceId, // clientId
// 5000, // connectTimeoutMs
// 10 * 1000, // heartbeatIntervalMs
// 30 * 1000 // heartbeatTimeoutMs
// )
//
// tcpClient?.setListener(object : TcpClientListenerImpl() {
// override fun onSendSuccess(json: JSONObject?) {
// super.onSendSuccess(json)
// loadLogInfo("collectFace,TcpClientListener发送成功:$json")
//// toast("发送成功")
// }
//
// override fun onSendFailed(json: JSONObject?, e: java.lang.Exception?) {
// super.onSendFailed(json, e)
// ToastUtils.showToast("发送失败${e?.message}")
// loadLogInfo("collectFace,TcpClientListener人脸数据发送失败:${e?.message}")
// }
//
// override fun onMessage(json: JSONObject?) {
// super.onMessage(json)
// loadLogInfo("collectFace,TcpClientListener收到消息:$json")
// val type = json?.getInt("type")
// // 根据服务端消息类型处理删除新增临时用户人脸数据---------------------
// when (type) {
// LanServer.TYPE_ADD_FACE_DATA -> {
// //采集设备id自己生成,不接收服务端的,在本地只判断是否存在同一人脸数据
// loadLogInfo("collectFace,TcpClientListener收到消息,新增用户:采集设备id自己生成,不接收服务端的,在本地只判断是否存在同一人脸数据")
// }
//
// LanServer.TYPE_CLEAR_FACE_DATA -> {
// clearFaceData()
// }
//
// else -> {}
// }
// }
// })
// tcpClient?.start()
//
// try {
// LanServer.getInstance().let {
// it.setListener(object : LanServerListenerImpl() {
// override fun onMessageReceived(clientId: String?, message: JSONObject?) {
// super.onMessageReceived(clientId, message)
// ToastUtils.showToast("收到消息clientId=$clientId")
// }
// })
// it.start()
// }
// } catch (e: Exception) {
// e.printStackTrace()
// }
// }
private fun clearFaceData() {
Thread {
@@ -917,34 +928,6 @@ class LoginByFaceActivity : BaseActivity<ActivityLoginFaceBinding>(),
}.start()
}
// private val WAITING_TIME = 3 * 1000L
// private var checkStartTime = 0L
private fun checkFaceState() {
// checkStartTime = System.currentTimeMillis()
//
// checkFaceScheduler?.scheduleWithFixedDelay(
// {
// checkFaceBlock()
// }, 5L, 5L, TimeUnit.MILLISECONDS
// )
}
private var isCollectFace = false
// private fun checkFaceBlock() {
// loadLogInfo("collectFace,currentUserId=${currentUserId}")
// if (currentUserId.isNullOrBlank().not()) {
// isCollectFace = false
//
// checkFaceScheduler?.shutdown()
// return
// }
//// if (System.currentTimeMillis() - checkStartTime >= WAITING_TIME) {
//// //超过1秒采集人脸并识别
//// checkFaceScheduler?.shutdown()
//// isCollectFace = true
//// collectFace()
//// }
// }
}