package com.doumee.keyCabinet.ui.face; import androidx.annotation.NonNull; import androidx.annotation.Nullable; import android.content.Context; import android.graphics.Bitmap; import android.hardware.Camera; import android.os.Bundle; import android.os.Handler; import android.os.Message; import android.text.SpannableString; import android.text.Spanned; import android.text.TextUtils; import android.text.style.TextAppearanceSpan; import android.view.View; import android.view.ViewTreeObserver; import android.view.inputmethod.InputMethodManager; import android.widget.TextView; import android.widget.Toast; import com.baidu.idl.main.facesdk.model.BDFaceSDKCommon; import com.doumee.keyCabinet.MApplication; import com.doumee.keyCabinet.R; import com.doumee.keyCabinet.base.MyBaseActivity; import com.doumee.keyCabinet.databinding.FaceActivityBinding; import com.doumee.keyCabinet.event.FaceStatusChangeEvent; import com.doumee.keyCabinet.event.JiujinBeginEvent; import com.doumee.keyCabinet.event.JiujinResultEvent; import com.doumee.keyCabinet.event.TimeClockEvent; import com.doumee.keyCabinet.ui.keyCabinet.KeyCabinetActivity; import com.doumee.keyCabinet.utils.BraceletLogUtils; import com.doumee.keyCabinet.utils.face.FaceUtils; import com.doumee.keyCabinet.utils.face.model.SingleBaseConfig; import com.doumee.lib_coremodel.bean.event.ActionEventData; import com.doumee.lib_coremodel.util.SpUtil; import com.doumee.lib_coremodel.util.StringUtil; import com.example.datalibrary.callback.CameraDataCallback; import com.example.datalibrary.callback.FaceDetectCallBack; import com.example.datalibrary.gatecamera.CameraPreviewManager; import com.example.datalibrary.gl.view.GlMantleSurfacView; import com.example.datalibrary.manager.FaceSDKManager; import com.example.datalibrary.model.BDFaceCheckConfig; import com.example.datalibrary.model.BDFaceImageConfig; import com.example.datalibrary.model.LivenessModel; import com.example.datalibrary.model.User; import com.example.datalibrary.utils.FaceOnDrawTexturViewUtil; import com.example.datalibrary.utils.ToastUtils; import org.greenrobot.eventbus.EventBus; import org.greenrobot.eventbus.Subscribe; import org.greenrobot.eventbus.ThreadMode; import java.math.BigDecimal; import dagger.hilt.android.AndroidEntryPoint; @AndroidEntryPoint public class FaceActivity extends MyBaseActivity implements View.OnClickListener{ /*图片越大,性能消耗越大,也可以选择640*480, 1280*720*/ private static final int PREFER_WIDTH = SingleBaseConfig.getBaseConfig().getRgbAndNirWidth(); private static final int PERFER_HEIGH = SingleBaseConfig.getBaseConfig().getRgbAndNirHeight(); private Context mContext; private boolean isCompareCheck = true; private User mUser; private GlMantleSurfacView glMantleSurfacView; private BDFaceImageConfig bdFaceImageConfig; private BDFaceCheckConfig bdFaceCheckConfig; //0:取,1:还 private int flag ; private int status; @Override public int getLayoutId() { return R.layout.face_activity; } @Override public void initView(@Nullable Bundle savedInstanceState) { isToGuild = false; normalConfig(); getDB().setModel(getVM()); mContext = this; flag = MApplication.getLoginBean().getFlag(); FaceSDKManager.getInstance().initDataBases(this); initFaceCheck(); initView(); if(flag==0){ if(MApplication.getConfigBean().getDoubleAuth()==1){ statusFsm(0); }else { statusFsm(2); } }else { statusFsm(7); } getDB().tvDjs.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { statusFsm(status); } }); } @Override public void initData(@Nullable Bundle savedInstanceState) { //getPermission(); } @Override protected void timeChange(String djs) { getDB().tvDjs.setText(djs); } private SpannableString getErrPhoneText(){ String phone = MApplication.getConfigBean().getLinkPhone(); String text = "如有问题请联系管理员"+phone; SpannableString styledText = new SpannableString(text); styledText.setSpan(new TextAppearanceSpan(this, R.style.style_tip3), 0, text.length()-phone.length(), Spanned.SPAN_EXCLUSIVE_EXCLUSIVE); styledText.setSpan(new TextAppearanceSpan(this,R.style.style_tip1), text.length()-phone.length()+1, text.length(), Spanned.SPAN_EXCLUSIVE_EXCLUSIVE); return styledText; } private void statusFsm(int toStatus){ status = toStatus; isToChose = false; switch (toStatus){ case 0: //取-管理员人脸验证 getDB().tvTitle.setText("管理员身份验证"); getDB().clCard.setVisibility(View.GONE); getDB().clFace.setVisibility(View.VISIBLE); setFaceModel(0); break; case 1: //取-管理员刷卡验证 getDB().tvTitle.setText("管理员身份验证"); getDB().clFace.setVisibility(View.GONE); getDB().clCard.setVisibility(View.VISIBLE); setFaceModel(2); break; case 5: //取-司机验证方式选择页 getDB().tvTitle.setText("司机身份验证"); getDB().clFace.setVisibility(View.GONE); getDB().clCard.setVisibility(View.GONE); getDB().clTip1.setVisibility(View.GONE); getDB().clSjXuan.setVisibility(View.VISIBLE); getDB().clSjXuan.invalidate(); getDB().clSjXuan.requestLayout(); break; case 2: //取-司机人脸验证 getDB().tvTitle.setText("司机身份验证"); getDB().clCard.setVisibility(View.GONE); getDB().clSjXuan.setVisibility(View.GONE); getDB().clFace.setVisibility(View.VISIBLE); setFaceModel(1); break; case 3: //取-司机刷卡验证 getDB().tvTitle.setText("司机身份验证"); getDB().clFace.setVisibility(View.GONE); getDB().clSjXuan.setVisibility(View.GONE); getDB().clCard.setVisibility(View.VISIBLE); setFaceModel(2); break; case 4: //取-司机酒精检测 getDB().tvTitle.setText("酒精检测"); getDB().clFace.setVisibility(View.GONE); getDB().clCard.setVisibility(View.GONE); getDB().clSjXuan.setVisibility(View.GONE); getDB().clTip1.setVisibility(View.GONE); getDB().clJiu.setVisibility(View.VISIBLE); getDB().clJiu.invalidate(); getDB().clJiu.requestLayout(); if(MApplication.getConfigBean()!=null&&MApplication.getConfigBean().getCabinetConfigDataVO()!=null&& MApplication.getConfigBean().getCabinetConfigDataVO().getConcentration()!=null){ //开始检测 EventBus.getDefault().post(new JiujinBeginEvent()); }else { ToastUtils.toast(this,"未获取到酒精浓度报警值"); statusFsm(6); } break; case 6: //取-司机酒精检测失败 Toast.makeText(mContext, "司机酒精检测失败", Toast.LENGTH_SHORT).show(); getDB().clJiu.setVisibility(View.GONE); getDB().clTip1.setVisibility(View.VISIBLE); break; case 7: //还-司机人脸验证 getDB().tvTitle.setText("司机身份验证"); getDB().clCard.setVisibility(View.GONE); getDB().clFace.setVisibility(View.VISIBLE); setFaceModel(1); break; case 8: //还-司机刷卡验证 getDB().tvTitle.setText("司机身份验证"); getDB().clFace.setVisibility(View.GONE); getDB().clCard.setVisibility(View.VISIBLE); setFaceModel(2); break; default: break; } } private void setFaceModel(int faceModel){ if(faceModel==0){ //管理员 FaceSDKManager.getInstance().setGroupId("0"); isToChose = false; }else if(faceModel==1){ //司机 FaceSDKManager.getInstance().setGroupId("1"); isToChose = false; }else { isToChose = true; } } private Bitmap bitmap; private byte[] secondFeature = new byte[512]; @Override protected void doRegister(int type, ActionEventData data) { switch (type){ case 1: //切换到刷卡 if(flag==0){ if(status==0){ statusFsm(1); }else if(status==2){ statusFsm(3); } }else { statusFsm(8); } break; case 2: //切换司机刷卡 statusFsm(3); break; case 3: //切换司机人脸 statusFsm(2); break; case 4: //切换到人脸 if(flag==0){ if(status==1){ statusFsm(0); }else if(status==3){ statusFsm(2); } }else { statusFsm(7); } break; case 5: statusFsm(4); break; default: break; } } private void initFaceConfig(int height , int width){ bdFaceImageConfig = new BDFaceImageConfig(height , width , SingleBaseConfig.getBaseConfig().getRgbDetectDirection(), SingleBaseConfig.getBaseConfig().getMirrorDetectRGB() , BDFaceSDKCommon.BDFaceImageType.BDFACE_IMAGE_TYPE_YUV_NV21); } private void initFaceCheck(){ bdFaceCheckConfig = FaceUtils.getInstance().getBDFaceCheckConfig(); } /** * View */ private void initView() { getDB().faceDetectImageView.setVisibility(View.GONE); glMantleSurfacView = findViewById(R.id.camera_textureview); glMantleSurfacView.initSurface(SingleBaseConfig.getBaseConfig().getRgbRevert(), SingleBaseConfig.getBaseConfig().getMirrorVideoRGB() , SingleBaseConfig.getBaseConfig().isOpenGl()); CameraPreviewManager.getInstance().startPreview(glMantleSurfacView, SingleBaseConfig.getBaseConfig().getRgbVideoDirection() , PREFER_WIDTH, PERFER_HEIGH); getDB().tvJg2.setText(getErrPhoneText(), TextView.BufferType.SPANNABLE); //ic卡读取 getDB().etEwm.requestFocus(); getDB().etEwm.setShowSoftInputOnFocus(false); hideSoftKeyboard(getDB().etEwm); getDB().etEwm.getViewTreeObserver().addOnGlobalLayoutListener(new ViewTreeObserver.OnGlobalLayoutListener() { @Override public void onGlobalLayout() { hideSoftKeyboard(getDB().etEwm); } }); } private void hideSoftKeyboard(View view) { InputMethodManager imm = (InputMethodManager) getSystemService(Context.INPUT_METHOD_SERVICE); if (imm != null) { imm.hideSoftInputFromWindow(view.getWindowToken(), 0); } } @Override protected void onResume() { super.onResume(); startTestOpenDebugRegisterFunction(); } private void startTestOpenDebugRegisterFunction() { if(SingleBaseConfig.getBaseConfig().getRBGCameraId()==-1){ if(!TextUtils.isEmpty(SpUtil.getString("rbgCameraId"))) { SingleBaseConfig.getBaseConfig().setRBGCameraId(Integer.parseInt(SpUtil.getString("rbgCameraId"))); } } if (SingleBaseConfig.getBaseConfig().getRBGCameraId() != -1) { BraceletLogUtils.saveLog("使用相机("+SingleBaseConfig.getBaseConfig().getRBGCameraId()+")"); CameraPreviewManager.getInstance().setCameraFacing(SingleBaseConfig.getBaseConfig().getRBGCameraId()); } else { BraceletLogUtils.saveLog("使用相机("+CameraPreviewManager.CAMERA_USB+")"); CameraPreviewManager.getInstance().setCameraFacing(CameraPreviewManager.CAMERA_USB); } int[] cameraSize = CameraPreviewManager.getInstance().initCamera(new CameraPreviewManager.ErrInfoCallBack() { @Override public void err(String errInfo) { BraceletLogUtils.saveLog(errInfo); } }); initFaceConfig(cameraSize[1] , cameraSize[0]); isPause = true; count = 60; CameraPreviewManager.getInstance().setmCameraDataCallback(dataCallback); } private CameraDataCallback dataCallback = new CameraDataCallback() { @Override public void onGetCameraData(byte[] data, Camera camera, int width, int height) { if(!isFinishing()){ //isCheckFace = true; handler.sendEmptyMessageDelayed(1,4000); glMantleSurfacView.setFrame(); bdFaceImageConfig.setData(data); FaceSDKManager.getInstance().onDetectCheck(bdFaceImageConfig, null, null, bdFaceCheckConfig, faceDetectCallBack); } } }; //private boolean isCheckFace; private FaceDetectCallBack faceDetectCallBack = new FaceDetectCallBack() { @Override public void onFaceDetectCallback(LivenessModel livenessModel) { //System.out.println("==isOk==>onFaceDetectCallback"); //System.out.println("==rgbInstance==>onFaceDetectCallback "+livenessModel); // 开发模式 //isCheckFace = false; if(handler.hasMessages(1)){ handler.removeMessages(1); } checkOpenDebugResult(livenessModel); } @Override public void onTip(int code, String msg) { if(isToChose){ return; } /*getDB().clFail.setVisibility(View.VISIBLE); getDB().tv4.setText(msg); handler.sendEmptyMessageDelayed(0,1000);*/ System.out.println("==isOk==>onTip:"+msg); } @Override public void onFaceDetectDarwCallback(LivenessModel livenessModel) { //System.out.println("==rgbInstance==>onFaceDetectDarwCallback"); if(isToChose){ return; } if (isCompareCheck) { /*getDB().clFail.setVisibility(View.VISIBLE); getDB().tv4.setText(getString(R.string.face_tip2)); handler.sendEmptyMessageDelayed(0,1000);*/ } // 绘制人脸框 showFrame(livenessModel); } }; private boolean isPause = false; public void showFrame(LivenessModel livenessModel){ if(isFinishing()){ return; } if (livenessModel == null){ return; } if (isPause){ glMantleSurfacView.onGlDraw(livenessModel.getTrackFaceInfo() , livenessModel.getBdFaceImageInstance() , FaceOnDrawTexturViewUtil.drawFaceColor(mUser , livenessModel)); } } private Handler handler = new Handler(){ @Override public void handleMessage(@NonNull Message msg) { switch (msg.what){ case 0: getDB().clFail.setVisibility(View.GONE); break; case 1: //isCheckFace = false; break; case 3: Toast.makeText(mContext, "酒精检查返回", Toast.LENGTH_SHORT).show(); if(new BigDecimal(MApplication.getConfigBean().getCabinetConfigDataVO().getConcentration()) .compareTo(resultEvent.getConcentration())>=0){ //酒精通过 getDB().clJiujinOk.setVisibility(View.VISIBLE); handler.sendEmptyMessageDelayed(4,1000); }else { //酒精不通过 getVM().alcoholTestAlarm(""); Toast.makeText(mContext, "酒精检测不通过", Toast.LENGTH_SHORT).show(); statusFsm(6); } break; case 4: startActivity(KeyCabinetActivity.class); finish(); break; default: break; } } }; @Override protected void onRestart() { super.onRestart(); isTimePause = false; isToChose = false; count = 120; } private int count = 120; private boolean isTimePause = false; @Subscribe public void TimeClockEvent(TimeClockEvent event) { if (!isFinishing()&&!isTimePause) { if (count > 0) { count--; if (count == 0) { finish(); return; } } } } @Override protected void onDestroy() { super.onDestroy(); handler.removeCallbacksAndMessages(null); handler = null; dataCallback = null; CameraPreviewManager.getInstance().destroy(); faceDetectCallBack = null; glMantleSurfacView = null; FaceSDKManager.getInstance().destroy(); } private int resultCount = 0; // ***************开发模式结果输出************* private void checkOpenDebugResult(final LivenessModel livenessModel) { if(isFinishing()){ return; } if(handler==null){ return; } // 当未检测到人脸UI显示 runOnUiThread(new Runnable() { @Override public void run() { if(isToChose) { return; } if (livenessModel == null) { if (isCompareCheck) { /*getDB().clFail.setVisibility(View.VISIBLE); getDB().tv4.setText(getString(R.string.face_tip2)); handler.sendEmptyMessageDelayed(0,1000);*/ } System.out.println("======>人脸识别失败"); return; } if (livenessModel.isQualityCheck()){ //是否通过质量检测 if (isCompareCheck) { /*getDB().clFail.setVisibility(View.VISIBLE); getDB().tv4.setText(getString(R.string.face_tip2)); handler.sendEmptyMessageDelayed(0,1000);*/ } } else { User user = livenessModel.getUser(); if (user == null) { mUser = null; if (isCompareCheck) { /*getDB().clFail.setVisibility(View.VISIBLE); getDB().tv4.setText(getString(R.string.face_tip2)); handler.sendEmptyMessageDelayed(0,1000);*/ } } else { mUser = user; if (isCompareCheck) { getDB().clFail.setVisibility(View.GONE); if(handler.hasMessages(0)) { handler.removeMessages(0); } /*textHuanying.setVisibility(View.GONE); userNameLayout.setVisibility(View.VISIBLE); nameImage.setImageResource(R.mipmap.ic_tips_gate_success); nameText.setTextColor(Color.parseColor("#0dc6ff")); nameText.setText(FileUtils.spotString(user.getUserName()) + " 欢迎您");*/ } isToChose = true; //识别成功,跳转 if(status==0){ //取-管理员 MApplication.getLoginBean().setAutoMemberId(Integer.parseInt(user.getUserId())); //handler.sendEmptyMessageDelayed(7,0); EventBus.getDefault().post(new FaceStatusChangeEvent(5)); }else if(status==2){ //取-司机 CameraPreviewManager.getInstance().stopPreview(); MApplication.getLoginBean().setMemberId(Integer.parseInt(user.getUserId())); MApplication.getLoginBean().setAuthType(0); //handler.sendEmptyMessageDelayed(8,0); EventBus.getDefault().post(new FaceStatusChangeEvent(4)); }else if(status==7){ //还-司机 MApplication.getLoginBean().setMemberId(Integer.parseInt(user.getUserId())); MApplication.getLoginBean().setAuthType(0); startActivity(KeyCabinetActivity.class); finish(); } } } } }); } @Subscribe(threadMode = ThreadMode.MAIN) public void FaceStatusChangeEvent(FaceStatusChangeEvent e){ if(!isFinishing()){ statusFsm(e.getStatus()); } } boolean isToChose = false; @Override public void onClick(View v) { } @Override protected void onPause() { super.onPause(); isPause = false; isTimePause = true; CameraPreviewManager.getInstance().stopPreview(); } private JiujinResultEvent resultEvent; @Subscribe(threadMode = ThreadMode.MAIN) public void JiujinResultEvent(JiujinResultEvent e){ if(!isFinishing()){ //Toast.makeText(mContext, "酒精检测返回:"+e.isOk(), Toast.LENGTH_SHORT).show(); if(!e.isOk()){ statusFsm(6); }else { if(resultEvent==null){ resultEvent = e; }else if(resultEvent.getConcentration().compareTo(e.getConcentration())<0){ //值更大 resultEvent = e; } if(handler.hasMessages(3)){ handler.removeMessages(3); } handler.sendEmptyMessageDelayed(3,1000); } } } }