- 在FaceHelper中添加人脸宽度小于200像素时的过滤逻辑,避免远距离识别人脸 - 注释掉LoginByFaceActivity中的重复识别状态判断逻辑 - 在PlcSettingActivity中添加协程支持用于异步处理人脸数据清除操作 - 实现环境切换时清空所有人脸数据并重新获取用户人脸缓存的功能 - 修改UserViewModel中回调逻辑,当第一页无数据时返回false而非true
201 lines
6.3 KiB
Kotlin
201 lines
6.3 KiB
Kotlin
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
|
|
import com.sw.plate.utils.Base64
|
|
import com.sw.plate.utils.ToastUtils
|
|
import com.sw.plate.utils.arcface.FaceApi
|
|
import com.sw.plate.utils.arcface.facedb.entity.FaceEntity
|
|
import com.sw.platecabinet.GlobalData
|
|
import com.sw.platecabinet.GlobalKey
|
|
import com.sw.platecabinet.model.DeviceConfig
|
|
import com.sw.platecabinet.model.response.UserFaceModel
|
|
import com.sw.platecabinet.utils.SpTool
|
|
import kotlinx.coroutines.Dispatchers
|
|
import kotlinx.coroutines.launch
|
|
import kotlinx.coroutines.withContext
|
|
import timber.log.Timber
|
|
import java.io.File
|
|
|
|
/**
|
|
* 用户viewmodel
|
|
*/
|
|
class UserViewModel : BaseViewModel() {
|
|
|
|
companion object {
|
|
const val PAGE_SIZE = 100
|
|
}
|
|
|
|
private val faceApi: FaceApi = FaceApi()
|
|
|
|
|
|
fun getUserFace(
|
|
pageNo: Int,
|
|
pageSize: Int,
|
|
callback: (List<UserFaceModel>) -> Unit
|
|
) {
|
|
launchWithLoading {
|
|
val response = repository.getUserFaceCache(pageNum = pageNo, pageSize = pageSize)
|
|
val status = parseResponse(response)
|
|
if (status) callback(response.data ?: emptyList())
|
|
else emptyList<UserFaceModel>()
|
|
}
|
|
}
|
|
|
|
/**
|
|
* 获取人脸数据
|
|
*/
|
|
fun getUserFaceCache(
|
|
pageNo: Int = 1,
|
|
pageSize: Int = PAGE_SIZE,
|
|
callback: (Boolean, String?) -> Unit = { statue, msg -> }
|
|
) {
|
|
var currentPageNo = pageNo
|
|
launchWithLoading {
|
|
val response = repository.getUserFaceCache(pageNum = pageNo, pageSize = pageSize)
|
|
val status = parseResponse(response)
|
|
if (status.not()) {
|
|
callback(false, response.msg)
|
|
return@launchWithLoading
|
|
}
|
|
// 获取成功一次后缓存状态
|
|
SPUtil.getInstance().put(GlobalKey.KEY_FIRST_RUN, true)
|
|
val list: List<UserFaceModel> = response.data ?: emptyList()
|
|
if (pageNo == 1 && list.isEmpty()) {
|
|
callback(false, "暂无数据")
|
|
return@launchWithLoading
|
|
}
|
|
val faceEntityList = list.map {
|
|
FaceEntity(it.userId, null, Base64.decode(it.faceFeatureStr)).apply {
|
|
userType = if (it.member) "1" else "2"
|
|
}
|
|
}
|
|
withContext(Dispatchers.Default) {
|
|
if (currentPageNo == 1) {
|
|
//第一页数据删除本地数据库
|
|
faceApi.clearFaceData()
|
|
}
|
|
faceApi.updateFaceData(pageNo, faceEntityList)
|
|
if (list.size >= pageSize) {
|
|
faceTimestamp = list.last().faceUpdateTimestamp ?: 0
|
|
currentPageNo++
|
|
getUserFaceCache(
|
|
pageNo = currentPageNo,
|
|
callback = callback
|
|
)
|
|
return@withContext
|
|
}
|
|
if (list.isNotEmpty()) {
|
|
faceTimestamp = list.last().faceUpdateTimestamp ?: 0
|
|
}
|
|
SpTool.lastFaceTimestamp = faceTimestamp
|
|
callback(true, "查询完成")
|
|
}
|
|
}
|
|
}
|
|
|
|
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}")
|
|
}
|
|
}
|
|
})
|
|
}
|
|
|
|
|
|
fun getDeviceConfig(block: (DeviceConfig?) -> Unit) {
|
|
// Timber.tag(TAG).d("getDeviceConfig")
|
|
launch {
|
|
val response = repository.getDeviceConfig()
|
|
if (parseResponse(response)) {
|
|
block(response.data)
|
|
} else {
|
|
block(null)
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
/**
|
|
* 获取人脸数据
|
|
*/
|
|
fun getFaceIncrementList(
|
|
pageNo: Int = 1,
|
|
pageSize: Int = PAGE_SIZE,
|
|
timestamp: Long,
|
|
block: (List<UserFaceModel>) -> Unit
|
|
) {
|
|
launch {
|
|
val response = repository.getFaceIncrementList(
|
|
pageNum = pageNo.toLong(),
|
|
pageSize = pageSize.toLong(),
|
|
timestamp = timestamp
|
|
)
|
|
if (parseResponse(response)) {
|
|
withContext(Dispatchers.Default) {
|
|
val list: List<UserFaceModel> = response.data ?: emptyList()
|
|
block(list)
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
/**
|
|
* 添加人脸数据
|
|
*/
|
|
fun addUserFace(faceData: String, imageFile: File, block: (Boolean, UserFaceModel?) -> Unit) {
|
|
launch {
|
|
val imageResp = repository.uploadImage(imageFile)
|
|
val imageUrl = imageResp.data ?: ""
|
|
if (imageUrl.isBlank()) {
|
|
block(false, null)
|
|
return@launch
|
|
}
|
|
val faceResp = repository.addUserFace(faceData, imageUrl)
|
|
val status = parseResponse(faceResp)
|
|
if (status.not()) {
|
|
block(false, null)
|
|
return@launch
|
|
}
|
|
block(true, faceResp.data)
|
|
}
|
|
}
|
|
|
|
} |