From e9a366b52ae06610d4c7239626169d62118090e5 Mon Sep 17 00:00:00 2001 From: lvmeng <848755140@qq.com> Date: Tue, 9 Sep 2025 15:59:29 +0800 Subject: [PATCH] =?UTF-8?q?=E5=A2=9E=E5=8A=A0=E5=BF=83=E8=B7=B3=E5=A4=84?= =?UTF-8?q?=E7=90=86=E4=BA=BA=E8=84=B8=E6=95=B0=E6=8D=AE=E5=A2=9E=E5=87=8F?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- app/build.gradle.kts | 2 + .../activity/LoginByFaceActivity.kt | 4 + .../com/sw/platecabinet/network/ApiClient.kt | 2 +- .../sw/platecabinet/network/api/ApiService.kt | 8 ++ .../network/task/HeartBeatTask.kt | 81 +++++++++++++++++++ .../platecabinet/network/task/TaskManager.kt | 26 ++++++ .../repository/RemoteRepository.kt | 9 +++ .../com/sw/plate/utils/arcface/FaceApi.java | 23 ++++++ .../utils/arcface/facedb/dao/FaceDao.java | 3 + .../arcface/facedb/entity/FaceEntity.java | 1 - .../utils/arcface/faceserver/FaceServer.java | 4 + 11 files changed, 161 insertions(+), 2 deletions(-) create mode 100644 app/src/main/java/com/sw/platecabinet/network/task/HeartBeatTask.kt create mode 100644 app/src/main/java/com/sw/platecabinet/network/task/TaskManager.kt diff --git a/app/build.gradle.kts b/app/build.gradle.kts index b5ddeba..ef303cd 100644 --- a/app/build.gradle.kts +++ b/app/build.gradle.kts @@ -93,4 +93,6 @@ dependencies { implementation(libs.androidx.activity.ktx) implementation(libs.androidx.fragment.ktx) // implementation(libs.adapter.coroutines) + + implementation("androidx.work:work-runtime-ktx:2.8.1") } \ 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 69d9283..1a412a9 100644 --- a/app/src/main/java/com/sw/platecabinet/activity/LoginByFaceActivity.kt +++ b/app/src/main/java/com/sw/platecabinet/activity/LoginByFaceActivity.kt @@ -31,6 +31,7 @@ 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.network.task.TaskManager import com.sw.platecabinet.utils.PermissionHelper import timber.log.Timber @@ -79,6 +80,9 @@ class LoginByFaceActivity : BaseActivity(), val intent = Intent(this, LoginByPwdActivity::class.java) startActivity(intent) } + + // TODO: 测试请求 + TaskManager.startTask() } private fun checkCameraPermission() { diff --git a/app/src/main/java/com/sw/platecabinet/network/ApiClient.kt b/app/src/main/java/com/sw/platecabinet/network/ApiClient.kt index 6a069eb..9785b37 100644 --- a/app/src/main/java/com/sw/platecabinet/network/ApiClient.kt +++ b/app/src/main/java/com/sw/platecabinet/network/ApiClient.kt @@ -16,7 +16,7 @@ object ApiClient { // private const val BASE_URL = "http://192.168.1.8:9092" private const val TIME_OUT = 30L // 超时时间(秒) - private val okHttpClient = OkHttpClient.Builder() + val okHttpClient = OkHttpClient.Builder() .connectTimeout(TIME_OUT, TimeUnit.SECONDS) .readTimeout(TIME_OUT, TimeUnit.SECONDS) .writeTimeout(TIME_OUT, TimeUnit.SECONDS) diff --git a/app/src/main/java/com/sw/platecabinet/network/api/ApiService.kt b/app/src/main/java/com/sw/platecabinet/network/api/ApiService.kt index 585b847..37e9beb 100644 --- a/app/src/main/java/com/sw/platecabinet/network/api/ApiService.kt +++ b/app/src/main/java/com/sw/platecabinet/network/api/ApiService.kt @@ -63,4 +63,12 @@ interface ApiService { */ @POST("/shuwei-zhct/swEquipmentRelUser/findByPlateNumber") suspend fun findByPlateNumber(@Body param: BindParam): ApiResponse + + /** + * 获取人脸增量数据 + * + * @param timeDate 时间戳(毫秒级) + */ + @GET("/shuwei-zhct/scales/getHeartbeatInterface") + suspend fun getHeartbeatInterface(@Query("timeDate") timeDate: Long): ApiResponse> } \ No newline at end of file diff --git a/app/src/main/java/com/sw/platecabinet/network/task/HeartBeatTask.kt b/app/src/main/java/com/sw/platecabinet/network/task/HeartBeatTask.kt new file mode 100644 index 0000000..7ca6c6c --- /dev/null +++ b/app/src/main/java/com/sw/platecabinet/network/task/HeartBeatTask.kt @@ -0,0 +1,81 @@ +package com.sw.platecabinet.network.task + +import android.content.Context +import android.util.Log +import androidx.work.CoroutineWorker +import androidx.work.WorkerParameters +import com.arcsoft.face.FaceEngine +import com.sw.inbound.utils.GsonUtils +import com.sw.plate.utils.Base64 +import com.sw.plate.utils.arcface.FaceApi +import com.sw.plate.utils.arcface.facedb.entity.FaceEntity +import com.sw.plate.utils.arcface.faceserver.FaceServer +import com.sw.platecabinet.network.ApiClient +import com.sw.platecabinet.repository.RemoteRepository +import kotlinx.coroutines.Dispatchers +import kotlinx.coroutines.withContext + +class HeartBeatTask(appContext: Context, workerParams: WorkerParameters) : + CoroutineWorker(appContext, workerParams) { + + companion object { + private const val TAG = "HeartBeatTask" + } + + override suspend fun doWork(): Result { + return try { + // 执行后台任务逻辑 + performSync() + + TaskManager.startTask() + + Result.success() + } catch (e: Exception) { + e.printStackTrace() + Result.retry() + } + } + + private val repository: RemoteRepository by lazy { + RemoteRepository(ApiClient.apiService) + } + + private val faceApi: FaceApi = FaceApi() + + private suspend fun performSync() { + withContext(Dispatchers.IO) { + val timestamp = System.currentTimeMillis() +// val timestamp = 1757063902000 + val resp = repository.getHeartbeatInterface(timestamp) + Log.d(TAG, "performSync: ${GsonUtils.toJson(resp)}") + val list = resp.data + if (list.isNullOrEmpty()) { + return@withContext + } + val faceServer = FaceServer.getInstance() + val faceEngine: FaceEngine? = faceServer.faceEngine + + list.forEach { + try { + if (it.faceType == "0") { + if (it.userId.isNullOrBlank().not()) { + //userId非空,根据userId删除人脸数据 + faceApi.deleteByUserName(it.userId) + faceEngine?.removeFaceFeature(it.userId.toInt()) + } + } else if (it.faceType == "1") { + //新增人脸数据 + val featureData = Base64.decode(it.faceFeatureString) + val insertEntity = FaceEntity(it.userId, null, featureData) + val faceId = faceApi.insert(insertEntity) + insertEntity.faceId = faceId + faceServer.registerFaceFeatureInfoFromDb( insertEntity, faceEngine) + } + } catch (e: Exception) { + e.printStackTrace() + } + } + } + } + +} \ No newline at end of file diff --git a/app/src/main/java/com/sw/platecabinet/network/task/TaskManager.kt b/app/src/main/java/com/sw/platecabinet/network/task/TaskManager.kt new file mode 100644 index 0000000..6678b7a --- /dev/null +++ b/app/src/main/java/com/sw/platecabinet/network/task/TaskManager.kt @@ -0,0 +1,26 @@ +package com.sw.platecabinet.network.task + +import androidx.work.ExistingWorkPolicy +import androidx.work.OneTimeWorkRequestBuilder +import androidx.work.WorkManager +import com.sw.plate.App +import java.util.concurrent.TimeUnit + +object TaskManager { + private const val TASK_NAME = "SmartPlateCabinetTask" + + fun startTask() { + val nextRequest = OneTimeWorkRequestBuilder() + .setInitialDelay(3, TimeUnit.MINUTES) +// .setInputData(inputData) + .build() + WorkManager.getInstance(App.getContext()) + .enqueueUniqueWork(TASK_NAME, ExistingWorkPolicy.REPLACE, nextRequest) + } + + fun cancelTask() { + WorkManager.getInstance(App.getContext()) + .cancelUniqueWork(TASK_NAME) + } + +} \ No newline at end of file diff --git a/app/src/main/java/com/sw/platecabinet/repository/RemoteRepository.kt b/app/src/main/java/com/sw/platecabinet/repository/RemoteRepository.kt index 4a9880e..b512884 100644 --- a/app/src/main/java/com/sw/platecabinet/repository/RemoteRepository.kt +++ b/app/src/main/java/com/sw/platecabinet/repository/RemoteRepository.kt @@ -76,4 +76,13 @@ class RemoteRepository constructor( suspend fun findByPlateNumber(param: BindParam): ApiResponse { return safeApiCall { apiService.findByPlateNumber(param) } } + + /** + * 获取人脸增量数据 + * + * @param timeDate 时间戳(毫秒级) + */ + suspend fun getHeartbeatInterface(timeDate: Long): ApiResponse> { + return safeApiCall { apiService.getHeartbeatInterface(timeDate) } + } } \ No newline at end of file diff --git a/lib_face/src/main/java/com/sw/plate/utils/arcface/FaceApi.java b/lib_face/src/main/java/com/sw/plate/utils/arcface/FaceApi.java index c8424d9..6af7ba9 100644 --- a/lib_face/src/main/java/com/sw/plate/utils/arcface/FaceApi.java +++ b/lib_face/src/main/java/com/sw/plate/utils/arcface/FaceApi.java @@ -1,6 +1,7 @@ package com.sw.plate.utils.arcface; import android.content.Context; +import android.text.TextUtils; import android.util.Log; import com.arcsoft.face.FaceEngine; @@ -79,4 +80,26 @@ public class FaceApi { // List facePreviewInfoList = recognizeViewModel.onPreviewFrame(nv21, true); return null; } + + public void deleteByUserName(String userName) { + FaceDao faceDao = FaceDatabase.getInstance(App.getContext()).faceDao(); + faceDao.deleteFaceById(userName); + } + + public Long insert(FaceEntity entity) { + if (entity == null) { + return 0L; + } + FaceDao faceDao = FaceDatabase.getInstance(App.getContext()).faceDao(); + return faceDao.insert(entity); + } + + public FaceEntity queryByUserName(String userName) { + if (TextUtils.isEmpty(userName)) { + return null; + } + FaceDao faceDao = FaceDatabase.getInstance(App.getContext()).faceDao(); + return faceDao.queryByUserName(userName); + } + } diff --git a/lib_face/src/main/java/com/sw/plate/utils/arcface/facedb/dao/FaceDao.java b/lib_face/src/main/java/com/sw/plate/utils/arcface/facedb/dao/FaceDao.java index db4d806..9bf100f 100644 --- a/lib_face/src/main/java/com/sw/plate/utils/arcface/facedb/dao/FaceDao.java +++ b/lib_face/src/main/java/com/sw/plate/utils/arcface/facedb/dao/FaceDao.java @@ -88,4 +88,7 @@ public interface FaceDao { @Query("UPDATE sqlite_sequence SET seq = 0 WHERE name ='face'") void resetId(); + + @Query("SELECT * FROM face WHERE user_name = :userName limit 1") + FaceEntity queryByUserName(String userName); } diff --git a/lib_face/src/main/java/com/sw/plate/utils/arcface/facedb/entity/FaceEntity.java b/lib_face/src/main/java/com/sw/plate/utils/arcface/facedb/entity/FaceEntity.java index aac56cb..e32f670 100644 --- a/lib_face/src/main/java/com/sw/plate/utils/arcface/facedb/entity/FaceEntity.java +++ b/lib_face/src/main/java/com/sw/plate/utils/arcface/facedb/entity/FaceEntity.java @@ -43,7 +43,6 @@ public class FaceEntity implements Parcelable { @ColumnInfo(name = "register_time") private long registerTime; - public FaceEntity(String userName, String imagePath, byte[] featureData) { this.userName = userName; this.imagePath = imagePath; diff --git a/lib_face/src/main/java/com/sw/plate/utils/arcface/faceserver/FaceServer.java b/lib_face/src/main/java/com/sw/plate/utils/arcface/faceserver/FaceServer.java index 6a9db10..3c99eed 100644 --- a/lib_face/src/main/java/com/sw/plate/utils/arcface/faceserver/FaceServer.java +++ b/lib_face/src/main/java/com/sw/plate/utils/arcface/faceserver/FaceServer.java @@ -60,6 +60,10 @@ public class FaceServer { faceRegisterInfoList = new ArrayList<>(); } + public FaceEngine getFaceEngine() { + return faceEngine; + } + public static FaceServer getInstance() { if (faceServer == null) { synchronized (FaceServer.class) {