Browse Source

optimize:优化百度人脸:下发队列、摄像头预览等等。

xwh 4 months ago
parent
commit
1dc8b062a0

+ 2 - 2
app/build.gradle

@@ -14,8 +14,8 @@ android {
         applicationId "com.hanghui.senic"
         minSdkVersion 22
         targetSdkVersion 22
-        versionCode 119//115
-        versionName "1.1.9.241009" //1.1.5.241003
+        versionCode 120//115
+        versionName "1.1.9.241010" //1.1.5.241003
         testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
         ndk {
             abiFilters "armeabi-v7a"   //armeabi-v7a 'arm64-v8a'

+ 7 - 0
app/src/main/java/com/hanghui/senic/MyAppliction.java

@@ -40,6 +40,7 @@ public class MyAppliction extends BaseApplication {
     public static BlackListDao blackListDao;
     public static RecentAppsReceiver recentAppsReceiver;
     ArrayList<Activity> list = new ArrayList<Activity>();
+    private static volatile  long appHeartbeatTime=0; //上次上报心跳时间
 
     public static Context getContext() {
         return context;
@@ -249,5 +250,11 @@ public class MyAppliction extends BaseApplication {
         }
     };
 
+    public static long getAppHeartbeatTime() {
+        return appHeartbeatTime;
+    }
 
+    public static void setAppHeartbeatTime(long appHeartbeatTime) {
+        MyAppliction.appHeartbeatTime = appHeartbeatTime;
+    }
 }

+ 1 - 0
app/src/main/java/com/hanghui/senic/baiduface/BaiduFaceMainActivity.java

@@ -363,6 +363,7 @@ public class BaiduFaceMainActivity extends BaseActivity {
         BroadcastManager.getInstance().registerNetworkChangeReceiver(netNetworkCallback);
         BroadcastManager.getInstance().registerUSBroadcastReceiver(usBroadcastCallback);
         PosManager.getInstance().init();
+        MyAppliction.setAppHeartbeatTime(0L);
         //启动应用状态定时上报服务
         RegularReportingService.start(this);
         //ping百度,判断网络连接是否正常

+ 26 - 4
app/src/main/java/com/hanghui/senic/baiduface/BaiduFacePreviewActivity.java

@@ -113,7 +113,7 @@ public class BaiduFacePreviewActivity extends BaiduFaceMainActivity {
     /**
      * 是否需要处理刷脸数据,刷脸成功后,在结果页展示期间是不需要处理刷脸数据的
      */
-    private boolean isNeedVerify = true;
+    private volatile boolean isNeedVerify = true;
 
     private LivenessModel mCurLivenessModel = null;//最新刷到的人脸数据
 
@@ -182,6 +182,7 @@ public class BaiduFacePreviewActivity extends BaiduFaceMainActivity {
             irPreviewView.setRotationY(180);
         }
         mPreview = new BaiduPreviewTexture(this, irPreviewView);
+        BaiduFaceUtil.stopBaiduFaceWebsocketService();
         AppLogUtils.i(true, TAG, "BaiduFaceActivity, onCreate()");
         super.setOnCreate();
     }
@@ -191,7 +192,15 @@ public class BaiduFacePreviewActivity extends BaiduFaceMainActivity {
     public void onPause() {
         super.onPause();
         Log.i(TAG, "BaiduFaceActivity, onPause()");
-        stopCameraPreview();
+        if(mHandler!=null) {
+            mHandler.post(new Runnable() {
+                @Override
+                public void run() {
+                    stopCameraPreview();
+                }
+            });
+        }
+
 
     }
 
@@ -423,10 +432,15 @@ public class BaiduFacePreviewActivity extends BaiduFaceMainActivity {
             irPreviewView.setLayoutParams(layoutParams);
             mPreview.setCamera(mCamera, PREFER_WIDTH, PERFER_HEIGH);
             initNirFaceConfig(PERFER_HEIGH, PREFER_WIDTH);
-            mCamera.setPreviewCallback(new Camera.PreviewCallback() {
+            byte[] buffer=new byte[460800];
+            mCamera.addCallbackBuffer(buffer);
+            mCamera.setPreviewCallbackWithBuffer(new Camera.PreviewCallback() {
                 @Override
                 public void onPreviewFrame(byte[] data, Camera camera) {
-                    dealIr(data);
+                    if(camera!=null) {
+                        camera.addCallbackBuffer(data);
+                        dealIr(data);
+                    }
                 }
             });
         } catch (Exception e) {
@@ -510,6 +524,13 @@ public class BaiduFacePreviewActivity extends BaiduFaceMainActivity {
                                 doPersonCardResult(livenessModel);
                             }
 
+                        }else{
+                            if (livenessModel != null && livenessModel.getBdNirFaceImageInstance() != null) {
+                                livenessModel.getBdNirFaceImageInstance().destory();
+                            }
+                            if (livenessModel != null && livenessModel.getBdFaceImageInstance() != null) {
+                                livenessModel.getBdFaceImageInstance().destory();
+                            }
                         }
 
 
@@ -563,6 +584,7 @@ public class BaiduFacePreviewActivity extends BaiduFaceMainActivity {
             }
             if (mCamera != null) {
                 mCamera.stopPreview();
+                mCamera.setPreviewCallbackWithBuffer(null);
                 mCamera.setPreviewCallback(null);
                 mCamera.release();
                 mCamera = null;

+ 94 - 26
app/src/main/java/com/hanghui/senic/baiduface/WebsocketService.java

@@ -4,7 +4,11 @@ import static com.hanghui.senic.baiduface.BaiduFaceConstant.STATUS_cancel;
 import static com.hanghui.senic.baiduface.BaiduFaceConstant.STATUS_processing;
 import static com.hanghui.senic.baiduface.BaiduFaceConstant.STATUS_success;
 
+import android.annotation.SuppressLint;
+import android.app.AlarmManager;
+import android.app.PendingIntent;
 import android.app.Service;
+import android.content.Context;
 import android.content.Intent;
 import android.os.Handler;
 import android.os.HandlerThread;
@@ -55,6 +59,7 @@ public class WebsocketService extends Service {
     private CustomWebSocketListener mWebSocketListener = new CustomWebSocketListener();
 
     private volatile static  ConcurrentHashMap<String, WebSocketTask> webSocketTaskMap;  //todo 人脸执行队列任务 MAP
+    private volatile boolean isOnDestory=false; //服务是否销毁
 
     private Runnable mUserInfoReportRunnable = new Runnable() {
         @Override
@@ -81,6 +86,8 @@ public class WebsocketService extends Service {
         public void run() {
             sendMessage_heartbeat();
             mHandlerThreadHandler.postDelayed(this, HEART_BEAT_INTERVAL);
+            rebortApp();
+
         }
     };
 
@@ -92,8 +99,6 @@ public class WebsocketService extends Service {
     private HandlerThread mHandlerThread;
     private Handler mHandlerThreadHandler;
 
-    //相同的userId过滤
-    private HashMap<Integer, String> mUserHashMap = new HashMap<>();
     private int errorUserDataCount;//错误的用户数据
 
     @Override
@@ -109,7 +114,8 @@ public class WebsocketService extends Service {
         AppLogUtils.i(true, TAG + " ,onStartCommand", "onStartCommand()");
 
         //test_processUserData_delete();
-
+        isOnDestory=false;
+        cleanFaceQueue(); //清除刷脸队列
         initWebSocket();
 
         return START_STICKY;
@@ -128,13 +134,24 @@ public class WebsocketService extends Service {
 
     @Override
     public void onDestroy() {
+        isOnDestory=true;
         super.onDestroy();
-
         AppLogUtils.i(true, TAG + " ,WebSocket, onDestroy()", "WebSocket, onDestroy()");
-
+        closeWebSocket();
         mHandlerThreadHandler.removeCallbacks(mUserInfoReportRunnable);
         mHandlerThreadHandler.removeCallbacks(mHeartbeatRunnable);
         mHandlerThreadHandler.removeCallbacks(mHeartbeatTimeOutRunnable);
+        cleanFaceQueue();
+    }
+
+    /**
+     *
+     * @author xwh
+     * Time 2024/10/23
+     * Description: 清除人脸下发队列
+     *
+    **/
+    private void cleanFaceQueue(){
         if(webSocketTaskMap!=null) {
             for (String key : webSocketTaskMap.keySet()) {
                 WebSocketTask webSocketTask = webSocketTaskMap.get(key);
@@ -143,11 +160,10 @@ public class WebsocketService extends Service {
                 }
                 webSocketTask.setWebSocketTaskEnum(WebSocketTaskEnum.CANCEL);
                 webSocketTaskMap.put(key,webSocketTask);
+                mFaceDataHandlerThreadHandler.removeCallbacks(webSocketTask.getRunnable());
             }
-            mFaceDataHandlerThread.interrupt();
+            webSocketTaskMap.clear();
         }
-
-        closeWebSocket();
     }
 
 
@@ -354,7 +370,11 @@ public class WebsocketService extends Service {
         if(userFaceData==null){
             return;
         }
-
+     //   Log.i("____789","新增:"+userFaceData.getOp()+"   ");
+        if(isOnDestory){
+        //    Log.i("____789","executeAddFacetasks:"+"isOnDestory = true   ");
+            return;
+        }
         Runnable runnable=new Runnable() {
             @Override
             public void run() {
@@ -364,6 +384,7 @@ public class WebsocketService extends Service {
             }
         };
         if(userFaceData.getData()!=null) {
+            //TODO 人脸执行队列任务更新状态 WAIT
             WebSocketTask webSocketTask = new WebSocketTask(WebSocketTaskEnum.WAIT, runnable);
             getWebSocketTaskMap().put(userFaceData.getData().getTraceId(), webSocketTask);
         }
@@ -556,24 +577,39 @@ public class WebsocketService extends Service {
      */
     public synchronized void processUserData_issue(UserFaceData.Data data) {
         AppLogUtils.i(true, TAG + " ,processUserData_issue", "processUserData_issue(), item.size=" + data.getItems().size());
-        mUserHashMap.clear();
+        if(isOnDestory){
+            return;
+        }
         errorUserDataCount = 0;
 
-
         ArrayList<UserFaceData.Data.Item> userItems = data.getItems();
 
         ArrayList<UserFaceDataIssueCallback.Data.Item> callbackItems = new ArrayList<>(); //已处理的数据, 回调给后台
 
-        int totalSize = userItems.size();
-
+        int totalSize = userItems.size(); //todo 需要下发总数
         int currentPercent = -1; //todo 当前下发进度
+        int currentCount =0; //todo 当前已下发总数
         boolean isTaskCancel =false; //当前任务是否被取消
+        String traceId= data.getTraceId();
+     //   Log.i("____789","当前任务:"+traceId+"   ");
+        if (!TextUtils.isEmpty(traceId)
+                && getWebSocketTaskMap().containsKey(traceId) &&
+                getWebSocketTaskMap().get(traceId) != null) {
+            if (getWebSocketTaskMap().get(traceId)
+                    .getWebSocketTaskEnum() == WebSocketTaskEnum.CANCEL) { //TODO 如果任务已取消 返回
+            //    Log.i("____789", "当前任务已取消:" + traceId + "   ");
+                return;
+            }
+            WebSocketTask tempTask = getWebSocketTaskMap().get(traceId);//TODO 人脸执行队列任务更新状态 RUNNING
+            tempTask.setWebSocketTaskEnum(WebSocketTaskEnum.RUNNING);
+            getWebSocketTaskMap().put(traceId, tempTask);
+        }
         for (int i = 0; i < totalSize; i++) {
 
             if (userItems.size() <= i) { //todo 避免数组越界
                 break;
             }
-            String traceId= data.getTraceId();
+
             if(!TextUtils.isEmpty(traceId)&&getWebSocketTaskMap().containsKey(traceId)){
                 if (getWebSocketTaskMap().get(traceId) != null
                         && getWebSocketTaskMap().get(traceId)
@@ -658,10 +694,7 @@ public class WebsocketService extends Service {
                     msg = "下发失败";
                 }
 
-
-                // 人脸数据下发结果统计,相同的userId过滤
-                mUserHashMap.put(userItem.getUserId(), userItem.getUserName());
-
+                currentCount++;
             }
 
             //回调给后台
@@ -677,19 +710,28 @@ public class WebsocketService extends Service {
                 }
                 if (tempPercent > currentPercent) { //todo 当前进度如果有更新,同步后台百分比
                     currentPercent = tempPercent;
-                    sendMessage_issueCallback(data.getTraceId(), STATUS_processing, "下发中", totalSize, callbackItems);
+                    sendMessage_issueCallback(data.getTraceId(), STATUS_processing, "下发中", totalSize,currentCount, callbackItems);
+                    callbackItems=new ArrayList<>();
                 }
             }
 
 
         }
-        sendMessage_issueCallback(data.getTraceId(), isTaskCancel?STATUS_cancel:STATUS_success, "下发任务成功完成", totalSize, callbackItems);
+        sendMessage_issueCallback(data.getTraceId(), isTaskCancel?STATUS_cancel:STATUS_success, "下发任务成功完成", totalSize, currentCount,callbackItems);
 
+        if(!TextUtils.isEmpty(traceId)&&getWebSocketTaskMap().containsKey(traceId)){ //todo 人脸执行队列任务更新状态
+            WebSocketTask tempTask=getWebSocketTaskMap().get(traceId);
+            if ( tempTask!= null){
+                tempTask.setWebSocketTaskEnum( isTaskCancel?WebSocketTaskEnum.CANCEL:WebSocketTaskEnum.COMPLETE);
+                getWebSocketTaskMap().put(traceId,tempTask);
+            }
+        }
+        callbackItems.clear();
         //人脸数据下发结果统计
         if( callbackItems.size() == totalSize ) { //最后一条数据
             String result = "本次共下发 " + totalSize + " 条人脸数据" + " ,其中错误的数据 " + errorUserDataCount + " 条, " +
                     "正确的数据 " + (totalSize - errorUserDataCount) + " 条, " +
-                    "正确的数据中,不同userid的数据共有 " + mUserHashMap.size() + " 条.";
+                    "正确的数据中,不同userid的数据共有 " + currentCount + " 条.";
             AppLogUtils.i(true, "processUserData_issue, 人脸数据下发结果统计", "processUserData_issue, 人脸数据下发结果统计: " + result );
         }
 //        initFaceSearchData();
@@ -802,7 +844,7 @@ public class WebsocketService extends Service {
 
         //清空本地的数据
         FaceApi.getInstance().userClean();
-
+        FaceSDKManager.getInstance().cleanSearch();
         initFaceSearchData();
 
         sendMessage_deleteAllCallback(data.getTraceId(), STATUS_success, "删除成功");
@@ -842,7 +884,7 @@ public class WebsocketService extends Service {
      * @param totalCount    后台总共下发的用户数量
      * @param callbackItems 客户端已处理的用户数据
      */
-    private void sendMessage_issueCallback(String traceId, String status, String msg, int totalCount,
+    private void sendMessage_issueCallback(String traceId, String status, String msg, int totalCount, int currCount,
                                            ArrayList<UserFaceDataIssueCallback.Data.Item> callbackItems) {
         if (TextUtils.isEmpty(traceId)) {
             AppLogUtils.e(true, TAG + " ,sendMessage_issueCallback", "WebSocket, sendMessage_deleteAllCallback(), traceId为空");
@@ -853,7 +895,7 @@ public class WebsocketService extends Service {
             return;
         }
 
-        int callbackItemSize = callbackItems.size();
+        int callbackItemSize = currCount;
 
         int percent = 0;
         if(totalCount == 0) {
@@ -876,8 +918,8 @@ public class WebsocketService extends Service {
         data.setIssuePercent(percent);
         //data.setItems(callbackItems);
         //百度人脸下发的回调,Data.items字段,处理过程中不需要传items数据,最后一条数据时再传items数据
-        if(callbackItemSize < totalCount ) {
-            data.setItems(null);
+        if(status.equals(STATUS_processing)) {
+            data.setItems(callbackItems);
         } else { //处理最后一条数据
             data.setItems(callbackItems);
         }
@@ -1102,4 +1144,30 @@ public class WebsocketService extends Service {
         }
         return webSocketTaskMap;
     }
+
+    private void rebortApp(){
+        try {
+            long currentTime=System.currentTimeMillis();
+            long appHeartTime=MyAppliction.getAppHeartbeatTime();
+            if (appHeartTime > 0 && currentTime - appHeartTime >= 60 * 1000) {
+                Intent intent = new Intent( MyAppliction.getContext().getApplicationContext(), BaiduFacePreviewActivity.class);
+                @SuppressLint("WrongConstant")
+                PendingIntent restartIntent = PendingIntent.getActivity( MyAppliction.getContext().getApplicationContext(), 0, intent,
+                        Intent.FLAG_ACTIVITY_NEW_TASK);
+                //退出程序
+                AlarmManager mgr = (AlarmManager) MyAppliction.getContext().getSystemService(Context.ALARM_SERVICE);
+                mgr.set(AlarmManager.RTC, System.currentTimeMillis() + 500, restartIntent); //1秒钟后重启应用
+                if( MyAppliction.getContext() instanceof MyAppliction){
+                    ((MyAppliction) MyAppliction.getContext()).finishActivity();
+                    System.exit(0);
+                }else{
+                    System.exit(0);
+                }
+
+            }
+        }catch (Exception e){
+
+        }
+
+    }
 }

+ 1 - 0
app/src/main/java/com/hanghui/senic/presenter/MyPresenter.java

@@ -220,6 +220,7 @@ public class MyPresenter<T> implements ContractInterface.PAuthentication, Contra
             @Override
             public void doAfterResponse(Object o) {
                 AppLogUtils.i(true, "接口请求_上报应用状态接口", "应用状态数据返回  " + o);
+                MyAppliction.setAppHeartbeatTime(System.currentTimeMillis());
             }
         });
     }

+ 1 - 0
datalibrary/src/main/java/com/example/datalibrary/api/FaceApi.java

@@ -262,6 +262,7 @@ public class FaceApi {
                         curUser.setImageName(user.getImageName());
                         curUser.setUserInfo(user.getUserInfo());
                         curUser.setFeature(user.getFeature());
+                        curUser.setUserInfo(user.getUserInfo());
                         users.put(curUser.getUserId(), curUser);
                     }
                 }

+ 18 - 5
datalibrary/src/main/java/com/example/datalibrary/gatecamera/CameraPreviewManager.java

@@ -152,6 +152,7 @@ public class CameraPreviewManager implements SurfaceHolder.Callback , TextureVie
         if (mCamera != null) {
             try {
                 mCamera.stopPreview();
+                mCamera.setPreviewCallbackWithBuffer(null);
                 mCamera.setPreviewCallback(null);
                 mPreviewed = false;
                 mCamera.release();
@@ -212,16 +213,28 @@ public class CameraPreviewManager implements SurfaceHolder.Callback , TextureVie
             mCamera.setParameters(params);
             if (mTextureView != null){
                 try {
-                    mCamera.setPreviewCallback(new Camera.PreviewCallback() {
+                    byte[] buffer=new byte[460800];
+                    mCamera.addCallbackBuffer(buffer);
+                    mCamera.setPreviewCallbackWithBuffer(new Camera.PreviewCallback() {
                         @Override
                         public void onPreviewFrame(byte[] bytes, Camera camera) {
-                          //  Log.i("______456","rgb摄像头预览数据"+bytes.length);
-                            if (mCameraDataCallback != null) {
-                                mCameraDataCallback.onGetCameraData(bytes, camera,
-                                        videoWidth, videoHeight);
+                            if(camera!=null) {
+                                camera.addCallbackBuffer(bytes);
+                                if (mCameraDataCallback != null) {
+                                    mCameraDataCallback.onGetCameraData(bytes, camera,
+                                            videoWidth, videoHeight);
+                                }
                             }
                         }
                     });
+
+                    /*mCamera.setPreviewCallback(new Camera.PreviewCallback() {
+                        @Override
+                        public void onPreviewFrame(byte[] bytes, Camera camera) {
+                          //  Log.i("______456","rgb摄像头预览数据"+bytes.length);
+
+                        }
+                    });*/
                     mCamera.setPreviewTexture(mSurfaceTexture);
 
                     mCamera.startPreview();

+ 1 - 0
registerlibrary/src/main/java/com/baidu/idl/main/facesdk/registerlibrary/user/activity/BatchImportActivity.java

@@ -352,6 +352,7 @@ public class BatchImportActivity extends BaseActivity implements View.OnClickLis
             // 设置数据库状态
 //            ShareManager.getInstance(mContext).setDBState(false);
             FaceApi.getInstance().userClean();
+            FaceSDKManager.getInstance().cleanSearch();
             if (FaceApi.getInstance().getAllUserList() != null &&
                     FaceApi.getInstance().getAllUserList().size() > 0){
                 mRelativeShow.setVisibility(View.VISIBLE);