diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml
index 67ce82d..c9400bd 100644
--- a/app/src/main/AndroidManifest.xml
+++ b/app/src/main/AndroidManifest.xml
@@ -33,17 +33,21 @@
android:name=".activity.LoginByPwdActivity"
android:exported="true"
android:launchMode="singleTask">
-
-
+
+
-
-
+
+
+
+
+
+
: AppCompatActivity() {
// 确保内容延伸到导航栏区域
// WindowCompat.setDecorFitsSystemWindows(window, false)
+ //保持亮屏
+ window.addFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON)
+
binding = inflateViewBinding()
headerBinding = inflateTitleBinding()
setContentView(binding.root)
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 8f4770a..de989a5 100644
--- a/app/src/main/java/com/sw/platecabinet/activity/LoginByFaceActivity.kt
+++ b/app/src/main/java/com/sw/platecabinet/activity/LoginByFaceActivity.kt
@@ -60,8 +60,7 @@ class LoginByFaceActivity : BaseActivity(),
}
override fun initialize() {
-
-// viewModel.activeEngine()
+ viewModel.activeEngine()
initArcViewModel()
initArcView()
openRectInfoDraw = true
@@ -156,6 +155,10 @@ class LoginByFaceActivity : BaseActivity(),
Timber.i("recognizeUserId observe userId = $userId")
viewModel.getUserInfoById(memberId = userId?.toInt() ?: 0)
})
+
+ recognizeViewModel.drawRectInfoText.observe(this, Observer { info ->
+ Timber.i("drawRectInfoText observe info = $info")
+ })
}
private fun initArcView() {
@@ -250,8 +253,10 @@ class LoginByFaceActivity : BaseActivity(),
val layoutParams = adjustPreviewViewSize(
binding.dualCameraTexturePreviewRgb,
binding.dualCameraTexturePreviewRgb, binding.dualCameraFaceRectView,
- previewSizeRgb, displayOrientation, 1.0f
+ previewSizeRgb, displayOrientation, 1f
)
+ Timber.d("initRgbCamera previewSizeRgb = ${previewSizeRgb.width}-${previewSizeRgb.height}")
+ Timber.d("initRgbCamera layoutParams = ${layoutParams.width}-${layoutParams.height}")
rgbFaceRectTransformer = FaceRectTransformer(
previewSizeRgb.width,
previewSizeRgb.height,
@@ -269,7 +274,6 @@ class LoginByFaceActivity : BaseActivity(),
})
}
-
@RequiresApi(api = Build.VERSION_CODES.Q)
override fun onPreview(nv21: ByteArray?, camera: Camera?) {
if (!isRecognition) {
@@ -322,7 +326,6 @@ class LoginByFaceActivity : BaseActivity(),
rgbCameraHelper!!.start()
}
-
/**
* 绘制RGB、IR画面的实时人脸信息
*
@@ -337,7 +340,6 @@ class LoginByFaceActivity : BaseActivity(),
)
// 识别成功
binding.dualCameraFaceRectView.drawRealtimeFaceInfo(rgbDrawInfoList)
-
}
}
diff --git a/app/src/main/java/com/sw/platecabinet/activity/LoginByPwdActivity.kt b/app/src/main/java/com/sw/platecabinet/activity/LoginByPwdActivity.kt
index 44c7501..3fb98d0 100644
--- a/app/src/main/java/com/sw/platecabinet/activity/LoginByPwdActivity.kt
+++ b/app/src/main/java/com/sw/platecabinet/activity/LoginByPwdActivity.kt
@@ -4,6 +4,7 @@ import android.content.Intent
import androidx.activity.viewModels
import androidx.lifecycle.lifecycleScope
import com.sw.plate.utils.ToastUtils
+import com.sw.plate.utils.arcface.face.Test
import com.sw.platecabinet.databinding.ActivityLoginByPwdBinding
import com.sw.platecabinet.databinding.ItemTitleTimeBinding
import com.sw.platecabinet.viewmodel.UserViewModel
@@ -28,6 +29,11 @@ class LoginByPwdActivity : BaseActivity() {
val pwd = binding.etPwd.text.toString()
if (phone.isEmpty() || pwd.isEmpty()) {
ToastUtils.showToast("手机或校验码不能为空")
+ val test = Test()
+ for (i in 1..1000) {
+ test.test1()
+ }
+
return@setOnClickListener
}
viewModel.loginWithPwd(phone = phone, password = pwd)
diff --git a/app/src/main/java/com/sw/platecabinet/viewmodel/UserViewModel.kt b/app/src/main/java/com/sw/platecabinet/viewmodel/UserViewModel.kt
index 6a902e1..983be92 100644
--- a/app/src/main/java/com/sw/platecabinet/viewmodel/UserViewModel.kt
+++ b/app/src/main/java/com/sw/platecabinet/viewmodel/UserViewModel.kt
@@ -14,8 +14,10 @@ import com.sw.platecabinet.model.request.LoginParam
import com.sw.platecabinet.model.response.EquipmentUserInfo
import com.sw.platecabinet.model.response.UserFaceModel
import com.sw.platecabinet.utils.ThreadUtils
+import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.flow.MutableStateFlow
import kotlinx.coroutines.flow.StateFlow
+import kotlinx.coroutines.withContext
import timber.log.Timber
class UserViewModel : BaseViewModel() {
@@ -55,8 +57,10 @@ class UserViewModel : BaseViewModel() {
val faceEntity = list.map {
FaceEntity(it.userId, null, Base64.decode(it.faceFeatureString))
}
- faceApi.updateFaceData(index, faceEntity)
- activeEngine()
+ withContext(Dispatchers.Default) {
+ faceApi.updateFaceData(index, faceEntity)
+ activeEngine()
+ }
}
}
}
diff --git a/app/src/main/res/drawable/bg.png b/app/src/main/res/drawable/bg.png
new file mode 100644
index 0000000..6794388
Binary files /dev/null and b/app/src/main/res/drawable/bg.png differ
diff --git a/app/src/main/res/drawable/bg_face.png b/app/src/main/res/drawable/bg_face.png
new file mode 100644
index 0000000..b280fc3
Binary files /dev/null and b/app/src/main/res/drawable/bg_face.png differ
diff --git a/app/src/main/res/drawable/ic_bind_img.png b/app/src/main/res/drawable/ic_bind_img.png
new file mode 100644
index 0000000..7a9de74
Binary files /dev/null and b/app/src/main/res/drawable/ic_bind_img.png differ
diff --git a/app/src/main/res/drawable/ic_full.png b/app/src/main/res/drawable/ic_full.png
new file mode 100644
index 0000000..1c22e16
Binary files /dev/null and b/app/src/main/res/drawable/ic_full.png differ
diff --git a/app/src/main/res/drawable/ic_phone.png b/app/src/main/res/drawable/ic_phone.png
new file mode 100644
index 0000000..8a61218
Binary files /dev/null and b/app/src/main/res/drawable/ic_phone.png differ
diff --git a/app/src/main/res/drawable/ic_plate_open.png b/app/src/main/res/drawable/ic_plate_open.png
new file mode 100644
index 0000000..a6c3bb2
Binary files /dev/null and b/app/src/main/res/drawable/ic_plate_open.png differ
diff --git a/app/src/main/res/drawable/ic_pwd.png b/app/src/main/res/drawable/ic_pwd.png
new file mode 100644
index 0000000..4f8d609
Binary files /dev/null and b/app/src/main/res/drawable/ic_pwd.png differ
diff --git a/app/src/main/res/drawable/ic_unbind_img.png b/app/src/main/res/drawable/ic_unbind_img.png
new file mode 100644
index 0000000..725766c
Binary files /dev/null and b/app/src/main/res/drawable/ic_unbind_img.png differ
diff --git a/app/src/main/res/layout/activity_login_by_pwd.xml b/app/src/main/res/layout/activity_login_by_pwd.xml
index 7ea4e15..5116f4e 100644
--- a/app/src/main/res/layout/activity_login_by_pwd.xml
+++ b/app/src/main/res/layout/activity_login_by_pwd.xml
@@ -2,7 +2,7 @@
+ android:src="@drawable/ic_phone" />
+ android:src="@drawable/ic_pwd" />
+
-
-
-
-
-
+
-
+
-
-
+
+
-
-
-
-
-
-
-
+ android:background="@drawable/bg_face" />
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/app/src/main/res/layout/activity_main.xml b/app/src/main/res/layout/activity_main.xml
index 3e22785..f5200d5 100644
--- a/app/src/main/res/layout/activity_main.xml
+++ b/app/src/main/res/layout/activity_main.xml
@@ -5,7 +5,7 @@
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
- android:background="#14141E"
+ android:background="@drawable/bg"
tools:context=".activity.MainActivity">
+ android:src="@drawable/ic_bind_img" />
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:src="@drawable/ic_full" />
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:src="@drawable/ic_plate_open" />
+ android:src="@drawable/ic_unbind_img" />
#F0C8B4
#F0C8B4
#32283C
+
+ #4c91ceff
\ No newline at end of file
diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml
index f000453..a82b98a 100644
--- a/app/src/main/res/values/strings.xml
+++ b/app/src/main/res/values/strings.xml
@@ -4,4 +4,5 @@
Hello blank fragment
%s 初始化失败,错误码:%d\n错误码常量名:%s
+ 权限被拒绝!
\ 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 67c4d41..c8424d9 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.util.Log;
import com.arcsoft.face.FaceEngine;
import com.arcsoft.face.enums.RuntimeABI;
@@ -14,6 +15,8 @@ import com.sw.plate.utils.arcface.facedb.entity.FaceEntity;
import java.util.List;
public class FaceApi {
+ private static final String TAG = "FaceApi";
+
public interface ActiveCallback {
void onSuccess(int code);
@@ -27,12 +30,12 @@ public class FaceApi {
* @param list
*/
public void updateFaceData(int index, List list) {
+ Log.d(TAG, "updateFaceData: index = " + index + ", listSize = " + list.size());
FaceDao faceDao = FaceDatabase.getInstance(App.getContext()).faceDao();
if (index == 0) {
faceDao.deleteAll();
faceDao.resetId();
}
-
faceDao.insert(list);
}
diff --git a/lib_face/src/main/java/com/sw/plate/utils/arcface/face/FaceHelper.java b/lib_face/src/main/java/com/sw/plate/utils/arcface/face/FaceHelper.java
index 3f78375..411fdf1 100644
--- a/lib_face/src/main/java/com/sw/plate/utils/arcface/face/FaceHelper.java
+++ b/lib_face/src/main/java/com/sw/plate/utils/arcface/face/FaceHelper.java
@@ -2,6 +2,8 @@ package com.sw.plate.utils.arcface.face;
import android.graphics.Rect;
import android.hardware.Camera;
+import android.os.Handler;
+import android.os.Looper;
import android.util.Log;
import androidx.annotation.IntDef;
@@ -47,7 +49,6 @@ import java.util.concurrent.ThreadPoolExecutor;
import java.util.concurrent.TimeUnit;
import io.reactivex.Observable;
-import io.reactivex.Observer;
import io.reactivex.android.schedulers.AndroidSchedulers;
import io.reactivex.disposables.CompositeDisposable;
import io.reactivex.disposables.Disposable;
@@ -529,7 +530,7 @@ public class FaceHelper implements FaceListener {
if (recognizeInfoMap.containsKey(trackId)) {
onFaceFeatureInfoGet(faceFeature, trackId, errorCode);
}
- } catch (InterruptedException e) {
+ } catch (Exception e) {
Log.e(TAG, "onFaceFeatureInfoGet: 等待活体结果时退出界面会执行,正常现象,可注释异常代码块");
e.printStackTrace();
}
@@ -549,40 +550,35 @@ public class FaceHelper implements FaceListener {
}
}
+
+ // 定义一个Handler,用于处理延迟任务
+ private Handler delayHandler = new Handler(Looper.getMainLooper());
+
/**
* 延迟 {@link RecognizeConfiguration#getLivenessFailedRetryInterval()}后,重新进行活体检测
*
* @param trackId 人脸ID
*/
private void retryLivenessDetectDelayed(final Integer trackId) {
- Observable.timer(recognizeConfiguration.getLivenessFailedRetryInterval(), TimeUnit.MILLISECONDS)
- .observeOn(AndroidSchedulers.mainThread())
- .subscribe(new Observer() {
- Disposable disposable;
+ Log.d(TAG, "retryLivenessDetectDelayed: trackId = " + trackId + ", threadName =" + Thread.currentThread().getName());
+ Log.d(TAG, "retryLivenessDetectDelayed: Interval = " + recognizeConfiguration.getLivenessFailedRetryInterval());
- @Override
- public void onSubscribe(Disposable d) {
- disposable = d;
- delayFaceTaskCompositeDisposable.add(disposable);
- }
+ // 创建延迟任务
+ Runnable delayTask = new Runnable() {
+ @Override
+ public void run() {
+ // 将该人脸状态置为UNKNOWN,帧回调处理时会重新进行活体检测
+ changeLiveness(trackId, LivenessInfo.UNKNOWN);
+ // 从集合中移除这个任务
+ delayFaceTaskList.remove(this);
+ }
+ };
- @Override
- public void onNext(Long aLong) {
+ // 将任务添加到集合中管理
+ delayFaceTaskList.add(delayTask);
- }
-
- @Override
- public void onError(Throwable e) {
- e.printStackTrace();
- }
-
- @Override
- public void onComplete() {
- // 将该人脸状态置为UNKNOWN,帧回调处理时会重新进行活体检测
- changeLiveness(trackId, LivenessInfo.UNKNOWN);
- delayFaceTaskCompositeDisposable.remove(disposable);
- }
- });
+ // 发送延迟任务
+ delayHandler.postDelayed(delayTask, recognizeConfiguration.getLivenessFailedRetryInterval());
}
/**
@@ -591,40 +587,33 @@ public class FaceHelper implements FaceListener {
* @param trackId 人脸ID
*/
private void retryRecognizeDelayed(final Integer trackId) {
+ Log.d(TAG, "retryRecognizeDelayed: trackId = " + trackId);
changeRecognizeStatus(trackId, RequestFeatureStatus.FAILED);
- Observable.timer(recognizeConfiguration.getRecognizeFailedRetryInterval(), TimeUnit.MILLISECONDS)
- .observeOn(AndroidSchedulers.mainThread())
- .subscribe(new Observer() {
- Disposable disposable;
- @Override
- public void onSubscribe(Disposable d) {
- disposable = d;
- delayFaceTaskCompositeDisposable.add(disposable);
- }
+ // 创建延迟任务
+ Runnable delayTask = new Runnable() {
+ @Override
+ public void run() {
+ // 将该人脸特征提取状态置为FAILED,帧回调处理时会重新进行活体检测
+ changeRecognizeStatus(trackId, RequestFeatureStatus.TO_RETRY);
+ // 从集合中移除这个任务
+ delayFaceTaskList.remove(this);
+ }
+ };
- @Override
- public void onNext(Long aLong) {
+ // 将任务添加到集合中管理
+ delayFaceTaskList.add(delayTask);
- }
-
- @Override
- public void onError(Throwable e) {
- Log.e(TAG, "retryRecognizeDelayed e = " + e);
- e.printStackTrace();
- }
-
- @Override
- public void onComplete() {
- // 将该人脸特征提取状态置为FAILED,帧回调处理时会重新进行活体检测
- changeRecognizeStatus(trackId, RequestFeatureStatus.TO_RETRY);
- delayFaceTaskCompositeDisposable.remove(disposable);
- }
- });
+ // 发送延迟任务
+ delayHandler.postDelayed(delayTask, recognizeConfiguration.getRecognizeFailedRetryInterval());
}
+ // 需要在类中定义一个集合来管理所有的延迟任务,替代原来的CompositeDisposable
+ private List delayFaceTaskList = new ArrayList<>();
+
@Override
public void onFaceLivenessInfoGet(@Nullable LivenessInfo livenessInfo, Integer trackId, Integer errorCode) {
+ Log.d(TAG, "onFaceLivenessInfoGet: trackId = " + trackId);
if (livenessInfo != null) {
int liveness = livenessInfo.getLiveness();
Log.i(TAG, "onFaceLivenessInfoGet liveness:" + liveness);
diff --git a/lib_face/src/main/java/com/sw/plate/utils/arcface/face/Test.java b/lib_face/src/main/java/com/sw/plate/utils/arcface/face/Test.java
new file mode 100644
index 0000000..535f2f8
--- /dev/null
+++ b/lib_face/src/main/java/com/sw/plate/utils/arcface/face/Test.java
@@ -0,0 +1,49 @@
+package com.sw.plate.utils.arcface.face;
+
+
+import android.util.Log;
+
+import java.util.concurrent.TimeUnit;
+
+import io.reactivex.Observable;
+import io.reactivex.Observer;
+import io.reactivex.android.schedulers.AndroidSchedulers;
+import io.reactivex.disposables.CompositeDisposable;
+import io.reactivex.disposables.Disposable;
+
+public class Test {
+
+ private static final String TAG = "Test";
+ private CompositeDisposable delayFaceTaskCompositeDisposable = new CompositeDisposable();
+
+ public void test1() {
+ Log.d(TAG, "test1: ");
+ Observable.timer(10, TimeUnit.MILLISECONDS)
+ .observeOn(AndroidSchedulers.mainThread())
+ .subscribe(new Observer() {
+ Disposable disposable;
+
+ @Override
+ public void onSubscribe(Disposable d) {
+ disposable = d;
+ delayFaceTaskCompositeDisposable.add(disposable);
+ }
+
+ @Override
+ public void onNext(Long value) {
+
+ }
+
+ @Override
+ public void onError(Throwable e) {
+ e.printStackTrace();
+ }
+
+ @Override
+ public void onComplete() {
+ Log.d(TAG, "onComplete: ");
+ delayFaceTaskCompositeDisposable.remove(disposable);
+ }
+ });
+ }
+}
diff --git a/lib_face/src/main/java/com/sw/plate/utils/arcface/facedb/FaceDatabase.java b/lib_face/src/main/java/com/sw/plate/utils/arcface/facedb/FaceDatabase.java
index 1e87446..ddb985f 100644
--- a/lib_face/src/main/java/com/sw/plate/utils/arcface/facedb/FaceDatabase.java
+++ b/lib_face/src/main/java/com/sw/plate/utils/arcface/facedb/FaceDatabase.java
@@ -9,8 +9,6 @@ import androidx.room.RoomDatabase;
import com.sw.plate.utils.arcface.facedb.dao.FaceDao;
import com.sw.plate.utils.arcface.facedb.entity.FaceEntity;
-import java.io.File;
-
@Database(entities = {FaceEntity.class}, version = 1, exportSchema = false)
public abstract class FaceDatabase extends RoomDatabase {
public abstract FaceDao faceDao();
@@ -22,7 +20,9 @@ public abstract class FaceDatabase extends RoomDatabase {
synchronized (FaceDatabase.class) {
if (faceDatabase == null) {
faceDatabase = Room.databaseBuilder(context, FaceDatabase.class,
- context.getExternalFilesDir("database") + File.separator + "faceDB.db").build();
+ context.getDatabasePath("faceDB.db").getPath()
+// context.getExternalFilesDir("database") + File.separator + "faceDB.db"
+ ).build();
}
}
}
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 e414751..6a9db10 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
@@ -4,7 +4,6 @@ import android.annotation.SuppressLint;
import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.Rect;
-import android.os.Environment;
import android.util.Log;
import com.arcsoft.face.ErrorInfo;
@@ -354,8 +353,11 @@ public class FaceServer {
* @return 存放注册照的文件夹路径
*/
private String getImageDir() {
- return App.getContext().getExternalFilesDir(Environment.DIRECTORY_PICTURES)
- + File.separator + "faceDB" + File.separator + "registerFaces";
+// return App.getContext().getExternalFilesDir(Environment.DIRECTORY_PICTURES)
+// + File.separator + "faceDB" + File.separator + "registerFaces";
+ return App.getContext().getFilesDir()
+ + File.separator + "faceDB"
+ + File.separator + "registerFaces";
}
/**