|
|
@@ -1,495 +0,0 @@
|
|
|
-/**
|
|
|
- * Copyright (C) 2017 Baidu Inc. All rights reserved.
|
|
|
- */
|
|
|
-package com.baidu.idl.face.platform.ui;
|
|
|
-
|
|
|
-import android.content.BroadcastReceiver;
|
|
|
-import android.content.Context;
|
|
|
-import android.graphics.Bitmap;
|
|
|
-import android.graphics.BitmapFactory;
|
|
|
-import android.graphics.PixelFormat;
|
|
|
-import android.graphics.Point;
|
|
|
-import android.graphics.Rect;
|
|
|
-import android.graphics.drawable.Drawable;
|
|
|
-import android.hardware.Camera;
|
|
|
-import android.media.AudioManager;
|
|
|
-import android.text.TextUtils;
|
|
|
-import android.util.DisplayMetrics;
|
|
|
-import android.view.Display;
|
|
|
-import android.view.Gravity;
|
|
|
-import android.view.Surface;
|
|
|
-import android.view.SurfaceHolder;
|
|
|
-import android.view.SurfaceView;
|
|
|
-import android.view.WindowManager;
|
|
|
-import android.widget.FrameLayout;
|
|
|
-import android.widget.TextView;
|
|
|
-
|
|
|
-import com.baidu.aip.face.stat.Ast;
|
|
|
-import com.baidu.idl.face.platform.FaceConfig;
|
|
|
-import com.baidu.idl.face.platform.FaceSDKManager;
|
|
|
-import com.baidu.idl.face.platform.FaceStatusEnum;
|
|
|
-import com.baidu.idl.face.platform.ILivenessStrategy;
|
|
|
-import com.baidu.idl.face.platform.ILivenessStrategyCallback;
|
|
|
-import com.baidu.idl.face.platform.ui.utils.CameraUtils;
|
|
|
-import com.baidu.idl.face.platform.ui.utils.VolumeUtils;
|
|
|
-import com.baidu.idl.face.platform.ui.widget.FaceDetectRoundView;
|
|
|
-import com.baidu.idl.face.platform.utils.APIUtils;
|
|
|
-import com.baidu.idl.face.platform.utils.Base64Utils;
|
|
|
-import com.baidu.idl.face.platform.utils.CameraPreviewUtils;
|
|
|
-import com.modular.apputils.activity.BaseNetActivity;
|
|
|
-
|
|
|
-import java.util.HashMap;
|
|
|
-import java.util.Map;
|
|
|
-import java.util.Set;
|
|
|
-
|
|
|
-/**
|
|
|
- * 活体检测接口
|
|
|
- */
|
|
|
-public abstract class FaceLivenessActivity extends BaseNetActivity implements
|
|
|
- SurfaceHolder.Callback,
|
|
|
- Camera.PreviewCallback,
|
|
|
- Camera.ErrorCallback,
|
|
|
- VolumeUtils.VolumeCallback,
|
|
|
- ILivenessStrategyCallback {
|
|
|
-
|
|
|
- public static final String TAG = FaceLivenessActivity.class.getSimpleName();
|
|
|
-
|
|
|
- // View
|
|
|
- protected FrameLayout mFrameLayout;
|
|
|
- protected SurfaceView mSurfaceView;
|
|
|
- protected SurfaceHolder mSurfaceHolder;
|
|
|
- protected TextView mTipsTopView;
|
|
|
- protected FaceDetectRoundView mFaceDetectRoundView;
|
|
|
-
|
|
|
- // 人脸信息
|
|
|
- protected FaceConfig mFaceConfig;
|
|
|
- protected ILivenessStrategy mILivenessStrategy;
|
|
|
- // 显示Size
|
|
|
- private Rect mPreviewRect = new Rect();
|
|
|
- protected int mDisplayWidth = 0;
|
|
|
- protected int mDisplayHeight = 0;
|
|
|
- protected int mSurfaceWidth = 0;
|
|
|
- protected int mSurfaceHeight = 0;
|
|
|
- protected Drawable mTipsIcon;
|
|
|
- // 状态标识
|
|
|
- protected volatile boolean mIsEnableSound = true;
|
|
|
- protected boolean mIsCreateSurface = false;
|
|
|
- protected boolean mIsCompletion = false;
|
|
|
- // 相机
|
|
|
- protected Camera mCamera;
|
|
|
- protected Camera.Parameters mCameraParam;
|
|
|
- protected int mCameraId;
|
|
|
- protected int mPreviewWidth;
|
|
|
- protected int mPreviewHight;
|
|
|
- protected int mPreviewDegree;
|
|
|
- // 监听系统音量广播
|
|
|
- protected BroadcastReceiver mVolumeReceiver;
|
|
|
-
|
|
|
- @Override
|
|
|
- public void preOnCreacte() {
|
|
|
- getWindow().addFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON);
|
|
|
- Ast.getInstance().init(getApplicationContext(), "3.1.0.0", "facenormal");
|
|
|
- }
|
|
|
-
|
|
|
- @Override
|
|
|
- protected int getLayoutId() {
|
|
|
- return R.layout.activity_face_verifty;
|
|
|
- }
|
|
|
-
|
|
|
- @Override
|
|
|
- protected void init() throws Exception {
|
|
|
-
|
|
|
- DisplayMetrics dm = new DisplayMetrics();
|
|
|
- Display display = this.getWindowManager().getDefaultDisplay();
|
|
|
- display.getMetrics(dm);
|
|
|
- mDisplayWidth = dm.widthPixels;
|
|
|
- mDisplayHeight = dm.heightPixels;
|
|
|
-
|
|
|
- com.baidu.idl.face.platform.ui.config.FaceConfig.initializeResId();
|
|
|
- mFaceConfig = FaceSDKManager.getInstance().getFaceConfig();
|
|
|
-
|
|
|
- AudioManager am = (AudioManager) getSystemService(Context.AUDIO_SERVICE);
|
|
|
- int vol = am.getStreamVolume(AudioManager.STREAM_MUSIC);
|
|
|
- mIsEnableSound = vol > 0 ? mFaceConfig.isSound : false;
|
|
|
-
|
|
|
- mFrameLayout = findViewById(R.id.liveness_surface_layout);
|
|
|
- mFaceDetectRoundView = findViewById(R.id.liveness_face_round);
|
|
|
- mTipsTopView = findViewById(R.id.liveness_top_tips);
|
|
|
-
|
|
|
-
|
|
|
- mSurfaceView = new SurfaceView(this);
|
|
|
- mSurfaceHolder = mSurfaceView.getHolder();
|
|
|
- mSurfaceHolder.setSizeFromLayout();
|
|
|
- mSurfaceHolder.addCallback(this);
|
|
|
- mSurfaceHolder.setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS);
|
|
|
-
|
|
|
- int w = mDisplayWidth;
|
|
|
- int h = mDisplayHeight;
|
|
|
-
|
|
|
- FrameLayout.LayoutParams cameraFL = new FrameLayout.LayoutParams(
|
|
|
- (int) (w * FaceDetectRoundView.SURFACE_RATIO), (int) (h * FaceDetectRoundView.SURFACE_RATIO),
|
|
|
- Gravity.CENTER_VERTICAL | Gravity.CENTER_HORIZONTAL);
|
|
|
-
|
|
|
- mSurfaceView.setLayoutParams(cameraFL);
|
|
|
- mFrameLayout.addView(mSurfaceView);
|
|
|
-
|
|
|
-
|
|
|
- }
|
|
|
-
|
|
|
-
|
|
|
- @Override
|
|
|
- public void onResume() {
|
|
|
- super.onResume();
|
|
|
- setVolumeControlStream(AudioManager.STREAM_MUSIC);
|
|
|
- mVolumeReceiver = VolumeUtils.registerVolumeReceiver(this, this);
|
|
|
- if (mTipsTopView != null) {
|
|
|
- mTipsTopView.setText(R.string.detect_face_in);
|
|
|
- }
|
|
|
- startPreview();
|
|
|
- }
|
|
|
-
|
|
|
- @Override
|
|
|
- public void onPause() {
|
|
|
- super.onPause();
|
|
|
- stopPreview();
|
|
|
- }
|
|
|
-
|
|
|
- @Override
|
|
|
- public void onStop() {
|
|
|
- if (mILivenessStrategy != null) {
|
|
|
- mILivenessStrategy.reset();
|
|
|
- }
|
|
|
- VolumeUtils.unRegisterVolumeReceiver(this, mVolumeReceiver);
|
|
|
- mVolumeReceiver = null;
|
|
|
- super.onStop();
|
|
|
- stopPreview();
|
|
|
- Ast.getInstance().immediatelyUpload();
|
|
|
- }
|
|
|
-
|
|
|
- @Override
|
|
|
- public void finish() {
|
|
|
- super.finish();
|
|
|
- }
|
|
|
-
|
|
|
- @Override
|
|
|
- public void volumeChanged() {
|
|
|
- try {
|
|
|
- AudioManager am = (AudioManager) this.getSystemService(Context.AUDIO_SERVICE);
|
|
|
- if (am != null) {
|
|
|
-// int cv = am.getStreamVolume(AudioManager.STREAM_MUSIC);
|
|
|
-// mIsEnableSound = cv > 0;
|
|
|
-// mSoundView.setImageResource(mIsEnableSound
|
|
|
-// ? R.mipmap.ic_enable_sound_ext : R.mipmap.ic_disable_sound_ext);
|
|
|
-// if (mILivenessStrategy != null) {
|
|
|
-// mILivenessStrategy.setLivenessStrategySoundEnable(mIsEnableSound);
|
|
|
-// }
|
|
|
- }
|
|
|
- } catch (Exception ex) {
|
|
|
- ex.printStackTrace();
|
|
|
- }
|
|
|
- }
|
|
|
-
|
|
|
- private Camera open() {
|
|
|
- Camera camera;
|
|
|
- int numCameras = Camera.getNumberOfCameras();
|
|
|
- if (numCameras == 0) {
|
|
|
- return null;
|
|
|
- }
|
|
|
-
|
|
|
- int index = 0;
|
|
|
- while (index < numCameras) {
|
|
|
- Camera.CameraInfo cameraInfo = new Camera.CameraInfo();
|
|
|
- Camera.getCameraInfo(index, cameraInfo);
|
|
|
- if (cameraInfo.facing == Camera.CameraInfo.CAMERA_FACING_FRONT) {
|
|
|
- break;
|
|
|
- }
|
|
|
- index++;
|
|
|
- }
|
|
|
-
|
|
|
- if (index < numCameras) {
|
|
|
- camera = Camera.open(index);
|
|
|
- mCameraId = index;
|
|
|
- } else {
|
|
|
- camera = Camera.open(0);
|
|
|
- mCameraId = 0;
|
|
|
- }
|
|
|
- return camera;
|
|
|
- }
|
|
|
-
|
|
|
- protected void startPreview() {
|
|
|
- if (mSurfaceView != null && mSurfaceView.getHolder() != null) {
|
|
|
- mSurfaceHolder = mSurfaceView.getHolder();
|
|
|
- mSurfaceHolder.addCallback(this);
|
|
|
- }
|
|
|
-
|
|
|
- if (mCamera == null) {
|
|
|
- try {
|
|
|
- mCamera = open();
|
|
|
- } catch (RuntimeException e) {
|
|
|
- e.printStackTrace();
|
|
|
- } catch (Exception e) {
|
|
|
- e.printStackTrace();
|
|
|
- }
|
|
|
- }
|
|
|
-
|
|
|
- if (mCamera == null) {
|
|
|
- return;
|
|
|
- }
|
|
|
-
|
|
|
- if (mCameraParam == null) {
|
|
|
- mCameraParam = mCamera.getParameters();
|
|
|
- }
|
|
|
-
|
|
|
- mCameraParam.setPictureFormat(PixelFormat.JPEG);
|
|
|
- int degree = displayOrientation(this);
|
|
|
- mCamera.setDisplayOrientation(degree);
|
|
|
- // 设置后无效,camera.setDisplayOrientation方法有效
|
|
|
- mCameraParam.set("rotation", degree);
|
|
|
- mPreviewDegree = degree;
|
|
|
-
|
|
|
- Point point = CameraPreviewUtils.getBestPreview(mCameraParam,
|
|
|
- new Point(mDisplayWidth, mDisplayHeight));
|
|
|
-
|
|
|
- mPreviewWidth = point.x;
|
|
|
- mPreviewHight = point.y;
|
|
|
- // Preview 768,432
|
|
|
-
|
|
|
- if (mILivenessStrategy != null) {
|
|
|
- mILivenessStrategy.setPreviewDegree(degree);
|
|
|
- }
|
|
|
-
|
|
|
- mPreviewRect.set(0, 0, mPreviewHight, mPreviewWidth);
|
|
|
-
|
|
|
- mCameraParam.setPreviewSize(mPreviewWidth, mPreviewHight);
|
|
|
- mCamera.setParameters(mCameraParam);
|
|
|
-
|
|
|
- try {
|
|
|
- mCamera.setPreviewDisplay(mSurfaceHolder);
|
|
|
- mCamera.stopPreview();
|
|
|
- mCamera.setErrorCallback(this);
|
|
|
- mCamera.setPreviewCallback(this);
|
|
|
- mCamera.startPreview();
|
|
|
- } catch (RuntimeException e) {
|
|
|
- e.printStackTrace();
|
|
|
- CameraUtils.releaseCamera(mCamera);
|
|
|
- mCamera = null;
|
|
|
- } catch (Exception e) {
|
|
|
- e.printStackTrace();
|
|
|
- CameraUtils.releaseCamera(mCamera);
|
|
|
- mCamera = null;
|
|
|
- }
|
|
|
- }
|
|
|
-
|
|
|
- protected void stopPreview() {
|
|
|
- if (mCamera != null) {
|
|
|
- try {
|
|
|
- mCamera.setErrorCallback(null);
|
|
|
- mCamera.setPreviewCallback(null);
|
|
|
- mCamera.stopPreview();
|
|
|
- } catch (RuntimeException e) {
|
|
|
- e.printStackTrace();
|
|
|
- } catch (Exception e) {
|
|
|
- e.printStackTrace();
|
|
|
- } finally {
|
|
|
- CameraUtils.releaseCamera(mCamera);
|
|
|
- mCamera = null;
|
|
|
- }
|
|
|
- }
|
|
|
- if (mSurfaceHolder != null) {
|
|
|
- mSurfaceHolder.removeCallback(this);
|
|
|
- }
|
|
|
- if (mILivenessStrategy != null) {
|
|
|
- mILivenessStrategy = null;
|
|
|
- }
|
|
|
- }
|
|
|
-
|
|
|
- private int displayOrientation(Context context) {
|
|
|
- WindowManager windowManager = (WindowManager) context.getSystemService(Context.WINDOW_SERVICE);
|
|
|
- int rotation = windowManager.getDefaultDisplay().getRotation();
|
|
|
- int degrees = 0;
|
|
|
- switch (rotation) {
|
|
|
- case Surface.ROTATION_0:
|
|
|
- degrees = 0;
|
|
|
- break;
|
|
|
- case Surface.ROTATION_90:
|
|
|
- degrees = 90;
|
|
|
- break;
|
|
|
- case Surface.ROTATION_180:
|
|
|
- degrees = 180;
|
|
|
- break;
|
|
|
- case Surface.ROTATION_270:
|
|
|
- degrees = 270;
|
|
|
- break;
|
|
|
- default:
|
|
|
- degrees = 0;
|
|
|
- break;
|
|
|
- }
|
|
|
- int result = (0 - degrees + 360) % 360;
|
|
|
- if (APIUtils.hasGingerbread()) {
|
|
|
- Camera.CameraInfo info = new Camera.CameraInfo();
|
|
|
- Camera.getCameraInfo(mCameraId, info);
|
|
|
- if (info.facing == Camera.CameraInfo.CAMERA_FACING_FRONT) {
|
|
|
- result = (info.orientation + degrees) % 360;
|
|
|
- result = (360 - result) % 360;
|
|
|
- } else {
|
|
|
- result = (info.orientation - degrees + 360) % 360;
|
|
|
- }
|
|
|
- }
|
|
|
- return result;
|
|
|
- }
|
|
|
-
|
|
|
- @Override
|
|
|
- public void surfaceCreated(SurfaceHolder holder) {
|
|
|
- mIsCreateSurface = true;
|
|
|
- }
|
|
|
-
|
|
|
- @Override
|
|
|
- public void surfaceChanged(SurfaceHolder holder,
|
|
|
- int format,
|
|
|
- int width,
|
|
|
- int height) {
|
|
|
- mSurfaceWidth = width;
|
|
|
- mSurfaceHeight = height;
|
|
|
- if (holder.getSurface() == null) {
|
|
|
- return;
|
|
|
- }
|
|
|
- startPreview();
|
|
|
- }
|
|
|
-
|
|
|
- @Override
|
|
|
- public void surfaceDestroyed(SurfaceHolder holder) {
|
|
|
- mIsCreateSurface = false;
|
|
|
- }
|
|
|
-
|
|
|
- @Override
|
|
|
- public void onPreviewFrame(byte[] data, Camera camera) {
|
|
|
-
|
|
|
- if (mIsCompletion) {
|
|
|
- return;
|
|
|
- }
|
|
|
-
|
|
|
- if (mILivenessStrategy == null) {
|
|
|
- mILivenessStrategy = FaceSDKManager.getInstance().getLivenessStrategyModule();
|
|
|
- mILivenessStrategy.setPreviewDegree(mPreviewDegree);
|
|
|
- mILivenessStrategy.setLivenessStrategySoundEnable(mIsEnableSound);
|
|
|
-
|
|
|
- Rect detectRect = FaceDetectRoundView.getPreviewDetectRect(
|
|
|
- mDisplayWidth, mPreviewHight, mPreviewWidth);
|
|
|
- mILivenessStrategy.setLivenessStrategyConfig(
|
|
|
- mFaceConfig.getLivenessTypeList(), mPreviewRect, detectRect, this);
|
|
|
- }
|
|
|
- mILivenessStrategy.livenessStrategy(data);
|
|
|
- }
|
|
|
-
|
|
|
- @Override
|
|
|
- public void onError(int error, Camera camera) {
|
|
|
- }
|
|
|
-
|
|
|
- @Override
|
|
|
- public void onLivenessCompletion(FaceStatusEnum status, String message,
|
|
|
- HashMap<String, String> base64ImageMap) {
|
|
|
- if (mIsCompletion) {
|
|
|
- return;
|
|
|
- }
|
|
|
-
|
|
|
- onRefreshView(status, message);
|
|
|
- if (status == FaceStatusEnum.OK) {
|
|
|
- Ast.getInstance().faceHit();
|
|
|
- mIsCompletion = true;
|
|
|
- saveImage(base64ImageMap);
|
|
|
- }
|
|
|
- }
|
|
|
-
|
|
|
- private void onRefreshView(FaceStatusEnum status, String message) {
|
|
|
- switch (status) {
|
|
|
- case OK:
|
|
|
- case Liveness_OK:
|
|
|
- case Liveness_Completion:
|
|
|
- onRefreshTipsView(false, message);
|
|
|
- mFaceDetectRoundView.onRefreshSuccessView(true);
|
|
|
- break;
|
|
|
- case Detect_DataNotReady:
|
|
|
- case Liveness_Eye:
|
|
|
- case Liveness_Mouth:
|
|
|
- case Liveness_HeadUp:
|
|
|
- case Liveness_HeadDown:
|
|
|
- case Liveness_HeadLeft:
|
|
|
- case Liveness_HeadRight:
|
|
|
- case Liveness_HeadLeftRight:
|
|
|
- onRefreshTipsView(false, message);
|
|
|
- mFaceDetectRoundView.onRefreshSuccessView(false);
|
|
|
- break;
|
|
|
- case Detect_PitchOutOfUpMaxRange:
|
|
|
- case Detect_PitchOutOfDownMaxRange:
|
|
|
- case Detect_PitchOutOfLeftMaxRange:
|
|
|
- case Detect_PitchOutOfRightMaxRange:
|
|
|
- onRefreshTipsView(true, message);
|
|
|
- mFaceDetectRoundView.onRefreshSuccessView(false);
|
|
|
- break;
|
|
|
- case Error_LivenessTimeout:
|
|
|
- case Error_Timeout:
|
|
|
- case Error_DetectTimeout:
|
|
|
- errorTimeOut();
|
|
|
- onRefreshTipsView(false, message);
|
|
|
- break;
|
|
|
- default:
|
|
|
- onRefreshTipsView(false, message);
|
|
|
- mFaceDetectRoundView.onRefreshSuccessView(false);
|
|
|
- }
|
|
|
- }
|
|
|
-
|
|
|
-
|
|
|
- //提示信息
|
|
|
- private void onRefreshTipsView(boolean isAlert, String message) {
|
|
|
- mFaceDetectRoundView.onRefreshTipsView(message);
|
|
|
-
|
|
|
- if (isAlert) {
|
|
|
- if (mTipsIcon == null) {
|
|
|
- mTipsIcon = getResources().getDrawable(R.mipmap.ic_warning);
|
|
|
- mTipsIcon.setBounds(0, 0, (int) (mTipsIcon.getMinimumWidth() * 0.7f),
|
|
|
- (int) (mTipsIcon.getMinimumHeight() * 0.7f));
|
|
|
- mTipsTopView.setCompoundDrawablePadding(15);
|
|
|
- }
|
|
|
-// mTipsTopView.setBackgroundResource(R.drawable.bg_tips);
|
|
|
- mTipsTopView.setText(R.string.detect_standard);
|
|
|
- mTipsTopView.setCompoundDrawables(mTipsIcon, null, null, null);
|
|
|
- } else {
|
|
|
-// mTipsTopView.setBackgroundResource(R.drawable.bg_tips_no);
|
|
|
- mTipsTopView.setCompoundDrawables(null, null, null, null);
|
|
|
- if (!TextUtils.isEmpty(message)) {
|
|
|
- mTipsTopView.setText(message);
|
|
|
- }
|
|
|
- }
|
|
|
- }
|
|
|
-
|
|
|
-
|
|
|
- private void saveImage(HashMap<String, String> imageMap) {
|
|
|
- Set<Map.Entry<String, String>> sets = imageMap.entrySet();
|
|
|
- for (Map.Entry<String, String> entry : sets) {
|
|
|
- String bmpBase64 = entry.getValue();
|
|
|
- if (!TextUtils.isEmpty(bmpBase64)) {
|
|
|
- saveBmpBase64Ok(bmpBase64);
|
|
|
- break;
|
|
|
- }
|
|
|
- }
|
|
|
- }
|
|
|
-
|
|
|
- private static Bitmap base64ToBitmap(String base64Data) {
|
|
|
- byte[] bytes = Base64Utils.decode(base64Data, Base64Utils.NO_WRAP);
|
|
|
- return BitmapFactory.decodeByteArray(bytes, 0, bytes.length);
|
|
|
- }
|
|
|
-
|
|
|
- /**
|
|
|
- * 重新开启
|
|
|
- */
|
|
|
- public void reSetDetect() {
|
|
|
- mIsCompletion = false;
|
|
|
- mILivenessStrategy = null;
|
|
|
- startPreview();
|
|
|
- }
|
|
|
-
|
|
|
- public abstract void saveBmpBase64Ok(String bmpBase64);
|
|
|
-
|
|
|
- public abstract void errorTimeOut();
|
|
|
-
|
|
|
-}
|