Просмотр исходного кода

提交类型 修复bug
提交内容 处理外勤等界面在选择时间弹框弹出来的时候没有选择时间的情况下出现 时大约24的情况

Bitliker 7 лет назад
Родитель
Сommit
514411bcd4
43 измененных файлов с 3394 добавлено и 1139 удалено
  1. 6 2
      WeiChat/build.gradle
  2. 2 1
      WeiChat/src/main/java/com/xzjmyk/pm/activity/ui/MainActivity.java
  3. 3 2
      WeiChat/src/main/java/com/xzjmyk/pm/activity/ui/message/MessageFragment.java
  4. 2 2
      WeiChat/version.properties
  5. 2 2
      app_modular/apputils/src/main/java/com/modular/apputils/widget/VeriftyDialog.java
  6. 0 2
      app_modular/faceplatform-release/build.gradle
  7. 9 7
      app_modular/faceplatform-ui/build.gradle
  8. 0 0
      app_modular/faceplatform-ui/libs/faceplatform-release.aar
  9. 0 17
      app_modular/faceplatform-ui/proguard-rules.pro
  10. 6 5
      app_modular/faceplatform-ui/src/main/AndroidManifest.xml
  11. 31 0
      app_modular/faceplatform-ui/src/main/java/com/baidu/aip/face/ArgbPool.java
  12. 86 0
      app_modular/faceplatform-ui/src/main/java/com/baidu/aip/face/CameraImageSource.java
  13. 44 0
      app_modular/faceplatform-ui/src/main/java/com/baidu/aip/face/DetectRegionProcessor.java
  14. 89 0
      app_modular/faceplatform-ui/src/main/java/com/baidu/aip/face/FaceCropper.java
  15. 175 0
      app_modular/faceplatform-ui/src/main/java/com/baidu/aip/face/FaceDetectManager.java
  16. 246 0
      app_modular/faceplatform-ui/src/main/java/com/baidu/aip/face/FaceFilter.java
  17. 17 0
      app_modular/faceplatform-ui/src/main/java/com/baidu/aip/face/FaceProcessor.java
  18. 120 0
      app_modular/faceplatform-ui/src/main/java/com/baidu/aip/face/FileImageSource.java
  19. 78 0
      app_modular/faceplatform-ui/src/main/java/com/baidu/aip/face/ImageFrame.java
  20. 50 0
      app_modular/faceplatform-ui/src/main/java/com/baidu/aip/face/ImageSource.java
  21. 15 0
      app_modular/faceplatform-ui/src/main/java/com/baidu/aip/face/OnFrameAvailableListener.java
  22. 65 0
      app_modular/faceplatform-ui/src/main/java/com/baidu/aip/face/PreviewView.java
  23. 194 0
      app_modular/faceplatform-ui/src/main/java/com/baidu/aip/face/TexturePreviewView.java
  24. 415 0
      app_modular/faceplatform-ui/src/main/java/com/baidu/aip/face/camera/Camera1Control.java
  25. 769 0
      app_modular/faceplatform-ui/src/main/java/com/baidu/aip/face/camera/Camera2Control.java
  26. 156 0
      app_modular/faceplatform-ui/src/main/java/com/baidu/aip/face/camera/CameraView.java
  27. 135 0
      app_modular/faceplatform-ui/src/main/java/com/baidu/aip/face/camera/ICameraControl.java
  28. 8 0
      app_modular/faceplatform-ui/src/main/java/com/baidu/aip/face/camera/PermissionCallback.java
  29. 0 521
      app_modular/faceplatform-ui/src/main/java/com/baidu/idl/face/platform/ui/FaceDetectActivity.java
  30. 0 526
      app_modular/faceplatform-ui/src/main/java/com/baidu/idl/face/platform/ui/FaceLivenessActivity.java
  31. 2 2
      app_modular/faceplatform-ui/src/main/java/com/baidu/idl/face/platform/ui/FaceSDKResSettings.java
  32. 535 0
      app_modular/faceplatform-ui/src/main/java/com/baidu/idl/face/platform/ui/activity/FaceDetectActivity.java
  33. 16 16
      app_modular/faceplatform-ui/src/main/java/com/baidu/idl/face/platform/ui/activity/FaceVeriftyActivity.java
  34. 3 6
      app_modular/faceplatform-ui/src/main/java/com/baidu/idl/face/platform/ui/config/FaceConfig.java
  35. 3 3
      app_modular/faceplatform-ui/src/main/java/com/baidu/idl/face/platform/ui/utils/BrightnessTools.java
  36. 2 2
      app_modular/faceplatform-ui/src/main/java/com/baidu/idl/face/platform/ui/utils/CameraUtils.java
  37. 2 2
      app_modular/faceplatform-ui/src/main/java/com/baidu/idl/face/platform/ui/utils/VolumeUtils.java
  38. 24 10
      app_modular/faceplatform-ui/src/main/java/com/baidu/idl/face/platform/ui/widget/FaceRoundView.java
  39. 2 3
      app_modular/faceplatform-ui/src/main/res/layout/activity_face_detect_v3100.xml
  40. 57 0
      app_modular/faceplatform-ui/src/main/res/layout/activity_login_detected.xml
  41. 11 0
      app_modular/faceplatform-ui/src/main/res/values/dimens.xml
  42. 12 6
      app_modular/faceplatform-ui/src/main/res/values/strings.xml
  43. 2 2
      settings.gradle

+ 6 - 2
WeiChat/build.gradle

@@ -145,7 +145,11 @@ android {
         }
     }*/
 }
-
+repositories {
+    flatDir {
+        dirs 'libs', project(':faceplatform-ui').file('libs')
+    }
+}
 dependencies {
     compile fileTree(include: ['*.jar'], dir: 'libs')
     testCompile deps.junit
@@ -180,7 +184,7 @@ dependencies {
     compile project(':appbooking')
     compile project(':appmusic')
     compile project(':apputils')
-//    compile project(':faceplatform-ui')
+    compile project(':faceplatform-ui')
     compile 'com.android.support.constraint:constraint-layout:1.0.2'
     compile 'com.android.support:support-v4:26.+'
 }

+ 2 - 1
WeiChat/src/main/java/com/xzjmyk/pm/activity/ui/MainActivity.java

@@ -43,6 +43,7 @@ import com.baidu.android.pushservice.PushConstants;
 import com.baidu.android.pushservice.PushManager;
 import com.baidu.autoupdatesdk.BDAutoUpdateSDK;
 import com.baidu.autoupdatesdk.UICheckUpdateCallback;
+import com.baidu.idl.face.platform.ui.config.FaceConfig;
 import com.common.LogUtil;
 import com.common.data.DateFormatUtil;
 import com.common.data.ListUtils;
@@ -633,7 +634,7 @@ public class MainActivity extends BaseActivity implements ImStatusListener, NetW
         LogUtil.d("OnCreate end:" + DateFormatUtil.long2Str(DateFormatUtil.YMD_HMS));
 
         //初始化面部识别
-//        FaceConfig.initFace(ct);
+        FaceConfig.initFace(ct);
 
     }
 

+ 3 - 2
WeiChat/src/main/java/com/xzjmyk/pm/activity/ui/message/MessageFragment.java

@@ -19,6 +19,7 @@ import android.widget.ImageButton;
 import android.widget.LinearLayout;
 import android.widget.PopupWindow;
 
+import com.baidu.idl.face.platform.ui.activity.FaceVeriftyActivity;
 import com.common.data.DateFormatUtil;
 import com.common.data.ListUtils;
 import com.common.data.StringUtil;
@@ -330,8 +331,8 @@ public class MessageFragment extends SupportToolBarFragment implements IMessageV
                 break;
 
             case R.id.itemSignImage:
-                sign(true);
-//                startActivityForResult(new Intent(ct, FaceVeriftyActivity.class), 0x223);
+//                sign(true);
+                startActivityForResult(new Intent(ct, FaceVeriftyActivity.class), 0x223);
                 break;
         }
 

+ 2 - 2
WeiChat/version.properties

@@ -1,5 +1,5 @@
 #Wed Jun 13 11:08:53 CST 2018
 debugName=502
-versionName=632
+versionName=633
 debugCode=502
-versionCode=173
+versionCode=174

+ 2 - 2
app_modular/faceplatform-ui/src/main/java/com/baidu/idl/face/platform/ui/widget/VeriftyDialog.java → app_modular/apputils/src/main/java/com/modular/apputils/widget/VeriftyDialog.java

@@ -1,4 +1,4 @@
-package com.baidu.idl.face.platform.ui.widget;
+package com.modular.apputils.widget;
 
 import android.app.Dialog;
 import android.content.Context;
@@ -13,7 +13,7 @@ import android.view.ViewGroup;
 import android.view.Window;
 import android.widget.TextView;
 
-import com.baidu.idl.face.platform.ui.R;
+import com.modular.apputils.R;
 
 import java.io.Serializable;
 

+ 0 - 2
app_modular/faceplatform-release/build.gradle

@@ -1,2 +0,0 @@
-configurations.maybeCreate("default")
-artifacts.add("default", file('faceplatform-release.aar'))

+ 9 - 7
app_modular/faceplatform-ui/build.gradle

@@ -1,6 +1,3 @@
-/*
- * Copyright (C) 2017 Baidu, Inc. All Rights Reserved.
- */
 apply plugin: 'com.android.library'
 
 android {
@@ -10,8 +7,8 @@ android {
     defaultConfig {
         minSdkVersion rootProject.ext.android.minSdkVersion
         targetSdkVersion rootProject.ext.android.targetSdkVersion
-        versionCode 1
-        versionName "1.0"
+        versionCode rootProject.ext.android.versionCode
+        versionName rootProject.ext.android.versionName
     }
     buildTypes {
         release {
@@ -21,10 +18,15 @@ android {
     }
 }
 
-
+repositories {
+    flatDir {
+        dirs 'libs'
+    }
+}
 
 dependencies {
     compile fileTree(dir: 'libs', include: ['*.jar'])
+    compile files('libs/ast.jar')
+    compile(name:'faceplatform-release', ext:'aar')
     compile project(':apputils')
-    compile project(path: ':faceplatform-release')
 }

+ 0 - 0
app_modular/faceplatform-release/faceplatform-release.aar → app_modular/faceplatform-ui/libs/faceplatform-release.aar


+ 0 - 17
app_modular/faceplatform-ui/proguard-rules.pro

@@ -1,17 +0,0 @@
-# Add project specific ProGuard rules here.
-# By default, the flags in this file are appended to flags specified
-# in /Users/baidu/Documents/android/android_sdk_mac/tools/proguard/proguard-android.txt
-# You can edit the include path and order by changing the proguardFiles
-# directive in build.gradle.
-#
-# For more details, see
-#   http://developer.android.com/guide/developing/tools/proguard.html
-
-# Add any project specific detect_keep options here:
-
-# If your project uses WebView with JS, uncomment the following
-# and specify the fully qualified class name to the JavaScript interface
-# class:
-#-keepclassmembers class fqcn.of.javascript.interface.for.webview {
-#   public *;
-#}

+ 6 - 5
app_modular/faceplatform-ui/src/main/AndroidManifest.xml

@@ -1,11 +1,12 @@
+<!--
+  ~ Copyright (C) 2017 Baidu, Inc. All Rights Reserved.
+  -->
 <manifest xmlns:android="http://schemas.android.com/apk/res/android"
     package="com.baidu.idl.face.platform.ui">
 
-    <application android:label="@string/app_name" >
-
-
-        <activity android:name=".FaceLivenessActivity"/>
-        <activity android:name=".FaceVeriftyActivity"/>
+    <uses-permission android:name="android.permission.CAMERA"/>
+    <application >
+        <activity android:name=".activity.FaceVeriftyActivity"/>
     </application>
 
 </manifest>

+ 31 - 0
app_modular/faceplatform-ui/src/main/java/com/baidu/aip/face/ArgbPool.java

@@ -0,0 +1,31 @@
+/*
+ * Copyright (C) 2017 Baidu, Inc. All Rights Reserved.
+ */
+package com.baidu.aip.face;
+
+import android.support.v4.util.Pools;
+
+public class ArgbPool {
+
+    Pools.SynchronizedPool<int[]> pool = new Pools.SynchronizedPool<>(5);
+
+    public ArgbPool() {
+
+    }
+
+    public int[] acquire(int width, int height) {
+        int[] argb = pool.acquire();
+        if (argb == null || argb.length != width * height) {
+            argb = new int[width * height];
+        }
+        return argb;
+    }
+
+    public void release(int[] data) {
+        try {
+            pool.release(data);
+        } catch (IllegalStateException ignored) {
+            // ignored
+        }
+    }
+}

+ 86 - 0
app_modular/faceplatform-ui/src/main/java/com/baidu/aip/face/CameraImageSource.java

@@ -0,0 +1,86 @@
+/*
+ * Copyright (C) 2017 Baidu, Inc. All Rights Reserved.
+ */
+package com.baidu.aip.face;
+
+import java.util.ArrayList;
+
+import com.baidu.aip.face.camera.Camera1Control;
+import com.baidu.aip.face.camera.ICameraControl;
+import com.baidu.idl.facesdk.FaceSDK;
+
+import android.content.Context;
+
+/**
+ * 封装了系统做机做为输入源。
+ */
+public class CameraImageSource extends ImageSource {
+
+    //    private int[] argb = null;
+
+    private ICameraControl cameraControl;
+    private Context context;
+
+    public ICameraControl getCameraControl() {
+        return cameraControl;
+    }
+
+    private ArgbPool argbPool = new ArgbPool();
+
+    public CameraImageSource(Context context) {
+        this.context = context;
+        cameraControl = new Camera1Control(getContext());
+        cameraControl.setCameraFacing(ICameraControl.CAMERA_FACING_FRONT);
+        cameraControl.setOnFrameListener(new ICameraControl.OnFrameListener<byte[]>() {
+            @Override
+            public void onPreviewFrame(byte[] data, int rotation, int width, int height) {
+                int[] argb = argbPool.acquire(width, height);
+
+                if (argb == null || argb.length != width * height) {
+                    argb = new int[width * height];
+                }
+                rotation = rotation < 0 ? 360 + rotation : rotation;
+                FaceSDK.getARGBFromYUVimg(data, argb,
+                        width, height,
+                        rotation, 0);
+
+                // 旋转了90或270度。高宽需要替换
+                if (rotation % 180 == 90) {
+                    int temp = width;
+                    width = height;
+                    height = temp;
+                }
+                ImageFrame frame = new ImageFrame();
+                frame.setArgb(argb);
+                frame.setWidth(width);
+                frame.setHeight(height);
+                frame.setPool(argbPool);
+                ArrayList<OnFrameAvailableListener> listeners = getListeners();
+                for (OnFrameAvailableListener listener : listeners) {
+                    listener.onFrameAvailable(frame);
+                }
+            }
+        });
+    }
+
+    @Override
+    public void start() {
+        super.start();
+        cameraControl.start();
+    }
+
+    @Override
+    public void stop() {
+        super.stop();
+        cameraControl.stop();
+    }
+
+    private Context getContext() {
+        return context;
+    }
+
+    @Override
+    public void setPreviewView(PreviewView previewView) {
+        cameraControl.setPreviewView(previewView);
+    }
+}

+ 44 - 0
app_modular/faceplatform-ui/src/main/java/com/baidu/aip/face/DetectRegionProcessor.java

@@ -0,0 +1,44 @@
+/*
+ * Copyright (C) 2017 Baidu, Inc. All Rights Reserved.
+ */
+package com.baidu.aip.face;
+
+import android.graphics.Rect;
+import android.graphics.RectF;
+
+/**
+ * 裁剪一定区域内的图片进行检测。
+ */
+public class DetectRegionProcessor implements FaceProcessor {
+
+    private RectF detectedRect;
+
+    private RectF originalCoordinate = new RectF();
+
+    /**
+     * 设置裁剪的区域。该区域内的图片被会裁剪进行检测,其余会被抛弃。
+     * @param rect 检测区域
+     */
+    public void setDetectedRect(RectF rect) {
+        detectedRect = rect;
+    }
+
+    private Rect cropRect = new Rect();
+
+    @Override
+    public boolean process(FaceDetectManager faceDetectManager, ImageFrame frame) {
+        if (detectedRect != null) {
+            originalCoordinate.set(detectedRect);
+            CameraImageSource cam = (CameraImageSource) faceDetectManager.getImageSource(); // TODO
+            cam.getCameraControl().getPreviewView().mapToOriginalRect(originalCoordinate);
+            cropRect.left = (int) originalCoordinate.left;
+            cropRect.top = (int) originalCoordinate.top;
+            cropRect.right = (int) originalCoordinate.right;
+            cropRect.bottom = (int) originalCoordinate.bottom;
+            frame.setArgb(FaceCropper.crop(frame.getArgb(), frame.getWidth(), cropRect));
+            frame.setWidth(cropRect.width());
+            frame.setHeight(cropRect.height());
+        }
+        return false;
+    }
+}

+ 89 - 0
app_modular/faceplatform-ui/src/main/java/com/baidu/aip/face/FaceCropper.java

@@ -0,0 +1,89 @@
+/*
+ * Copyright (C) 2017 Baidu, Inc. All Rights Reserved.
+ */
+package com.baidu.aip.face;
+
+import android.graphics.Bitmap;
+import android.graphics.Rect;
+
+import com.baidu.idl.facesdk.FaceInfo;
+
+/**
+ *人脸裁剪工具类。
+ */
+public class FaceCropper {
+
+    /**
+     * 高速裁剪狂,防止框超出图片范围。
+     * @param argb 图片argb数据
+     * @param width 图片宽度
+     * @param rect 裁剪框
+     */
+    public static void adjustRect(int[] argb, int width, Rect rect) {
+        rect.left = Math.max(rect.left ,0);
+        rect.right = Math.min(rect.right,width);
+        int height = argb.length / width;
+        rect.bottom = Math.min(rect.bottom,height);
+        rect.sort();
+    }
+
+    /**
+     * 裁剪argb中的一块儿,裁剪框如果超出图片范围会被调整,所以记得检查。
+     * @param argb 图片argb数据
+     * @param width 图片宽度
+     * @param rect 裁剪框
+     */
+    public static int[] crop(int[] argb, int width, Rect rect) {
+        adjustRect(argb, width, rect);
+        int[] image = new int[rect.width() * rect.height()];
+
+        for (int i = rect.top; i < rect.bottom; i++) {
+            int rowIndex = width * i;
+            try {
+                System.arraycopy(argb, rowIndex + rect.left, image, rect.width() * (i - rect.top), rect.width());
+            } catch (Exception e) {
+                e.printStackTrace();
+                return argb;
+            }
+        }
+        return image;
+    }
+
+    /**
+     * 裁剪图片中的人脸。
+     * @param argb argb图片数据
+     * @param faceInfo 人脸信息
+     * @param imageWidth 图片宽度
+     * @return 返回裁剪后的人脸图片
+     */
+    public static Bitmap getFace(int[] argb, FaceInfo faceInfo, int imageWidth) {
+        int[] points = new int[8];
+
+        faceInfo.getRectPoints(points);
+
+        int left = points[2];
+        int top = points[3];
+        int right = points[6];
+        int bottom = points[7];
+
+        int width = right - left;
+        int height = bottom - top;
+
+        width = width * 3 / 2;
+        height = height * 2;
+        //
+        left = faceInfo.mCenter_x - width / 2;
+        top = faceInfo.mCenter_y - height / 2;
+
+        height = height * 4 / 5;
+        //
+        left = Math.max(left, 0);
+        top = Math.max(top, 0);
+
+        Rect region = new Rect(left, top, left + width, top + height);
+        FaceCropper.adjustRect(argb, imageWidth, region);
+        int offset = region.top * imageWidth + region.left;
+        return Bitmap.createBitmap(argb,offset,imageWidth,region.width(),region.height(),
+                Bitmap.Config.ARGB_8888);
+    }
+}

+ 175 - 0
app_modular/faceplatform-ui/src/main/java/com/baidu/aip/face/FaceDetectManager.java

@@ -0,0 +1,175 @@
+/*
+ * Copyright (C) 2017 Baidu, Inc. All Rights Reserved.
+ */
+package com.baidu.aip.face;
+
+import android.content.Context;
+import android.os.Handler;
+import android.os.HandlerThread;
+import android.util.Log;
+
+import com.baidu.aip.face.stat.Ast;
+import com.baidu.idl.face.platform.FaceSDKManager;
+import com.baidu.idl.facesdk.FaceInfo;
+import com.baidu.idl.facesdk.FaceSDK;
+import com.baidu.idl.facesdk.FaceTracker;
+
+import java.util.ArrayList;
+
+/**
+ * 封装了人脸检测的整体逻辑。
+ */
+public class FaceDetectManager {
+    /**
+     * 该回调用于回调,人脸检测结果。当没有人脸时,infos 为null,status为 FaceDetector.DETECT_CODE_NO_FACE_DETECTED
+     */
+    public interface OnFaceDetectListener {
+        void onDetectFace(int status, FaceInfo[] infos, ImageFrame imageFrame);
+    }
+
+    public FaceDetectManager(Context context) {
+        Ast.getInstance().init(context.getApplicationContext(), "3.1.0.0", "facelogin");
+    }
+
+    /**
+     * 图片源,获取检测图片。
+     */
+    private ImageSource imageSource;
+    /**
+     * 人脸检测事件监听器
+     */
+    private OnFaceDetectListener listener;
+    private FaceFilter faceFilter = new FaceFilter();
+    private HandlerThread processThread;
+    private Handler processHandler;
+    private ImageFrame lastFrame;
+
+    private ArrayList<FaceProcessor> preProcessors = new ArrayList<>();
+
+    /**
+     * 设置人脸检测监听器,检测后的结果会回调。
+     *
+     * @param listener 监听器
+     */
+    public void setOnFaceDetectListener(OnFaceDetectListener listener) {
+        this.listener = listener;
+    }
+
+    /**
+     * 设置图片帧来源
+     *
+     * @param imageSource 图片来源
+     */
+    public void setImageSource(ImageSource imageSource) {
+        this.imageSource = imageSource;
+    }
+
+    /**
+     * @return 返回图片来源
+     */
+    public ImageSource getImageSource() {
+        return this.imageSource;
+    }
+
+    /**
+     * 增加处理回调,在人脸检测前会被回调。
+     *
+     * @param processor 图片帧处理回调
+     */
+    public void addPreProcessor(FaceProcessor processor) {
+        preProcessors.add(processor);
+    }
+
+    /**
+     * 设置人检跟踪回调。
+     *
+     * @param onTrackListener 人脸回调
+     */
+    public void setOnTrackListener(FaceFilter.OnTrackListener onTrackListener) {
+        faceFilter.setOnTrackListener(onTrackListener);
+    }
+
+    /**
+     * @return 返回过虑器
+     */
+    public FaceFilter getFaceFilter() {
+        return faceFilter;
+    }
+
+    public void start() {
+        this.imageSource.addOnFrameAvailableListener(onFrameAvailableListener);
+        processThread = new HandlerThread("process");
+        processThread.start();
+        processHandler = new Handler(processThread.getLooper());
+        this.imageSource.start();
+    }
+
+    private Runnable processRunnable = new Runnable() {
+        @Override
+        public void run() {
+            if (lastFrame == null) {
+                return;
+            }
+            int[] argb;
+            int width;
+            int height;
+            ArgbPool pool;
+            synchronized (lastFrame) {
+                argb = lastFrame.getArgb();
+                width = lastFrame.getWidth();
+                height = lastFrame.getHeight();
+                pool = lastFrame.getPool();
+                lastFrame = null;
+            }
+            process(argb, width, height, pool);
+        }
+    };
+
+    public void stop() {
+        this.imageSource.stop();
+        this.imageSource.removeOnFrameAvailableListener(onFrameAvailableListener);
+        if (processThread != null) {
+            processThread.quit();
+            processThread = null;
+        }
+        Ast.getInstance().immediatelyUpload();
+    }
+
+    private void process(int[] argb, int width, int height, ArgbPool pool) {
+        int value;
+
+        ImageFrame frame = imageSource.borrowImageFrame();
+        frame.setArgb(argb);
+        frame.setWidth(width);
+        frame.setHeight(height);
+        frame.setPool(pool);
+        //        frame.retain();
+
+        for (FaceProcessor processor : preProcessors) {
+            if (processor.process(this, frame)) {
+                break;
+            }
+        }
+        value = FaceSDKManager.getInstance().getFaceTracker()
+                .prepare_max_face_data_for_verify(frame.getArgb(), frame.getHeight(), frame.getWidth(),
+                        FaceSDK.ImgType.ARGB.ordinal(), FaceTracker.ActionType.RECOGNIZE.ordinal());
+//         value = FaceSDKManager.getInstance().detect(frame.getArgb(), frame.getWidth(), frame.getHeight());
+        FaceInfo[] faces = FaceSDKManager.getInstance().getFaceTracker().get_TrackedFaceInfo();
+        Log.i("wtf", "process -》" + value);
+        faceFilter.filter(faces, frame);
+        if (listener != null) {
+            listener.onDetectFace(value, faces, frame);
+        }
+        Ast.getInstance().faceHit("detect", 60 * 60 * 1000, faces);
+        frame.release();
+
+    }
+
+    private OnFrameAvailableListener onFrameAvailableListener = new OnFrameAvailableListener() {
+        @Override
+        public void onFrameAvailable(ImageFrame imageFrame) {
+            lastFrame = imageFrame;
+            processHandler.post(processRunnable);
+        }
+    };
+}

+ 246 - 0
app_modular/faceplatform-ui/src/main/java/com/baidu/aip/face/FaceFilter.java

@@ -0,0 +1,246 @@
+/*
+ * Copyright (C) 2017 Baidu, Inc. All Rights Reserved.
+ */
+package com.baidu.aip.face;
+
+import android.graphics.Bitmap;
+import android.graphics.Rect;
+import android.support.v4.util.Pools;
+import android.util.Log;
+import android.util.SparseArray;
+
+import com.baidu.idl.facesdk.FaceInfo;
+
+import java.util.ArrayList;
+import java.util.HashSet;
+import java.util.UUID;
+
+/**
+ *  过虑器,可用根据条件过虑帧。
+ */
+public class FaceFilter {
+
+    /**
+     * 人脸追踪回调。
+     */
+    public interface OnTrackListener {
+        /**
+         *  追踪到某张人脸
+         * @param trackedModel 人脸信息
+         */
+        void onTrack(TrackedModel trackedModel);
+    }
+
+    /**
+     * 人脸追踪事件。
+     */
+    public enum Event {
+        /**
+         * 人脸第一次进入检测区域。
+         */
+        OnEnter,
+        /**
+         * 人脸没有离开检测区域。人脸检测更新。
+         */
+        OnUpdate,
+        /**
+         * 该人脸离开了检测区域,或者丢失了跟踪。
+         */
+        OnLeave,
+    }
+
+    public class TrackedModel {
+        private String trackId;
+        private ImageFrame frame;
+        private FaceInfo info;
+        private Event event;
+
+        public ImageFrame getImageFrame() {
+            return getFrame();
+        }
+
+        /**
+         * 对应的事件
+         */
+        public Event getEvent() {
+            return event;
+        }
+
+        /**
+         * 是否符合过虑标准
+         * @return 符合过虑标准
+         */
+        public boolean meetCriteria() {
+            float pitch = Math.abs(getInfo().headPose[0]);
+            float yaw = Math.abs(getInfo().headPose[1]);
+            float roll = Math.abs(getInfo().headPose[2]);
+            return pitch < angle && yaw < angle && roll < angle;
+        }
+
+        public Bitmap cropFace() {
+            return cropFace(getFaceRect());
+        }
+
+        /**
+         * 裁剪人脸图片。
+         * @param rect 裁剪区域。如果区域超出人脸,区域会被调整。
+         * @return 裁剪后的人脸图片。
+         */
+        public Bitmap cropFace(Rect rect) {
+            return FaceCropper.getFace(getFrame().getArgb(), info, getFrame().getWidth());
+            // int[] argb = FaceCropper.crop(getFrame().getArgb(), getFrame().getWidth(), rect);
+            // return Bitmap.createBitmap(argb, rect.width(), rect.height(), Bitmap.Config.ARGB_8888);
+        }
+
+        @Override
+        public int hashCode() {
+            return getInfo().face_id;
+        }
+
+        int[] points = new int[8];
+
+        /**
+         * 获取人脸框区域。
+         * @return 人脸框区域
+         */
+        // TODO padding?
+        public Rect getFaceRect() {
+            Rect rect = new Rect();
+            getInfo().getRectPoints(points);
+
+            int left = points[2];
+            int top = points[3];
+            int right = points[6];
+            int bottom = points[7];
+            //
+            int width = (right - left) * 7 / 3;
+            int height = (bottom - top) * 7 / 3;
+
+            left = getInfo().mCenter_x - width / 2;
+            top = getInfo().mCenter_y - height / 2;
+
+
+            rect.top = top < 0 ? 0 : top;
+            rect.left = left < 0 ? 0 : left;
+            rect.right = (left + width) > frame.getWidth() ? frame.getWidth() : (left + width) ;
+            rect.bottom = (top + height) > frame.getHeight() ? frame.getHeight() : (top + height);
+
+            return rect;
+        }
+
+        /**
+         * 标识一张人脸的追踪id。
+         */
+        public String getTrackId() {
+            return trackId;
+        }
+
+        public void setTrackId(String trackId) {
+            this.trackId = trackId;
+        }
+
+        /**
+         * 对应的帧
+         */
+        public ImageFrame getFrame() {
+            return frame;
+        }
+
+        public void setFrame(ImageFrame frame) {
+            this.frame = frame;
+        }
+
+        /**
+         * 人脸检测数据
+         */
+        public FaceInfo getInfo() {
+            return info;
+        }
+
+        public void setInfo(FaceInfo info) {
+            this.info = info;
+        }
+
+        public void setEvent(Event event) {
+            this.event = event;
+        }
+    }
+
+    private OnTrackListener onTrackListener;
+
+    private SparseArray<TrackedModel> trackingFaces = new SparseArray<>();
+    private Pools.SynchronizedPool<TrackedModel> pool = new Pools.SynchronizedPool<>(5);
+
+    private HashSet<TrackedModel> currentFrame = new HashSet<>();
+    private ArrayList<Integer> leftFaces = new ArrayList<>();
+
+    private int angle = 15;
+
+    /**
+     * 设置过虑角度。参见人脸欧拉角;
+     * @param angle 欧拉角
+     */
+    public void setAngle(int angle) {
+        this.angle = angle;
+    }
+
+    /**
+     * 设置跟踪监听器
+     * @param onTrackListener 跟踪监听器
+     */
+    public void setOnTrackListener(OnTrackListener onTrackListener) {
+        this.onTrackListener = onTrackListener;
+    }
+
+    public void filter(FaceInfo[] infos, ImageFrame frame) {
+        currentFrame.clear();
+        if (infos != null) {
+            for (FaceInfo faceInfo : infos) {
+                TrackedModel face = getTrackedModel(faceInfo, frame);
+                currentFrame.add(face);
+                face.setInfo(faceInfo);
+            }
+        }
+
+        leftFaces.clear();
+        for (int i = 0; i < trackingFaces.size(); i++) {
+            int key = trackingFaces.keyAt(i);
+            TrackedModel face = trackingFaces.get(key);
+            if (!currentFrame.contains(face)) {
+                leftFaces.add(key);
+            } else {
+                if (onTrackListener != null) {
+                    face.setFrame(frame);
+                    onTrackListener.onTrack(face);
+                }
+            }
+
+        }
+        for (Integer key : leftFaces) {
+            TrackedModel left = trackingFaces.get(key);
+            Log.e("xx", " left:" + left);
+            left.setEvent(Event.OnLeave);
+            trackingFaces.remove(key);
+            if (onTrackListener != null) {
+                onTrackListener.onTrack(left);
+            }
+            // TODO release argb?
+        }
+    }
+
+    private TrackedModel getTrackedModel(FaceInfo faceInfo, ImageFrame frame) {
+        TrackedModel face = trackingFaces.get(faceInfo.face_id);
+        if (face == null) {
+            face = pool.acquire();
+            if (face == null) {
+                face = new TrackedModel();
+            }
+            trackingFaces.append(faceInfo.face_id, face);
+            face.setTrackId(UUID.randomUUID().toString());
+            face.setEvent(Event.OnEnter);
+        }
+        face.setInfo(faceInfo);
+        face.setFrame(frame);
+        return face;
+    }
+}

+ 17 - 0
app_modular/faceplatform-ui/src/main/java/com/baidu/aip/face/FaceProcessor.java

@@ -0,0 +1,17 @@
+/*
+ * Copyright (C) 2017 Baidu, Inc. All Rights Reserved.
+ */
+package com.baidu.aip.face;
+
+/**
+ *  FaceDetectManager 人脸检测之前的回调。可以对图片进行预处理。如果ImageFrame中的argb数据为空,将不进行检测。
+ */
+public interface FaceProcessor {
+    /**
+     * FaceDetectManager 回调该方法,对图片帧进行处理。
+     * @param detectManager 回调的 FaceDetectManager
+     * @param frame 需要处理的图片帧。
+     * @return 返回true剩下的FaceProcessor将不会被回调。
+     */
+    boolean process(FaceDetectManager detectManager, ImageFrame frame);
+}

+ 120 - 0
app_modular/faceplatform-ui/src/main/java/com/baidu/aip/face/FileImageSource.java

@@ -0,0 +1,120 @@
+/*
+ * Copyright (C) 2017 Baidu, Inc. All Rights Reserved.
+ */
+package com.baidu.aip.face;
+
+import java.io.IOException;
+
+import com.baidu.idl.face.platform.FaceSDKManager;
+
+import android.graphics.Bitmap;
+import android.graphics.BitmapFactory;
+import android.graphics.Matrix;
+import android.media.ExifInterface;
+
+/**
+ *  从图片读取并检测人脸。
+ */
+public class FileImageSource extends ImageSource {
+
+    private String filePath;
+
+    /**
+     * 设置检测图片的位置。
+     * @param filePath 图片路径
+     */
+    public void setFilePath(String filePath) {
+        this.filePath = filePath;
+    }
+
+    @Override
+    public void start() {
+        super.start();
+        Bitmap bitmap = getImageThumbnail(filePath, 960, 960);
+        int degree = getExifOrientation(filePath);
+
+        if (degree == 90 || degree == 180 || degree == 270) {
+            Matrix matrix = new Matrix();
+            matrix.postRotate(degree);
+            bitmap = Bitmap.createBitmap(bitmap, 0, 0, bitmap.getWidth(), bitmap.getHeight(), matrix, true);
+        }
+
+        int[] argb = new int[bitmap.getWidth() * bitmap.getHeight()];
+        bitmap.getPixels(argb, 0, bitmap.getWidth(), 0, 0, bitmap.getWidth(), bitmap.getHeight());
+        FaceSDKManager.getInstance().getFaceTracker().clearTrackedFaces();
+
+        ImageFrame frame = new ImageFrame();
+        frame.setArgb(argb);
+        frame.setWidth(bitmap.getWidth());
+        frame.setHeight(bitmap.getHeight());
+
+        for (OnFrameAvailableListener listener : getListeners()) {
+            listener.onFrameAvailable(frame);
+        }
+
+        FaceSDKManager.getInstance().getFaceTracker().clearTrackedFaces();
+    }
+
+    private Bitmap getImageThumbnail(String imagePath, int width, int height) {
+        Bitmap bitmap;
+        BitmapFactory.Options options = new BitmapFactory.Options();
+        options.inJustDecodeBounds = true;
+        // 获取这个图片的宽和高,注意此处的bitmap为null
+        bitmap = BitmapFactory.decodeFile(imagePath, options);
+        options.inJustDecodeBounds = false; // 设为 false
+        // 计算缩放比
+        int h = options.outHeight;
+        int w = options.outWidth;
+        int beWidth = w / width;
+        int beHeight = h / height;
+        int be = 1;
+        if (beWidth < beHeight) {
+            be = beWidth;
+        } else {
+            be = beHeight;
+        }
+        if (be <= 0) {
+            be = 1;
+        }
+        options.inSampleSize = be;
+        options.inPreferredConfig = Bitmap.Config.ARGB_8888;
+
+        // 重新读入图片,读取缩放后的bitmap,注意这次要把options.inJustDecodeBounds 设为 false
+        bitmap = BitmapFactory.decodeFile(imagePath, options);
+        return bitmap;
+    }
+
+    private static int getExifOrientation(String filepath) {
+        int degree = 0;
+        ExifInterface exif = null;
+
+        try {
+            exif = new ExifInterface(filepath);
+        } catch (IOException ex) {
+            // MmsLog.e(ISMS_TAG, "getExifOrientation():", ex);
+        }
+
+        if (exif != null) {
+            int orientation = exif.getAttributeInt(ExifInterface.TAG_ORIENTATION, -1);
+            if (orientation != -1) {
+                // We only recognize a subset of orientation tag values.
+                switch (orientation) {
+                    case ExifInterface.ORIENTATION_ROTATE_90:
+                        degree = 90;
+                        break;
+
+                    case ExifInterface.ORIENTATION_ROTATE_180:
+                        degree = 180;
+                        break;
+
+                    case ExifInterface.ORIENTATION_ROTATE_270:
+                        degree = 270;
+                        break;
+                    default:
+                        break;
+                }
+            }
+        }
+        return degree;
+    }
+}

+ 78 - 0
app_modular/faceplatform-ui/src/main/java/com/baidu/aip/face/ImageFrame.java

@@ -0,0 +1,78 @@
+/*
+ * Copyright (C) 2017 Baidu, Inc. All Rights Reserved.
+ */
+package com.baidu.aip.face;
+
+/**
+ *  该类封装了一帧图片。
+ */
+public class ImageFrame {
+    /**
+     * argb数据
+     */
+    private int[] argb;
+    /**
+     * 图片宽度
+     */
+    private int width;
+    /**
+     * 图片调试
+     */
+    private int height;
+    private ArgbPool pool;
+    private boolean retained = false;
+
+    public ImageFrame() {
+
+    }
+
+    public void setPool(ArgbPool pool) {
+        this.pool = pool;
+    }
+
+    public ArgbPool getPool() {
+        return pool;
+    }
+
+    public ImageFrame(int[] argb, int width, int height) {
+        this.argb = argb;
+        this.width = width;
+        this.height = height;
+    }
+
+    public int[] getArgb() {
+        return argb;
+    }
+
+    public void setArgb(int[] argb) {
+        this.argb = argb;
+    }
+
+    public int getWidth() {
+        return width;
+    }
+
+    public void setWidth(int width) {
+        this.width = width;
+    }
+
+    public int getHeight() {
+        return height;
+    }
+
+    public void setHeight(int height) {
+        this.height = height;
+    }
+
+    // TODO
+    public void retain() {
+        this.retained = true;
+    }
+
+    public void release() {
+//        if (!retained) {
+//            pool.release(argb);//TODO
+//        }
+        retained = false;
+    }
+}

+ 50 - 0
app_modular/faceplatform-ui/src/main/java/com/baidu/aip/face/ImageSource.java

@@ -0,0 +1,50 @@
+/*
+ * Copyright (C) 2017 Baidu, Inc. All Rights Reserved.
+ */
+package com.baidu.aip.face;
+
+import java.util.ArrayList;
+
+/**
+ * 该类封装了图片的图片源,给 @link(FaceDetectManager)提供一帧帧的图片用于人脸检测。
+ * 如CameraImageSource封装了,系统相机。
+ */
+public class ImageSource {
+
+    public ImageFrame borrowImageFrame() {
+        return new ImageFrame();
+    }
+
+    private ArrayList<OnFrameAvailableListener> listeners = new ArrayList<>();
+
+    /** 注册监听器,当有图片帧时会回调。*/
+    public void addOnFrameAvailableListener(OnFrameAvailableListener listener) {
+        this.listeners.add(listener);
+    }
+
+    /** 删除监听器*/
+    public void removeOnFrameAvailableListener(OnFrameAvailableListener listener) {
+        if (listener != null) {
+            this.listeners.remove(listener);
+        }
+    }
+
+    /** 获取监听器列表 */
+    protected ArrayList<OnFrameAvailableListener> getListeners() {
+        return listeners;
+    }
+
+    /** 打开图片源。*/
+    public void start() {
+
+    }
+
+    /** 停止图片源。*/
+    public void stop() {
+
+    }
+
+    /** 设置预览View用于显示预览图。*/
+    public void setPreviewView(PreviewView previewView) {
+    }
+}

+ 15 - 0
app_modular/faceplatform-ui/src/main/java/com/baidu/aip/face/OnFrameAvailableListener.java

@@ -0,0 +1,15 @@
+/*
+ * Copyright (C) 2017 Baidu, Inc. All Rights Reserved.
+ */
+package com.baidu.aip.face;
+
+/**
+ * 当图片源有新的图片帧时会回调该类。
+ */
+public interface OnFrameAvailableListener {
+    /**
+     * 每当图片源有新一帧时图片源会回调该方法。
+     * @param frame 新的一帧
+     */
+    void onFrameAvailable(ImageFrame frame);
+}

+ 65 - 0
app_modular/faceplatform-ui/src/main/java/com/baidu/aip/face/PreviewView.java

@@ -0,0 +1,65 @@
+/*
+ * Copyright (C) 2017 Baidu, Inc. All Rights Reserved.
+ */
+package com.baidu.aip.face;
+
+import android.graphics.RectF;
+import android.view.TextureView;
+
+/**
+ * 该类用于实现,图片源(@see ImageSource)数据预览。
+ */
+
+public interface PreviewView {
+
+    /**
+     * 图片帧缩放类型。
+     */
+    enum ScaleType{
+        /**
+         * 宽度与父控件一致,高度自适应
+         */
+        FIT_WIDTH,
+        /**
+         * 调试与父控件一致,宽度自适应
+         */
+        FIT_HEIGHT,
+        /**
+         * 全屏显示 ,保持显示比例,多余的部分会被裁剪掉。
+         */
+        CROP_INSIDE,
+    }
+
+    TextureView getTextureView();
+
+    /**
+     * 设置帧大小。
+     * @param width 帧宽度
+     * @param height 帧调试
+     */
+    void setPreviewSize(int width, int height);
+
+    /**
+     * 预览View中的坐标映射到,原始图片中。应用场景举例:裁剪框
+     * @param rect 预览View中的坐标
+     */
+    void mapToOriginalRect(RectF rect);
+
+    /**
+     * 原始图片中的坐标到预览View坐标中的映射。应用场景举例:预览页面显示人脸框。
+     * @param rectF 原始图中的坐标
+     */
+    void mapFromOriginalRect(RectF rectF);
+
+    /**
+     * 设置预览的缩放类型
+     * @param scaleType 缩放类型
+     */
+    void setScaleType(ScaleType scaleType);
+
+    /**
+     * 获取预览缩放类型
+     * @return 预览缩放类型
+     */
+    ScaleType getScaleType();
+}

+ 194 - 0
app_modular/faceplatform-ui/src/main/java/com/baidu/aip/face/TexturePreviewView.java

@@ -0,0 +1,194 @@
+/*
+ * Copyright (C) 2017 Baidu, Inc. All Rights Reserved.
+ */
+package com.baidu.aip.face;
+
+import android.content.Context;
+import android.graphics.Matrix;
+import android.graphics.RectF;
+import android.os.Handler;
+import android.os.Looper;
+import android.support.annotation.AttrRes;
+import android.support.annotation.NonNull;
+import android.support.annotation.Nullable;
+import android.util.AttributeSet;
+import android.view.TextureView;
+import android.widget.FrameLayout;
+
+/**
+ * 基于 系统TextureView实现的预览View;
+ */
+public class TexturePreviewView extends FrameLayout implements PreviewView {
+
+    private TextureView textureView;
+
+    private int videoWidth = 0;
+    private int videoHeight = 0;
+    private boolean mirrored = true;
+
+    public TexturePreviewView(@NonNull Context context) {
+        super(context);
+        init();
+    }
+
+    public TexturePreviewView(@NonNull Context context,
+                              @Nullable AttributeSet attrs) {
+        super(context, attrs);
+        init();
+    }
+
+    public TexturePreviewView(@NonNull Context context, @Nullable AttributeSet attrs,
+                              @AttrRes int defStyleAttr) {
+        super(context, attrs, defStyleAttr);
+        init();
+    }
+
+    private void init() {
+        textureView = new TextureView(getContext());
+        addView(textureView);
+    }
+
+    /**
+     * 有些ImageSource如系统相机前置设置头为镜面效果。这样换算坐标的时候会不一样
+     * @param mirrored 是否为镜面效果。
+     */
+    public void setMirrored(boolean mirrored) {
+        this.mirrored = mirrored;
+    }
+
+    @Override
+    protected void onLayout(boolean changed, int left, int top, int right, int bottom) {
+        super.onLayout(changed, left, top, right, bottom);
+        int selfWidth = getWidth();
+        int selfHeight = getHeight();
+        if (videoWidth == 0 || videoHeight == 0 || selfWidth == 0 || selfHeight == 0) {
+            return;
+        }
+        ScaleType scaleType = resolveScaleType();
+        if (scaleType == ScaleType.FIT_HEIGHT) {
+            int targetWith = videoWidth * selfHeight / videoHeight;
+            int delta = (targetWith - selfWidth) / 2;
+            textureView.layout(left - delta, top, right + delta, bottom);
+        } else {
+            int targetHeight = videoHeight * selfWidth / videoWidth;
+            int delta = (targetHeight - selfHeight) / 2;
+            textureView.layout(left, top - delta, right, bottom + delta);
+        }
+    }
+
+    @Override
+    public TextureView getTextureView() {
+        return textureView;
+    }
+
+    @Override
+    public void setPreviewSize(int width, int height) {
+        if (this.videoWidth == width && this.videoHeight == height) {
+            return;
+        }
+        this.videoWidth = width;
+        this.videoHeight = height;
+        handler.post(new Runnable() {
+            @Override
+            public void run() {
+                requestLayout();
+            }
+        });
+
+    }
+
+    @Override
+    public void mapToOriginalRect(RectF rectF) {
+
+        int selfWidth = getWidth();
+        int selfHeight = getHeight();
+        if (videoWidth == 0 || videoHeight == 0 || selfWidth == 0 || selfHeight == 0) {
+            return;
+            // TODO
+        }
+
+        Matrix matrix = new Matrix();
+
+        ScaleType scaleType = resolveScaleType();
+        if (scaleType == ScaleType.FIT_HEIGHT) {
+            int targetWith = videoWidth * selfHeight / videoHeight;
+            int delta = (targetWith - selfWidth) / 2;
+
+            float ratio = 1.0f * videoHeight / selfHeight;
+            matrix.postTranslate(delta, 0);
+            matrix.postScale(ratio, ratio);
+        } else {
+            int targetHeight = videoHeight * selfWidth / videoWidth;
+            int delta = (targetHeight - selfHeight) / 2;
+
+            float ratio = 1.0f * videoWidth / selfWidth;
+            matrix.postTranslate(0, delta);
+            matrix.postScale(ratio, ratio);
+        }
+        matrix.mapRect(rectF);
+    }
+
+    @Override
+    public void mapFromOriginalRect(RectF rectF) {
+        int selfWidth = getWidth();
+        int selfHeight = getHeight();
+        if (videoWidth == 0 || videoHeight == 0 || selfWidth == 0 || selfHeight == 0) {
+            return;
+            // TODO
+        }
+
+        Matrix matrix = new Matrix();
+
+        ScaleType scaleType = resolveScaleType();
+        if (scaleType == ScaleType.FIT_HEIGHT) {
+            int targetWith = videoWidth * selfHeight / videoHeight;
+            int delta = (targetWith - selfWidth) / 2;
+
+            float ratio = 1.0f * selfHeight / videoHeight;
+
+            matrix.postScale(ratio, ratio);
+            matrix.postTranslate(-delta, 0);
+        } else {
+            int targetHeight = videoHeight * selfWidth / videoWidth;
+            int delta = (targetHeight - selfHeight) / 2;
+
+            float ratio = 1.0f * selfWidth / videoWidth;
+
+            matrix.postScale(ratio, ratio);
+            matrix.postTranslate(0, -delta);
+        }
+        matrix.mapRect(rectF);
+
+        if (mirrored) {
+            float left = selfWidth - rectF.right;
+            float right = left + rectF.width();
+            rectF.left = left;
+            rectF.right = right;
+        }
+    }
+
+    @Override
+    public void setScaleType(ScaleType scaleType) {
+//        this.scaleType = scaleType;
+    }
+
+    @Override
+    public ScaleType getScaleType() {
+        return scaleType;
+    }
+
+    private ScaleType resolveScaleType() {
+        float selfRatio = 1.0f * getWidth() / getHeight();
+        float targetRatio = 1.0f * videoWidth / videoHeight;
+
+        ScaleType scaleType = this.scaleType;
+        if (this.scaleType == ScaleType.CROP_INSIDE) {
+            scaleType = selfRatio > targetRatio ? ScaleType.FIT_WIDTH : ScaleType.FIT_HEIGHT;
+        }
+        return scaleType;
+    }
+
+    private ScaleType scaleType = ScaleType.CROP_INSIDE;
+    private Handler handler = new Handler(Looper.getMainLooper());
+
+}

+ 415 - 0
app_modular/faceplatform-ui/src/main/java/com/baidu/aip/face/camera/Camera1Control.java

@@ -0,0 +1,415 @@
+/*
+ * Copyright (C) 2017 Baidu, Inc. All Rights Reserved.
+ */
+package com.baidu.aip.face.camera;
+
+import java.io.IOException;
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.Comparator;
+import java.util.List;
+import java.util.concurrent.atomic.AtomicBoolean;
+
+import com.baidu.aip.face.PreviewView;
+
+import android.Manifest;
+import android.annotation.TargetApi;
+import android.content.Context;
+import android.content.pm.PackageManager;
+import android.graphics.Rect;
+import android.graphics.SurfaceTexture;
+import android.hardware.Camera;
+import android.os.Build;
+import android.support.annotation.RequiresApi;
+import android.support.v4.app.ActivityCompat;
+import android.support.v4.content.ContextCompat;
+import android.util.SparseIntArray;
+import android.view.Surface;
+import android.view.TextureView;
+import android.view.View;
+
+/**
+ * 5.0以下相机API的封装。
+ */
+@SuppressWarnings("deprecation")
+@TargetApi(Build.VERSION_CODES.JELLY_BEAN)
+public class Camera1Control implements ICameraControl {
+
+    private static final SparseIntArray ORIENTATIONS = new SparseIntArray();
+    private static final int MAX_PREVIEW_SIZE = 2048;
+
+    static {
+        ORIENTATIONS.append(Surface.ROTATION_0, 90);
+        ORIENTATIONS.append(Surface.ROTATION_90, 0);
+        ORIENTATIONS.append(Surface.ROTATION_180, 270);
+        ORIENTATIONS.append(Surface.ROTATION_270, 180);
+    }
+
+
+    private int displayOrientation = 0;
+    private int cameraId = 0;
+    private int flashMode;
+    private AtomicBoolean takingPicture = new AtomicBoolean(false);
+
+    private Context context;
+    private Camera camera;
+
+    private Camera.Parameters parameters;
+    private PermissionCallback permissionCallback;
+    private Rect previewFrame = new Rect();
+
+    private int preferredWidth = 1280;
+    private int preferredHeight = 720;
+
+    @ICameraControl.CameraFacing
+    private int cameraFacing = CAMERA_FACING_FRONT;
+
+    private boolean usbCamera = false;
+
+    @Override
+    public void setDisplayOrientation(@CameraView.Orientation int displayOrientation) {
+        this.displayOrientation = displayOrientation;
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    @Override
+    public void refreshPermission() {
+        startPreview(true);
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    @Override
+    public void setFlashMode(@FlashMode int flashMode) {
+        if (this.flashMode == flashMode) {
+            return;
+        }
+        this.flashMode = flashMode;
+        updateFlashMode(flashMode);
+    }
+
+    @Override
+    public int getFlashMode() {
+        return flashMode;
+    }
+
+    @Override
+    public void setCameraFacing(@CameraFacing int cameraFacing) {
+        this.cameraFacing = cameraFacing;
+    }
+
+    @Override
+    public void setUsbCamera(boolean usbCamera) {
+        this.usbCamera = usbCamera;
+    }
+
+    @Override
+    public void start() {
+        startCamera();
+    }
+
+    public void isUsbCamera() {
+
+    }
+
+    private SurfaceTexture surfaceTexture;
+
+    private void startCamera() {
+        if (ContextCompat.checkSelfPermission(context, Manifest.permission.CAMERA)
+                != PackageManager.PERMISSION_GRANTED) {
+            if (permissionCallback != null) {
+                permissionCallback.onRequestPermission();
+            }
+            return;
+        }
+        if (camera == null) {
+            Camera.CameraInfo cameraInfo = new Camera.CameraInfo();
+            for (int i = 0; i < Camera.getNumberOfCameras(); i++) {
+                Camera.getCameraInfo(i, cameraInfo);
+                if (cameraInfo.facing == cameraFacing) {
+                    cameraId = i;
+                }
+            }
+            camera = Camera.open(cameraId);
+        }
+        if (parameters == null) {
+            parameters = camera.getParameters();
+            parameters.setFocusMode(Camera.Parameters.FOCUS_MODE_CONTINUOUS_PICTURE);
+        }
+
+        surfaceTexture = new SurfaceTexture(11);
+        parameters.setRotation(90); // TODO
+        int rotation = ORIENTATIONS.get(displayOrientation);
+
+        camera.setDisplayOrientation(rotation);
+        try {
+            camera.setPreviewCallback(new Camera.PreviewCallback() {
+                @Override
+                public void onPreviewFrame(byte[] data, Camera camera) {
+//                    Log.e("onPreviewFrame", "onPreviewFrame");
+                    Camera.Size size = camera.getParameters().getPreviewSize();
+
+                    int rotation = getSurfaceOrientation();
+                    if (cameraFacing == ICameraControl.CAMERA_FACING_FRONT) {
+                        // android自带的摄像头和接usb摄像头,图片有180旋转,用usb摄像头注释下面的代码
+                        if (!usbCamera) {
+                            if (rotation == 90 || rotation == 270) {
+                                rotation = (rotation + 180) % 360;
+                            }
+                        }
+                    }
+
+                    if (rotation % 180 == 90) {
+                        previewView.setPreviewSize(size.height, size.width);
+                    } else {
+                        previewView.setPreviewSize(size.width, size.height);
+                    }
+
+                    onFrameListener.onPreviewFrame(data, rotation, size.width, size.height);
+                }
+            });
+            camera.setPreviewTexture(surfaceTexture);
+            if (textureView != null) {
+                surfaceTexture.detachFromGLContext();
+                textureView.setSurfaceTexture(surfaceTexture);
+            }
+        } catch (IOException e) {
+            e.printStackTrace();
+        }
+        opPreviewSize(preferredWidth, preferredHeight);
+    }
+
+    private TextureView textureView;
+
+    @RequiresApi(api = Build.VERSION_CODES.JELLY_BEAN)
+    public void setTextureView(TextureView textureView) {
+        this.textureView = textureView;
+        if (surfaceTexture != null) {
+            surfaceTexture.detachFromGLContext();
+            textureView.setSurfaceTexture(surfaceTexture);
+        }
+    }
+
+    @Override
+    public void stop() {
+        if (camera != null) {
+            camera.stopPreview();
+            camera.setPreviewCallback(null);
+            camera.release();
+            camera = null;
+        }
+    }
+
+    @Override
+    public void pause() {
+        if (camera != null) {
+            camera.stopPreview();
+        }
+        setFlashMode(FLASH_MODE_OFF);
+    }
+
+    @Override
+    public void resume() {
+        takingPicture.set(false);
+        if (camera == null) {
+            startCamera();
+        }
+    }
+
+    private OnFrameListener onFrameListener;
+
+    @Override
+    public void setOnFrameListener(OnFrameListener listener) {
+        this.onFrameListener = listener;
+    }
+
+    @Override
+    public void setPreferredPreviewSize(int width, int height) {
+        this.preferredWidth = Math.max(width, height);
+        this.preferredHeight = Math.min(width, height);
+    }
+
+    @Override
+    public View getDisplayView() {
+        return null;
+    }
+
+
+    private PreviewView previewView;
+
+    @Override
+    public void setPreviewView(PreviewView previewView) {
+        this.previewView = previewView;
+        setTextureView(previewView.getTextureView());
+    }
+
+    @Override
+    public PreviewView getPreviewView() {
+        return previewView;
+    }
+
+    @Override
+    public void takePicture(final OnTakePictureCallback onTakePictureCallback) {
+        if (takingPicture.get()) {
+            return;
+        }
+
+        switch (displayOrientation) {
+            case CameraView.ORIENTATION_PORTRAIT:
+                parameters.setRotation(90);
+                break;
+            case CameraView.ORIENTATION_HORIZONTAL:
+                parameters.setRotation(0);
+                break;
+            case CameraView.ORIENTATION_INVERT:
+                parameters.setRotation(180);
+                break;
+            default:
+                parameters.setRotation(90);
+                break;
+        }
+        Camera.Size picSize =
+                getOptimalSize(preferredWidth, preferredHeight, camera.getParameters().getSupportedPictureSizes());
+        parameters.setPictureSize(picSize.width, picSize.height);
+        camera.setParameters(parameters);
+        takingPicture.set(true);
+        camera.autoFocus(new Camera.AutoFocusCallback() {
+            @Override
+            public void onAutoFocus(boolean success, Camera camera) {
+                camera.cancelAutoFocus();
+                try {
+                    camera.takePicture(null, null, new Camera.PictureCallback() {
+                        @Override
+                        public void onPictureTaken(byte[] data, Camera camera) {
+                            camera.startPreview();
+                            takingPicture.set(false);
+                            if (onTakePictureCallback != null) {
+                                onTakePictureCallback.onPictureTaken(data);
+                            }
+                        }
+                    });
+                } catch (RuntimeException e) {
+                    e.printStackTrace();
+                    camera.startPreview();
+                    takingPicture.set(false);
+                }
+            }
+        });
+    }
+
+    @Override
+    public void setPermissionCallback(PermissionCallback callback) {
+        this.permissionCallback = callback;
+    }
+
+    public Camera1Control(Context context) {
+        this.context = context;
+    }
+
+    // 开启预览
+    private void startPreview(boolean checkPermission) {
+        if (ActivityCompat.checkSelfPermission(context, Manifest.permission.CAMERA)
+                != PackageManager.PERMISSION_GRANTED) {
+            if (checkPermission && permissionCallback != null) {
+                permissionCallback.onRequestPermission();
+            }
+            return;
+        }
+        camera.startPreview();
+    }
+
+    private void opPreviewSize(int width, @SuppressWarnings("unused") int height) {
+        Camera.Size optSize;
+        if (parameters != null && camera != null && width > 0) {
+            optSize = getOptimalSize(width, height, camera.getParameters().getSupportedPreviewSizes());
+
+            parameters.setPreviewSize(optSize.width, optSize.height);
+
+//            camera.setDisplayOrientation(getSurfaceOrientation());
+            //            camera.stopPreview();
+            try {
+                camera.setParameters(parameters);
+            } catch (RuntimeException e) {
+                e.printStackTrace();
+
+            }
+            camera.startPreview();
+        }
+    }
+
+    private Camera.Size getOptimalSize(int width, int height, List<Camera.Size> sizes) {
+
+        Camera.Size pictureSize = sizes.get(0);
+
+        List<Camera.Size> candidates = new ArrayList<>();
+
+        for (Camera.Size size : sizes) {
+            if (size.width >= width && size.height >= height && size.width * height == size.height * width) {
+                // 比例相同
+                candidates.add(size);
+            } else if (size.height >= width && size.width >= height && size.width * width == size.height * height) {
+                // 反比例
+                candidates.add(size);
+            }
+        }
+        if (!candidates.isEmpty()) {
+            return Collections.min(candidates, sizeComparator);
+        }
+
+        for (Camera.Size size : sizes) {
+            if (size.width > width && size.height > height) {
+                return size;
+            }
+        }
+
+        return pictureSize;
+    }
+
+    private Comparator<Camera.Size> sizeComparator = new Comparator<Camera.Size>() {
+        @Override
+        public int compare(Camera.Size lhs, Camera.Size rhs) {
+            return Long.signum((long) lhs.width * lhs.height - (long) rhs.width * rhs.height);
+        }
+    };
+
+    private void updateFlashMode(int flashMode) {
+        switch (flashMode) {
+            case FLASH_MODE_TORCH:
+                parameters.setFlashMode(Camera.Parameters.FLASH_MODE_TORCH);
+                break;
+            case FLASH_MODE_OFF:
+                parameters.setFlashMode(Camera.Parameters.FLASH_MODE_OFF);
+                break;
+            case ICameraControl.FLASH_MODE_AUTO:
+                parameters.setFlashMode(Camera.Parameters.FLASH_MODE_AUTO);
+                break;
+            default:
+                parameters.setFlashMode(Camera.Parameters.FLASH_MODE_AUTO);
+                break;
+        }
+        camera.setParameters(parameters);
+    }
+
+    protected int getSurfaceOrientation() {
+        @CameraView.Orientation
+        int orientation = displayOrientation;
+        switch (orientation) {
+            case CameraView.ORIENTATION_PORTRAIT:
+                return 90;
+            case CameraView.ORIENTATION_HORIZONTAL:
+                return 0;
+            case CameraView.ORIENTATION_INVERT:
+                return 180;
+            default:
+                return 90;
+        }
+    }
+
+    @Override
+    public Rect getPreviewFrame() {
+        return previewFrame;
+    }
+}

+ 769 - 0
app_modular/faceplatform-ui/src/main/java/com/baidu/aip/face/camera/Camera2Control.java

@@ -0,0 +1,769 @@
+/*
+ * Copyright (C) 2017 Baidu, Inc. All Rights Reserved.
+ */
+
+package com.baidu.aip.face.camera;
+
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Collections;
+import java.util.Comparator;
+import java.util.List;
+import java.util.concurrent.Semaphore;
+import java.util.concurrent.TimeUnit;
+
+import com.baidu.aip.face.PreviewView;
+
+import android.Manifest;
+import android.annotation.TargetApi;
+import android.content.Context;
+import android.content.pm.PackageManager;
+import android.graphics.ImageFormat;
+import android.graphics.Matrix;
+import android.graphics.Point;
+import android.graphics.Rect;
+import android.graphics.RectF;
+import android.graphics.SurfaceTexture;
+import android.hardware.camera2.CameraAccessException;
+import android.hardware.camera2.CameraCaptureSession;
+import android.hardware.camera2.CameraCharacteristics;
+import android.hardware.camera2.CameraDevice;
+import android.hardware.camera2.CameraManager;
+import android.hardware.camera2.CameraMetadata;
+import android.hardware.camera2.CaptureRequest;
+import android.hardware.camera2.CaptureResult;
+import android.hardware.camera2.TotalCaptureResult;
+import android.hardware.camera2.params.StreamConfigurationMap;
+import android.media.Image;
+import android.media.ImageReader;
+import android.media.ImageReader.OnImageAvailableListener;
+import android.os.Build;
+import android.os.Handler;
+import android.os.HandlerThread;
+import android.os.Looper;
+import android.support.annotation.NonNull;
+import android.support.v4.content.ContextCompat;
+import android.util.Log;
+import android.util.Size;
+import android.util.SparseIntArray;
+import android.view.Surface;
+import android.view.TextureView;
+import android.view.View;
+import android.view.WindowManager;
+
+@TargetApi(Build.VERSION_CODES.LOLLIPOP)
+public class Camera2Control implements ICameraControl {
+
+    /**
+     * Conversion from screen rotation to JPEG orientation.
+     */
+    private static final SparseIntArray ORIENTATIONS = new SparseIntArray();
+    private static final int MAX_PREVIEW_SIZE = 2048;
+
+    static {
+        ORIENTATIONS.append(Surface.ROTATION_0, 90);
+        ORIENTATIONS.append(Surface.ROTATION_90, 0);
+        ORIENTATIONS.append(Surface.ROTATION_180, 270);
+        ORIENTATIONS.append(Surface.ROTATION_270, 180);
+    }
+
+    private static final int STATE_PREVIEW = 0;
+    private static final int STATE_WAITING_FOR_LOCK = 1;
+    private static final int STATE_WAITING_FOR_CAPTURE = 2;
+    private static final int STATE_CAPTURING = 3;
+    private static final int STATE_PICTURE_TAKEN = 4;
+
+    private static final int MAX_PREVIEW_WIDTH = 1920;
+    private static final int MAX_PREVIEW_HEIGHT = 1080;
+
+    private int flashMode;
+    private int orientation = 0;
+    private int state = STATE_PREVIEW;
+
+    private Context context;
+    private OnTakePictureCallback onTakePictureCallback;
+    private PermissionCallback permissionCallback;
+    private SurfaceTexture surfaceTexture;
+
+    private String cameraId;
+    private TextureView textureView;
+    private Size previewSize;
+
+    private HandlerThread backgroundThread;
+    private Handler backgroundHandler;
+    private ImageReader imageReader;
+    private CameraCaptureSession captureSession;
+    private CameraDevice cameraDevice;
+
+    private CaptureRequest.Builder previewRequestBuilder;
+    private CaptureRequest previewRequest;
+
+    private Semaphore cameraLock = new Semaphore(1);
+    private int sensorOrientation;
+
+    private int camFacing = CameraCharacteristics.LENS_FACING_BACK;
+
+    private Handler handler = new Handler(Looper.getMainLooper());
+
+    private int preferredWidth = 1280;
+    private int preferredHeight = 720;
+
+    private boolean usbCamera = false;
+
+    public void switchCamera() {
+        if (camFacing == CameraCharacteristics.LENS_FACING_BACK) {
+            camFacing = CameraCharacteristics.LENS_FACING_FRONT;
+        } else {
+            camFacing = CameraCharacteristics.LENS_FACING_BACK;
+        }
+        //        openCamera(textureView.getWidth(), textureView.getHeight());
+        stop();
+        handler.postDelayed(new Runnable() {
+            @Override
+            public void run() {
+                start();
+            }
+        }, 800);
+    }
+
+    @Override
+    public void start() {
+        startBackgroundThread();
+        openCamera(preferredWidth, preferredHeight);
+    }
+
+    @Override
+    public void stop() {
+        if (imageReader != null) {
+            imageReader.close();
+            closeCamera();
+            stopBackgroundThread();
+            imageReader = null;
+        }
+    }
+
+    @Override
+    public void pause() {
+        setFlashMode(FLASH_MODE_OFF);
+    }
+
+    @Override
+    public void resume() {
+        state = STATE_PREVIEW;
+    }
+
+    @Override
+    public void setOnFrameListener(OnFrameListener listener) {
+        this.onFrameListener = listener;
+    }
+
+    @Override
+    public void setPreferredPreviewSize(int width, int height) {
+        this.preferredWidth = Math.max(width, height);
+        this.preferredHeight = Math.min(width, height);
+    }
+
+    private OnFrameListener<Image> onFrameListener;
+
+    @Override
+    public View getDisplayView() {
+        return textureView;
+    }
+
+    private PreviewView previewView;
+
+    @Override
+    public void setPreviewView(PreviewView previewView) {
+        this.previewView = previewView;
+        textureView = previewView.getTextureView();
+        if (surfaceTexture != null) {
+            surfaceTexture.detachFromGLContext();
+            textureView.setSurfaceTexture(surfaceTexture);
+        }
+        textureView.setSurfaceTextureListener(surfaceTextureListener);
+    }
+
+    @Override
+    public PreviewView getPreviewView() {
+        return previewView;
+    }
+
+    @Override
+    public Rect getPreviewFrame() {
+        return null;
+    }
+
+    @Override
+    public void takePicture(OnTakePictureCallback callback) {
+        this.onTakePictureCallback = callback;
+        // 拍照第一步,对焦
+        lockFocus();
+    }
+
+    @Override
+    public void setPermissionCallback(PermissionCallback callback) {
+        this.permissionCallback = callback;
+    }
+
+    @Override
+    public void setDisplayOrientation(@CameraView.Orientation int displayOrientation) {
+        this.orientation = displayOrientation / 90;
+    }
+
+    @Override
+    public void refreshPermission() {
+        openCamera(preferredWidth, preferredHeight);
+    }
+
+    @Override
+    public void setFlashMode(@FlashMode int flashMode) {
+        if (this.flashMode == flashMode) {
+            return;
+        }
+        this.flashMode = flashMode;
+        try {
+            previewRequestBuilder.set(CaptureRequest.CONTROL_AF_MODE,
+                    CaptureRequest.CONTROL_AF_MODE_CONTINUOUS_PICTURE);
+            updateFlashMode(flashMode, previewRequestBuilder);
+            previewRequest = previewRequestBuilder.build();
+            captureSession.setRepeatingRequest(previewRequest, captureCallback, backgroundHandler);
+        } catch (Exception e) {
+            e.printStackTrace();
+        }
+    }
+
+    @Override
+    public int getFlashMode() {
+        return flashMode;
+    }
+
+    @Override
+    public void setCameraFacing(int cameraFacing) {
+        camFacing = cameraFacing == CAMERA_FACING_BACK ? CameraCharacteristics.LENS_FACING_FRONT :
+                CameraCharacteristics.LENS_FACING_BACK;
+    }
+
+    @Override
+    public void setUsbCamera(boolean usbCamera) {
+        this.usbCamera = usbCamera;
+    }
+
+    public Camera2Control(Context activity) {
+        this.context = activity;
+    }
+
+    private final TextureView.SurfaceTextureListener surfaceTextureListener =
+            new TextureView.SurfaceTextureListener() {
+                @Override
+                public void onSurfaceTextureAvailable(SurfaceTexture texture, int width, int height) {
+                    //                    openCamera(width, height);
+                }
+
+                @Override
+                public void onSurfaceTextureSizeChanged(SurfaceTexture texture, int width, int height) {
+                    configureTransform(width, height);
+                }
+
+                @Override
+                public boolean onSurfaceTextureDestroyed(SurfaceTexture texture) {
+                    stop();
+                    return false;
+                }
+
+                @Override
+                public void onSurfaceTextureUpdated(SurfaceTexture texture) {
+                }
+            };
+
+    private void openCamera(int width, int height) {
+        // 6.0+的系统需要检查系统权限 。
+        if (ContextCompat.checkSelfPermission(context, Manifest.permission.CAMERA)
+                != PackageManager.PERMISSION_GRANTED) {
+            requestCameraPermission();
+            return;
+        }
+        setUpCameraOutputs(width, height);
+        configureTransform(width, height);
+        CameraManager manager = (CameraManager) context.getSystemService(Context.CAMERA_SERVICE);
+        try {
+            if (!cameraLock.tryAcquire(2500, TimeUnit.MILLISECONDS)) {
+                throw new RuntimeException("Time out waiting to lock camera opening.");
+            }
+            manager.openCamera(cameraId, deviceStateCallback, backgroundHandler);
+        } catch (CameraAccessException e) {
+            e.printStackTrace();
+        } catch (InterruptedException e) {
+            throw new RuntimeException("Interrupted while trying to lock camera opening.", e);
+        }
+    }
+
+    private final CameraDevice.StateCallback deviceStateCallback = new CameraDevice.StateCallback() {
+        @Override
+        public void onOpened(@NonNull CameraDevice cameraDevice) {
+            cameraLock.release();
+            Camera2Control.this.cameraDevice = cameraDevice;
+            createCameraPreviewSession();
+        }
+
+        @Override
+        public void onDisconnected(@NonNull CameraDevice cameraDevice) {
+            cameraLock.release();
+            cameraDevice.close();
+            Camera2Control.this.cameraDevice = null;
+        }
+
+        @Override
+        public void onError(@NonNull CameraDevice cameraDevice, int error) {
+            cameraLock.release();
+            cameraDevice.close();
+            Camera2Control.this.cameraDevice = null;
+        }
+    };
+
+    private void createCameraPreviewSession() {
+        try {
+            if (surfaceTexture == null) {
+                surfaceTexture = new SurfaceTexture(11); // TODO
+            }
+
+            if (textureView != null) {
+                handler.post(new Runnable() {
+                    @Override
+                    public void run() {
+                        try {
+                            surfaceTexture.detachFromGLContext();
+                        } catch (Exception e) {
+                            e.printStackTrace();
+                        }
+                        if (textureView.getSurfaceTexture() != surfaceTexture) {
+                            textureView.setSurfaceTexture(surfaceTexture);
+                        }
+                    }
+                });
+            }
+
+            Surface surface = new Surface(surfaceTexture);
+            int rotation = ORIENTATIONS.get(orientation);
+            if (rotation % 180 == 90) {
+                surfaceTexture.setDefaultBufferSize(preferredWidth, preferredHeight);
+            } else {
+                surfaceTexture.setDefaultBufferSize(preferredHeight, preferredWidth);
+            }
+            previewRequestBuilder = cameraDevice.createCaptureRequest(CameraDevice.TEMPLATE_PREVIEW);
+            previewRequestBuilder.addTarget(surface);
+
+            imageReader =
+                    ImageReader
+                            .newInstance(preferredWidth, preferredHeight, ImageFormat.YUV_420_888, 1);
+            imageReader.setOnImageAvailableListener(new OnImageAvailableListener() {
+                @Override
+                public void onImageAvailable(ImageReader reader) {
+                    Image image = reader.acquireLatestImage();
+
+                    int rotation = ORIENTATIONS.get(orientation);
+                    if (camFacing == ICameraControl.CAMERA_FACING_FRONT) {
+                        if (rotation == 90 || rotation == 270) {
+                            rotation = (rotation + 180) % 360;
+                        }
+                    }
+
+                    Log.e("xx", "sensorOrientation" + sensorOrientation);
+                    Log.e("xx", "sensorOrientation" + orientation * 90);
+                    if (rotation % 180 == 90) {
+                        previewView.setPreviewSize(image.getHeight(), image.getWidth());
+                    } else {
+                        previewView.setPreviewSize(image.getWidth(), image.getHeight());
+                    }
+
+                    if (onFrameListener != null) {
+                        onFrameListener.onPreviewFrame(image, rotation, image.getWidth(), image.getHeight());
+                    }
+                    image.close();
+                }
+            }, backgroundHandler);
+
+            previewRequestBuilder.addTarget(imageReader.getSurface());
+
+            updateFlashMode(this.flashMode, previewRequestBuilder);
+
+            cameraDevice.createCaptureSession(Arrays.asList(surface, imageReader.getSurface()),
+                    new CameraCaptureSession.StateCallback() {
+
+                        @Override
+                        public void onConfigured(@NonNull CameraCaptureSession cameraCaptureSession) {
+                            // The camera is already closed
+                            if (null == cameraDevice) {
+                                return;
+                            }
+                            captureSession = cameraCaptureSession;
+                            try {
+                                previewRequestBuilder.set(CaptureRequest.CONTROL_AF_MODE,
+                                        CaptureRequest.CONTROL_AF_MODE_CONTINUOUS_PICTURE);
+
+                                previewRequest = previewRequestBuilder.build();
+                                captureSession.setRepeatingRequest(previewRequest,
+                                        captureCallback, backgroundHandler);
+                            } catch (CameraAccessException e) {
+                                e.printStackTrace();
+                            }
+                        }
+
+                        @Override
+                        public void onConfigureFailed(
+                                @NonNull CameraCaptureSession cameraCaptureSession) {
+                            Log.e("xx", "onConfigureFailed" + cameraCaptureSession);
+                        }
+                    }, backgroundHandler
+            );
+        } catch (CameraAccessException e) {
+            e.printStackTrace();
+        }
+    }
+
+    private CameraCaptureSession.CaptureCallback captureCallback =
+            new CameraCaptureSession.CaptureCallback() {
+                private void process(CaptureResult result) {
+                    switch (state) {
+                        case STATE_PREVIEW: {
+                            break;
+                        }
+                        case STATE_WAITING_FOR_LOCK: {
+                            Integer afState = result.get(CaptureResult.CONTROL_AF_STATE);
+                            if (afState == null || afState == CaptureResult.CONTROL_AF_STATE_PASSIVE_SCAN) {
+                                captureStillPicture();
+                            } else if (CaptureResult.CONTROL_AF_STATE_FOCUSED_LOCKED == afState
+                                    || CaptureRequest.CONTROL_AF_STATE_INACTIVE == afState
+                                    || CaptureResult.CONTROL_AF_STATE_NOT_FOCUSED_LOCKED == afState
+                                    || CaptureResult.CONTROL_AF_STATE_PASSIVE_FOCUSED == afState) {
+                                Integer aeState = result.get(CaptureResult.CONTROL_AE_STATE);
+                                if (aeState == null
+                                        || aeState == CaptureResult.CONTROL_AE_STATE_CONVERGED) {
+                                    captureStillPicture();
+                                } else {
+                                    runPreCaptureSequence();
+                                }
+                            }
+                            break;
+                        }
+                        case STATE_WAITING_FOR_CAPTURE: {
+                            Integer aeState = result.get(CaptureResult.CONTROL_AE_STATE);
+                            if (aeState == null
+                                    || aeState == CaptureResult.CONTROL_AE_STATE_PRECAPTURE
+                                    || aeState == CaptureRequest.CONTROL_AE_STATE_FLASH_REQUIRED) {
+                                state = STATE_CAPTURING;
+                            } else {
+                                if (aeState == CaptureResult.CONTROL_AE_STATE_CONVERGED) {
+                                    captureStillPicture();
+                                }
+                            }
+                            break;
+                        }
+                        case STATE_CAPTURING: {
+                            Integer aeState = result.get(CaptureResult.CONTROL_AE_STATE);
+                            if (aeState == null || aeState != CaptureResult.CONTROL_AE_STATE_PRECAPTURE) {
+                                captureStillPicture();
+                            }
+                            break;
+                        }
+                        default:
+                            break;
+                    }
+                }
+
+                @Override
+                public void onCaptureProgressed(@NonNull CameraCaptureSession session,
+                                                @NonNull CaptureRequest request,
+                                                @NonNull CaptureResult partialResult) {
+                    process(partialResult);
+                }
+
+                @Override
+                public void onCaptureCompleted(@NonNull CameraCaptureSession session,
+                                               @NonNull CaptureRequest request,
+                                               @NonNull TotalCaptureResult result) {
+                    process(result);
+                }
+
+            };
+
+    private Size getOptimalSize(Size[] choices, int textureViewWidth,
+                                int textureViewHeight, int maxWidth, int maxHeight, Size aspectRatio) {
+        List<Size> bigEnough = new ArrayList<>();
+        List<Size> notBigEnough = new ArrayList<>();
+        int w = aspectRatio.getWidth();
+        int h = aspectRatio.getHeight();
+        for (Size option : choices) {
+            if (option.getWidth() <= maxWidth && option.getHeight() <= maxHeight
+                    && option.getHeight() == option.getWidth() * h / w) {
+                if (option.getWidth() >= textureViewWidth
+                        && option.getHeight() >= textureViewHeight) {
+                    bigEnough.add(option);
+                } else {
+                    notBigEnough.add(option);
+                }
+            }
+        }
+
+        // Pick the smallest of those big enough. If there is no one big enough, pick the
+        // largest of those not big enough.
+        if (bigEnough.size() > 0) {
+            return Collections.min(bigEnough, sizeComparator);
+        }
+
+        for (Size option : choices) {
+            if (option.getWidth() > maxWidth && option.getHeight() > maxHeight) {
+                return option;
+            }
+        }
+
+        if (notBigEnough.size() > 0) {
+            return Collections.max(notBigEnough, sizeComparator);
+        }
+
+        return choices[0];
+    }
+
+    private Comparator<Size> sizeComparator = new Comparator<Size>() {
+        @Override
+        public int compare(Size lhs, Size rhs) {
+            return Long.signum((long) lhs.getWidth() * lhs.getHeight() - (long) rhs.getWidth() * rhs.getHeight());
+        }
+    };
+
+    private void requestCameraPermission() {
+        if (permissionCallback != null) {
+            permissionCallback.onRequestPermission();
+        }
+    }
+
+    @SuppressWarnings("SuspiciousNameCombination")
+    private void setUpCameraOutputs(int width, int height) {
+        CameraManager manager = (CameraManager) context.getSystemService(Context.CAMERA_SERVICE);
+        try {
+            for (String cameraId : manager.getCameraIdList()) {
+                CameraCharacteristics characteristics =
+                        manager.getCameraCharacteristics(cameraId);
+
+                Integer facing = characteristics.get(CameraCharacteristics.LENS_FACING);
+                if (facing != null && facing == camFacing) {
+                    continue;
+                }
+
+                StreamConfigurationMap map = characteristics.get(
+                        CameraCharacteristics.SCALER_STREAM_CONFIGURATION_MAP);
+                if (map == null) {
+                    continue;
+                }
+
+                WindowManager windowManager = (WindowManager) context.getSystemService(Context.WINDOW_SERVICE);
+                Point screenSize = new Point();
+                windowManager.getDefaultDisplay().getSize(screenSize);
+                int maxImageSize = Math.max(MAX_PREVIEW_SIZE, screenSize.y * 2 / 3);
+
+                Size size = getOptimalSize(map.getOutputSizes(ImageFormat.JPEG), textureView.getWidth(),
+                        textureView.getHeight(), maxImageSize, maxImageSize, new Size(4, 3));
+
+                int displayRotation = orientation;
+                // noinspection ConstantConditions
+                sensorOrientation = characteristics.get(CameraCharacteristics.SENSOR_ORIENTATION);
+                boolean swappedDimensions = false;
+                switch (displayRotation) {
+                    case Surface.ROTATION_0:
+                    case Surface.ROTATION_180:
+                        if (sensorOrientation == 90 || sensorOrientation == 270) {
+                            swappedDimensions = true;
+                        }
+                        break;
+                    case Surface.ROTATION_90:
+                    case Surface.ROTATION_270:
+                        if (sensorOrientation == 0 || sensorOrientation == 180) {
+                            swappedDimensions = true;
+                        }
+                        break;
+                    default:
+                }
+                //                orientation = sensorOrientation;
+
+                int rotatedPreviewWidth = width;
+                int rotatedPreviewHeight = height;
+                int maxPreviewWidth = screenSize.x;
+                int maxPreviewHeight = screenSize.y;
+
+                if (swappedDimensions) {
+                    rotatedPreviewWidth = height;
+                    rotatedPreviewHeight = width;
+                    maxPreviewWidth = screenSize.y;
+                    maxPreviewHeight = screenSize.x;
+                }
+
+                maxPreviewWidth = Math.min(maxPreviewWidth, MAX_PREVIEW_WIDTH);
+                maxPreviewHeight = Math.min(maxPreviewHeight, MAX_PREVIEW_HEIGHT);
+
+                previewSize = getOptimalSize(map.getOutputSizes(SurfaceTexture.class),
+                        rotatedPreviewWidth, rotatedPreviewHeight, maxPreviewWidth,
+                        maxPreviewHeight, size);
+                this.cameraId = cameraId;
+
+                return;
+            }
+        } catch (CameraAccessException | NullPointerException e) {
+            e.printStackTrace();
+        }
+    }
+
+    private void closeCamera() {
+        try {
+            cameraLock.acquire();
+            if (null != captureSession) {
+                captureSession.close();
+                captureSession = null;
+            }
+            if (null != cameraDevice) {
+                cameraDevice.close();
+                cameraDevice = null;
+            }
+            if (null != imageReader) {
+                imageReader.close();
+                imageReader = null;
+            }
+        } catch (InterruptedException e) {
+            throw new RuntimeException("Interrupted while trying to lock camera closing.", e);
+        } finally {
+            cameraLock.release();
+        }
+    }
+
+    private void startBackgroundThread() {
+        backgroundThread = new HandlerThread("ocr_camera");
+        backgroundThread.start();
+        backgroundHandler = new Handler(backgroundThread.getLooper());
+    }
+
+    private void stopBackgroundThread() {
+        if (backgroundThread != null) {
+            backgroundThread.quitSafely();
+            backgroundThread = null;
+            backgroundHandler = null;
+        }
+    }
+
+    private Matrix matrix = new Matrix();
+
+    private void configureTransform(int viewWidth, int viewHeight) {
+        if (null == textureView || null == previewSize || null == context) {
+            return;
+        }
+        int rotation = orientation;
+
+        RectF viewRect = new RectF(0, 0, viewWidth, viewHeight);
+        RectF bufferRect = new RectF(0, 0, previewSize.getHeight(), previewSize.getWidth());
+        float centerX = viewRect.centerX();
+        float centerY = viewRect.centerY();
+        if (Surface.ROTATION_90 == rotation || Surface.ROTATION_270 == rotation) {
+            bufferRect.offset(centerX - bufferRect.centerX(), centerY - bufferRect.centerY());
+            matrix.setRectToRect(viewRect, bufferRect, Matrix.ScaleToFit.FILL);
+            float scale = Math.max(
+                    (float) viewHeight / previewSize.getHeight(),
+                    (float) viewWidth / previewSize.getWidth());
+            matrix.postScale(scale, scale, centerX, centerY);
+            matrix.postRotate(90 * (rotation - 2), centerX, centerY);
+        } else if (Surface.ROTATION_180 == rotation) {
+            matrix.postRotate(180, centerX, centerY);
+        }
+        textureView.setTransform(matrix);
+    }
+
+    // 拍照前,先对焦
+    private void lockFocus() {
+        if (captureSession != null && state == STATE_PREVIEW) {
+            try {
+                previewRequestBuilder.set(CaptureRequest.CONTROL_AF_TRIGGER,
+                        CameraMetadata.CONTROL_AF_TRIGGER_START);
+                state = STATE_WAITING_FOR_LOCK;
+                captureSession.capture(previewRequestBuilder.build(), captureCallback,
+                        backgroundHandler);
+            } catch (CameraAccessException e) {
+                e.printStackTrace();
+            }
+        }
+    }
+
+    private void runPreCaptureSequence() {
+        try {
+            previewRequestBuilder.set(CaptureRequest.CONTROL_AE_PRECAPTURE_TRIGGER,
+                    CaptureRequest.CONTROL_AE_PRECAPTURE_TRIGGER_START);
+            state = STATE_WAITING_FOR_CAPTURE;
+            captureSession.capture(previewRequestBuilder.build(), captureCallback,
+                    backgroundHandler);
+        } catch (CameraAccessException e) {
+            e.printStackTrace();
+        }
+    }
+
+    // 拍照session
+    private void captureStillPicture() {
+        try {
+            if (null == context || null == cameraDevice) {
+                return;
+            }
+            final CaptureRequest.Builder captureBuilder =
+                    cameraDevice.createCaptureRequest(CameraDevice.TEMPLATE_STILL_CAPTURE);
+            captureBuilder.set(CaptureRequest.CONTROL_AF_MODE,
+                    CaptureRequest.CONTROL_AF_MODE_CONTINUOUS_PICTURE);
+
+            captureBuilder.set(CaptureRequest.JPEG_ORIENTATION, getOrientation(orientation));
+            updateFlashMode(this.flashMode, captureBuilder);
+            CameraCaptureSession.CaptureCallback captureCallback =
+                    new CameraCaptureSession.CaptureCallback() {
+                        @Override
+                        public void onCaptureCompleted(@NonNull CameraCaptureSession session,
+                                                       @NonNull CaptureRequest request,
+                                                       @NonNull TotalCaptureResult result) {
+                            unlockFocus();
+                        }
+                    };
+
+            // 停止预览
+            captureSession.stopRepeating();
+            captureSession.capture(captureBuilder.build(), captureCallback, backgroundHandler);
+            state = STATE_PICTURE_TAKEN;
+        } catch (CameraAccessException e) {
+            e.printStackTrace();
+        }
+    }
+
+    private int getOrientation(int rotation) {
+        return (ORIENTATIONS.get(rotation) + sensorOrientation + 270) % 360;
+    }
+
+    // 停止对焦
+    private void unlockFocus() {
+        try {
+            previewRequestBuilder.set(CaptureRequest.CONTROL_AF_TRIGGER,
+                    CameraMetadata.CONTROL_AF_TRIGGER_CANCEL);
+            captureSession.capture(previewRequestBuilder.build(), captureCallback,
+                    backgroundHandler);
+            state = STATE_PREVIEW;
+            // 预览
+            captureSession.setRepeatingRequest(previewRequest, captureCallback,
+                    backgroundHandler);
+        } catch (CameraAccessException e) {
+            e.printStackTrace();
+        }
+    }
+
+    private void updateFlashMode(@FlashMode int flashMode, CaptureRequest.Builder builder) {
+        switch (flashMode) {
+            case FLASH_MODE_TORCH:
+                builder.set(CaptureRequest.FLASH_MODE, CameraMetadata.FLASH_MODE_TORCH);
+                break;
+            case FLASH_MODE_OFF:
+                builder.set(CaptureRequest.FLASH_MODE, CameraMetadata.FLASH_MODE_OFF);
+                break;
+            case ICameraControl.FLASH_MODE_AUTO:
+            default:
+                builder.set(CaptureRequest.FLASH_MODE, CameraMetadata.FLASH_MODE_SINGLE);
+                break;
+        }
+    }
+}

+ 156 - 0
app_modular/faceplatform-ui/src/main/java/com/baidu/aip/face/camera/CameraView.java

@@ -0,0 +1,156 @@
+/*
+ * Copyright (C) 2017 Baidu, Inc. All Rights Reserved.
+ */
+package com.baidu.aip.face.camera;
+
+import android.content.Context;
+import android.graphics.Bitmap;
+import android.os.Build;
+import android.support.annotation.IntDef;
+import android.util.AttributeSet;
+import android.view.View;
+import android.widget.FrameLayout;
+import android.widget.ImageView;
+
+/**
+ * 负责,相机的管理。同时提供,裁剪遮罩功能。
+ */
+public class CameraView extends FrameLayout {
+
+    /**
+     * 照相回调
+     */
+    interface OnTakePictureCallback {
+        void onPictureTaken(Bitmap bitmap);
+    }
+
+    /**
+     * 垂直方向 {@link #setOrientation(int)}
+     */
+    public static final int ORIENTATION_PORTRAIT = 0;
+    /**
+     * 水平方向 {@link #setOrientation(int)}
+     */
+    public static final int ORIENTATION_HORIZONTAL = 90;
+    /**
+     * 水平翻转方向 {@link #setOrientation(int)}
+     */
+    public static final int ORIENTATION_INVERT = 270;
+
+    @IntDef({ORIENTATION_PORTRAIT, ORIENTATION_HORIZONTAL, ORIENTATION_INVERT})
+    public @interface Orientation {
+
+    }
+
+    private CameraViewTakePictureCallback cameraViewTakePictureCallback = new CameraViewTakePictureCallback();
+
+    private ICameraControl cameraControl;
+
+    /**
+     * 相机预览View
+     */
+    private View displayView;
+    /**
+     * 身份证,银行卡,等裁剪用的遮罩
+     */
+//    private MaskView maskView;
+
+    /**
+     * 用于显示提示证 "请对齐身份证正面" 之类的
+     */
+    private ImageView hintView;
+
+    public ICameraControl getCameraControl() {
+        return cameraControl;
+    }
+
+    public void setOrientation(@Orientation int orientation) {
+        cameraControl.setDisplayOrientation(orientation);
+    }
+
+    public CameraView(Context context) {
+        super(context);
+        init();
+    }
+
+    public CameraView(Context context, AttributeSet attrs) {
+        super(context, attrs);
+        init();
+    }
+
+    public CameraView(Context context, AttributeSet attrs, int defStyleAttr) {
+        super(context, attrs, defStyleAttr);
+        init();
+    }
+
+    public void start() {
+        cameraControl.start();
+        setKeepScreenOn(true);
+    }
+
+    public void stop() {
+        cameraControl.stop();
+        setKeepScreenOn(false);
+    }
+
+
+    private void init() {
+        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
+            cameraControl = new Camera2Control(getContext());
+        } else {
+            cameraControl = new Camera1Control(getContext());
+        }
+        displayView = cameraControl.getDisplayView();
+        addView(displayView);
+
+
+        hintView = new ImageView(getContext());
+        addView(hintView);
+    }
+
+    @Override
+    protected void onLayout(boolean changed, int left, int top, int right, int bottom) {
+        displayView.layout(left, 0, right, bottom - top);
+    }
+
+//    @Override
+//    protected void onDetachedFromWindow() {
+//        super.onDetachedFromWindow();
+//        if (cameraViewTakePictureCallback.thread != null) {
+//            cameraViewTakePictureCallback.thread.quit();
+//        }
+//    }
+
+    private class CameraViewTakePictureCallback implements ICameraControl.OnTakePictureCallback {
+
+//        private File file;
+//        private OnTakePictureCallback callback;
+//
+//        HandlerThread thread = new HandlerThread("cropThread");
+//        Handler handler;
+//
+//        {
+//            thread.start();
+//            handler = new Handler(thread.getLooper());
+//        }
+
+        @Override
+        public void onPictureTaken(final byte[] data) {
+//            handler.post(new Runnable() {
+//                @Override
+//                public void run() {
+//                    try {
+//                        final int rotation = ImageUtil.getOrientation(data);
+//                        final File tempFile = File.createTempFile(String.valueOf(System.currentTimeMillis()), "jpg");
+//                        FileOutputStream fileOutputStream = new FileOutputStream(tempFile);
+//                        fileOutputStream.write(data);
+//                        fileOutputStream.flush();
+//                        fileOutputStream.close();
+//                    } catch (IOException e) {
+//                        e.printStackTrace();
+//                    }
+//                }
+//            });
+        }
+    }
+}

+ 135 - 0
app_modular/faceplatform-ui/src/main/java/com/baidu/aip/face/camera/ICameraControl.java

@@ -0,0 +1,135 @@
+/*
+ * Copyright (C) 2017 Baidu, Inc. All Rights Reserved.
+ */
+package com.baidu.aip.face.camera;
+
+import com.baidu.aip.face.PreviewView;
+
+import android.graphics.Rect;
+import android.support.annotation.IntDef;
+import android.view.View;
+
+/**
+ * Android 5.0 相机的API发生很大的变化。些类屏蔽掉了 api的变化。相机的操作和功能,抽象剥离出来。
+ */
+public interface ICameraControl<T> {
+
+    interface OnFrameListener<T> {
+        void onPreviewFrame(T data, int rotation, int width, int height);
+    }
+
+    /**
+     * 闪光灯关 {@link #setFlashMode(int)}
+     */
+    int FLASH_MODE_OFF = 0;
+    /**
+     * 闪光灯开 {@link #setFlashMode(int)}
+     */
+    int FLASH_MODE_TORCH = 1;
+    /**
+     * 闪光灯自动 {@link #setFlashMode(int)}
+     */
+    int FLASH_MODE_AUTO = 2;
+
+    @IntDef({FLASH_MODE_TORCH, FLASH_MODE_OFF, FLASH_MODE_AUTO})
+    @interface FlashMode {
+
+    }
+
+    int CAMERA_FACING_BACK = 0;
+
+    int CAMERA_FACING_FRONT = 1;
+
+    @IntDef({CAMERA_FACING_FRONT, CAMERA_FACING_BACK})
+    @interface CameraFacing {
+
+    }
+
+    /**
+     * 照相回调。
+     */
+    interface OnTakePictureCallback {
+        void onPictureTaken(byte[] data);
+    }
+
+    /**
+     * 打开相机。
+     */
+    void start();
+
+    /**
+     * 关闭相机
+     */
+    void stop();
+
+    void pause();
+
+    void resume();
+
+    void setOnFrameListener(OnFrameListener listener);
+
+    void setPreferredPreviewSize(int width, int height);
+
+    /**
+     * 相机对应的预览视图。
+     *
+     * @return 预览视图
+     */
+    View getDisplayView();
+
+    void setPreviewView(PreviewView previewView);
+
+    PreviewView getPreviewView();
+
+    /**
+     * 看到的预览可能不是照片的全部。返回预览视图的全貌。
+     *
+     * @return 预览视图frame;
+     */
+    Rect getPreviewFrame();
+
+    /**
+     * 拍照。结果在回调中获取。
+     *
+     * @param callback 拍照结果回调
+     */
+    void takePicture(OnTakePictureCallback callback);
+
+    /**
+     * 设置权限回调,当手机没有拍照权限时,可在回调中获取。
+     *
+     * @param callback 权限回调
+     */
+    void setPermissionCallback(PermissionCallback callback);
+
+    /**
+     * 设置水平方向
+     *
+     * @param displayOrientation 参数值见 {@link CameraView.Orientation}
+     */
+    void setDisplayOrientation(@CameraView.Orientation int displayOrientation);
+
+    /**
+     * 获取到拍照权限时,调用些函数以继续。
+     */
+    void refreshPermission();
+
+    /**
+     * 设置闪光灯状态。
+     *
+     * @param flashMode {@link #FLASH_MODE_TORCH,#FLASH_MODE_OFF,#FLASH_MODE_AUTO}
+     */
+    void setFlashMode(@FlashMode int flashMode);
+
+    /**
+     * 获取当前闪光灯状态
+     *
+     * @return 当前闪光灯状态 参见 {@link #setFlashMode(int)}
+     */
+    @FlashMode
+    int getFlashMode();
+
+    void setCameraFacing(@CameraFacing int cameraFacing);
+
+    void setUsbCamera(boolean usbCamera);
+}

+ 8 - 0
app_modular/faceplatform-ui/src/main/java/com/baidu/aip/face/camera/PermissionCallback.java

@@ -0,0 +1,8 @@
+/*
+ * Copyright (C) 2017 Baidu, Inc. All Rights Reserved.
+ */
+package com.baidu.aip.face.camera;
+
+public interface PermissionCallback {
+    boolean onRequestPermission();
+}

+ 0 - 521
app_modular/faceplatform-ui/src/main/java/com/baidu/idl/face/platform/ui/FaceDetectActivity.java

@@ -1,521 +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.View;
-import android.view.WindowManager;
-import android.widget.FrameLayout;
-import android.widget.ImageView;
-import android.widget.LinearLayout;
-import android.widget.RelativeLayout;
-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.IDetectStrategy;
-import com.baidu.idl.face.platform.IDetectStrategyCallback;
-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.common.LogUtil;
-import com.modular.apputils.activity.BaseNetActivity;
-
-import java.util.HashMap;
-import java.util.Map;
-import java.util.Set;
-
-/**
- * 人脸采集接口
- */
-public abstract class FaceDetectActivity extends BaseNetActivity implements
-        SurfaceHolder.Callback,
-        Camera.PreviewCallback,
-        Camera.ErrorCallback,
-        VolumeUtils.VolumeCallback,
-        IDetectStrategyCallback {
-
-
-    // View
-    protected View mRootView;
-    protected FrameLayout mFrameLayout;
-    protected SurfaceView mSurfaceView;
-    protected SurfaceHolder mSurfaceHolder;
-    protected ImageView mCloseView;
-    protected ImageView mSoundView;
-    protected ImageView mSuccessView;
-    protected TextView mTipsTopView;
-    protected TextView mTipsBottomView;
-    protected FaceDetectRoundView mFaceDetectRoundView;
-    protected LinearLayout mImageLayout;
-    // 人脸信息
-    protected FaceConfig mFaceConfig;
-    protected IDetectStrategy mIDetectStrategy;
-    // 显示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 HashMap<String, String> mBase64ImageMap = new HashMap<String, String>();
-    protected boolean mIsCreateSurface = false;
-    protected volatile 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
-    protected int getLayoutId() {
-        return R.layout.activity_face_detect_v3100;
-    }
-
-    @Override
-    protected void init() throws Exception {
-        getWindow().addFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON);
-        Ast.getInstance().init(getApplicationContext(), "3.1.0.0", "facenormal");
-        DisplayMetrics dm = new DisplayMetrics();
-        Display display = this.getWindowManager().getDefaultDisplay();
-        display.getMetrics(dm);
-        mDisplayWidth = dm.widthPixels;
-        mDisplayHeight = dm.heightPixels;
-        FaceSDKResSettings.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;
-
-        mRootView = this.findViewById(R.id.detect_root_layout);
-        mFrameLayout = (FrameLayout) mRootView.findViewById(R.id.detect_surface_layout);
-
-        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);
-
-        mRootView.findViewById(R.id.detect_close).setOnClickListener(new View.OnClickListener() {
-            @Override
-            public void onClick(View v) {
-                onBackPressed();
-            }
-        });
-
-        mFaceDetectRoundView = (FaceDetectRoundView) mRootView.findViewById(R.id.detect_face_round);
-        mCloseView = (ImageView) mRootView.findViewById(R.id.detect_close);
-        mSoundView = (ImageView) mRootView.findViewById(R.id.detect_sound);
-        mSoundView.setImageResource(mIsEnableSound ?
-                R.mipmap.ic_enable_sound_ext : R.mipmap.ic_disable_sound_ext);
-        mSoundView.setOnClickListener(new View.OnClickListener() {
-            @Override
-            public void onClick(View v) {
-                mIsEnableSound = !mIsEnableSound;
-                mSoundView.setImageResource(mIsEnableSound ?
-                        R.mipmap.ic_enable_sound_ext : R.mipmap.ic_disable_sound_ext);
-                if (mIDetectStrategy != null) {
-                    mIDetectStrategy.setDetectStrategySoundEnable(mIsEnableSound);
-                }
-            }
-        });
-        mTipsTopView = (TextView) mRootView.findViewById(R.id.detect_top_tips);
-        mTipsBottomView = (TextView) mRootView.findViewById(R.id.detect_bottom_tips);
-        mSuccessView = (ImageView) mRootView.findViewById(R.id.detect_success_image);
-
-        mImageLayout = (LinearLayout) mRootView.findViewById(R.id.detect_result_image_layout);
-        if (mBase64ImageMap != null) {
-            mBase64ImageMap.clear();
-        }
-    }
-
-    @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() {
-        super.onStop();
-        VolumeUtils.unRegisterVolumeReceiver(this, mVolumeReceiver);
-        mVolumeReceiver = null;
-        if (mIDetectStrategy != null) {
-            mIDetectStrategy.reset();
-        }
-        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 (mIDetectStrategy != null) {
-                    mIDetectStrategy.setDetectStrategySoundEnable(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;
-        if (mIDetectStrategy != null) {
-            mIDetectStrategy.setPreviewDegree(degree);
-        }
-
-        Point point = CameraPreviewUtils.getBestPreview(mCameraParam,
-                new Point(mDisplayWidth, mDisplayHeight));
-        mPreviewWidth = point.x;
-        mPreviewHight = point.y;
-        // Preview 768,432
-        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 (mIDetectStrategy != null) {
-            mIDetectStrategy = 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 (mIDetectStrategy == null && mFaceDetectRoundView != null && mFaceDetectRoundView.getRound() > 0) {
-            mIDetectStrategy = FaceSDKManager.getInstance().getDetectStrategyModule();
-            mIDetectStrategy.setPreviewDegree(mPreviewDegree);
-            mIDetectStrategy.setDetectStrategySoundEnable(mIsEnableSound);
-
-            Rect detectRect = FaceDetectRoundView.getPreviewDetectRect(mDisplayWidth, mPreviewHight, mPreviewWidth);
-            mIDetectStrategy.setDetectStrategyConfig(mPreviewRect, detectRect, this);
-        }
-        if (mIDetectStrategy != null) {
-            mIDetectStrategy.detectStrategy(data);
-        }
-    }
-
-
-    @Override
-    public void onError(int error, Camera camera) {
-    }
-
-    @Override
-    public void onDetectCompletion(FaceStatusEnum status, String message,
-                                   HashMap<String, String> base64ImageMap) {
-        LogUtil.i("gong","onDetectCompletion");
-        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:
-                onRefreshTipsView(false, message);
-                mTipsBottomView.setText("");
-                mFaceDetectRoundView.processDrawState(false);
-                onRefreshSuccessView(true);
-                break;
-            case Detect_PitchOutOfUpMaxRange:
-            case Detect_PitchOutOfDownMaxRange:
-            case Detect_PitchOutOfLeftMaxRange:
-            case Detect_PitchOutOfRightMaxRange:
-                onRefreshTipsView(true, message);
-                mTipsBottomView.setText(message);
-                mFaceDetectRoundView.processDrawState(true);
-                onRefreshSuccessView(false);
-                break;
-            default:
-                onRefreshTipsView(false, message);
-                mTipsBottomView.setText("");
-                mFaceDetectRoundView.processDrawState(true);
-                onRefreshSuccessView(false);
-        }
-    }
-
-    private void onRefreshTipsView(boolean isAlert, String 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 onRefreshSuccessView(boolean isShow) {
-        if (mSuccessView.getTag() == null) {
-            Rect rect = mFaceDetectRoundView.getFaceRoundRect();
-            RelativeLayout.LayoutParams rlp = (RelativeLayout.LayoutParams) mSuccessView.getLayoutParams();
-            rlp.setMargins(
-                    rect.centerX() - (mSuccessView.getWidth() / 2),
-                    rect.top - (mSuccessView.getHeight() / 2),
-                    0,
-                    0);
-            mSuccessView.setLayoutParams(rlp);
-            mSuccessView.setTag("setlayout");
-        }
-        mSuccessView.setVisibility(isShow ? View.VISIBLE : View.INVISIBLE);
-    }
-
-    private void saveImage(HashMap<String, String> imageMap) {
-        Set<Map.Entry<String, String>> sets = imageMap.entrySet();
-        Bitmap bmp = null;
-        mImageLayout.removeAllViews();
-        for (Map.Entry<String, String> entry : sets) {
-            String bmpBase64 = entry.getValue();
-            if (!TextUtils.isEmpty(bmpBase64)) {
-                saveBmpBase64Ok(bmpBase64);
-                break;
-            }
-//            bmp = base64ToBitmap();
-//            ImageView iv = new ImageView(this);
-//            iv.setImageBitmap(bmp);
-//            mImageLayout.addView(iv, new LinearLayout.LayoutParams(100, 100));
-        }
-    }
-
-    private static Bitmap base64ToBitmap(String base64Data) {
-        byte[] bytes = Base64Utils.decode(base64Data, Base64Utils.NO_WRAP);
-        return BitmapFactory.decodeByteArray(bytes, 0, bytes.length);
-    }
-
-    public abstract void saveBmpBase64Ok(String bmpBase64);
-
-
-
-
-}
-

+ 0 - 526
app_modular/faceplatform-ui/src/main/java/com/baidu/idl/face/platform/ui/FaceLivenessActivity.java

@@ -1,526 +0,0 @@
-/**
- * Copyright (C) 2017 Baidu Inc. All rights reserved.
- */
-package com.baidu.idl.face.platform.ui;
-
-import android.app.Activity;
-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.os.Bundle;
-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.View;
-import android.view.WindowManager;
-import android.widget.FrameLayout;
-import android.widget.ImageView;
-import android.widget.LinearLayout;
-import android.widget.RelativeLayout;
-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 java.util.HashMap;
-import java.util.Map;
-import java.util.Set;
-
-/**
- * 活体检测接口
- */
-public class FaceLivenessActivity extends Activity implements
-        SurfaceHolder.Callback,
-        Camera.PreviewCallback,
-        Camera.ErrorCallback,
-        VolumeUtils.VolumeCallback,
-        ILivenessStrategyCallback {
-
-    public static final String TAG = FaceLivenessActivity.class.getSimpleName();
-
-    // View
-    protected View mRootView;
-    protected FrameLayout mFrameLayout;
-    protected SurfaceView mSurfaceView;
-    protected SurfaceHolder mSurfaceHolder;
-    protected ImageView mCloseView;
-    protected ImageView mSoundView;
-    protected ImageView mSuccessView;
-    protected TextView mTipsTopView;
-    protected TextView mTipsBottomView;
-    protected FaceDetectRoundView mFaceDetectRoundView;
-    protected LinearLayout mImageLayout;
-    // 人脸信息
-    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 HashMap<String, String> mBase64ImageMap = new HashMap<String, String>();
-    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 onCreate(Bundle savedInstanceState) {
-        super.onCreate(savedInstanceState);
-        getWindow().addFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON);
-        Ast.getInstance().init(getApplicationContext(), "3.1.0.0", "facenormal");
-        setContentView(R.layout.activity_face_liveness_v3100);
-        DisplayMetrics dm = new DisplayMetrics();
-        Display display = this.getWindowManager().getDefaultDisplay();
-        display.getMetrics(dm);
-        mDisplayWidth = dm.widthPixels;
-        mDisplayHeight = dm.heightPixels;
-
-        FaceSDKResSettings.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;
-
-        mRootView = this.findViewById(R.id.liveness_root_layout);
-        mFrameLayout = (FrameLayout) mRootView.findViewById(R.id.liveness_surface_layout);
-
-        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);
-
-        mRootView.findViewById(R.id.liveness_close).setOnClickListener(new View.OnClickListener() {
-            @Override
-            public void onClick(View v) {
-                onBackPressed();
-            }
-        });
-
-        mFaceDetectRoundView = (FaceDetectRoundView) mRootView.findViewById(R.id.liveness_face_round);
-        mCloseView = (ImageView) mRootView.findViewById(R.id.liveness_close);
-        mSoundView = (ImageView) mRootView.findViewById(R.id.liveness_sound);
-        mSoundView.setImageResource(mIsEnableSound ?
-                R.mipmap.ic_enable_sound_ext : R.mipmap.ic_disable_sound_ext);
-        mSoundView.setOnClickListener(new View.OnClickListener() {
-            @Override
-            public void onClick(View v) {
-                mIsEnableSound = !mIsEnableSound;
-                mSoundView.setImageResource(mIsEnableSound ?
-                        R.mipmap.ic_enable_sound_ext : R.mipmap.ic_disable_sound_ext);
-                if (mILivenessStrategy != null) {
-                    mILivenessStrategy.setLivenessStrategySoundEnable(mIsEnableSound);
-                }
-            }
-        });
-        mTipsTopView = (TextView) mRootView.findViewById(R.id.liveness_top_tips);
-        mTipsBottomView = (TextView) mRootView.findViewById(R.id.liveness_bottom_tips);
-        mSuccessView = (ImageView) mRootView.findViewById(R.id.liveness_success_image);
-
-        mImageLayout = (LinearLayout) mRootView.findViewById(R.id.liveness_result_image_layout);
-        if (mBase64ImageMap != null) {
-            mBase64ImageMap.clear();
-        }
-    }
-
-    @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);
-                mTipsBottomView.setText("");
-                mFaceDetectRoundView.processDrawState(false);
-                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);
-                mTipsBottomView.setText("");
-                mFaceDetectRoundView.processDrawState(false);
-                onRefreshSuccessView(false);
-                break;
-            case Detect_PitchOutOfUpMaxRange:
-            case Detect_PitchOutOfDownMaxRange:
-            case Detect_PitchOutOfLeftMaxRange:
-            case Detect_PitchOutOfRightMaxRange:
-                onRefreshTipsView(true, message);
-                mTipsBottomView.setText(message);
-                mFaceDetectRoundView.processDrawState(true);
-                onRefreshSuccessView(false);
-                break;
-            default:
-                onRefreshTipsView(false, message);
-                mTipsBottomView.setText("");
-                mFaceDetectRoundView.processDrawState(true);
-                onRefreshSuccessView(false);
-        }
-    }
-
-    private void onRefreshTipsView(boolean isAlert, String 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 onRefreshSuccessView(boolean isShow) {
-        if (mSuccessView.getTag() == null) {
-            Rect rect = mFaceDetectRoundView.getFaceRoundRect();
-            RelativeLayout.LayoutParams rlp = (RelativeLayout.LayoutParams) mSuccessView.getLayoutParams();
-            rlp.setMargins(
-                    rect.centerX() - (mSuccessView.getWidth() / 2),
-                    rect.top - (mSuccessView.getHeight() / 2),
-                    0,
-                    0);
-            mSuccessView.setLayoutParams(rlp);
-            mSuccessView.setTag("setlayout");
-        }
-        mSuccessView.setVisibility(isShow ? View.VISIBLE : View.INVISIBLE);
-    }
-
-    private void saveImage(HashMap<String, String> imageMap) {
-        Set<Map.Entry<String, String>> sets = imageMap.entrySet();
-        Bitmap bmp = null;
-        mImageLayout.removeAllViews();
-        for (Map.Entry<String, String> entry : sets) {
-            bmp = base64ToBitmap(entry.getValue());
-            ImageView iv = new ImageView(this);
-            iv.setImageBitmap(bmp);
-            mImageLayout.addView(iv, new LinearLayout.LayoutParams(300, 300));
-        }
-    }
-
-    private static Bitmap base64ToBitmap(String base64Data) {
-        byte[] bytes = Base64Utils.decode(base64Data, Base64Utils.NO_WRAP);
-        return BitmapFactory.decodeByteArray(bytes, 0, bytes.length);
-    }
-
-}

+ 2 - 2
app_modular/faceplatform-ui/src/main/java/com/baidu/idl/face/platform/ui/FaceSDKResSettings.java

@@ -1,5 +1,5 @@
-/**
- * Copyright (C) 2017 Baidu Inc. All rights reserved.
+/*
+ * Copyright (C) 2017 Baidu, Inc. All Rights Reserved.
  */
 package com.baidu.idl.face.platform.ui;
 

+ 535 - 0
app_modular/faceplatform-ui/src/main/java/com/baidu/idl/face/platform/ui/activity/FaceDetectActivity.java

@@ -0,0 +1,535 @@
+/*
+ * Copyright (C) 2018 Baidu, Inc. All Rights Reserved.
+ */
+package com.baidu.idl.face.platform.ui.activity;
+
+
+import android.Manifest;
+import android.content.res.Configuration;
+import android.graphics.Color;
+import android.graphics.Rect;
+import android.graphics.RectF;
+import android.os.Build;
+import android.os.Handler;
+import android.os.Message;
+import android.support.v4.app.ActivityCompat;
+import android.util.DisplayMetrics;
+import android.view.View;
+import android.view.ViewTreeObserver;
+import android.view.WindowManager;
+import android.widget.ImageView;
+import android.widget.RelativeLayout;
+import android.widget.TextView;
+
+import com.baidu.aip.face.CameraImageSource;
+import com.baidu.aip.face.DetectRegionProcessor;
+import com.baidu.aip.face.FaceDetectManager;
+import com.baidu.aip.face.FaceFilter;
+import com.baidu.aip.face.ImageFrame;
+import com.baidu.aip.face.PreviewView;
+import com.baidu.aip.face.camera.ICameraControl;
+import com.baidu.aip.face.camera.PermissionCallback;
+import com.baidu.idl.face.platform.FaceSDKManager;
+import com.baidu.idl.face.platform.ui.R;
+import com.baidu.idl.face.platform.ui.utils.BrightnessTools;
+import com.baidu.idl.face.platform.ui.widget.FaceRoundView;
+import com.baidu.idl.face.platform.ui.widget.WaveHelper;
+import com.baidu.idl.face.platform.ui.widget.WaveView;
+import com.baidu.idl.facesdk.FaceInfo;
+import com.common.LogUtil;
+import com.modular.apputils.activity.BaseNetActivity;
+
+import java.lang.ref.WeakReference;
+
+/**
+ * 实时检测调用identify进行人脸识别,MainActivity未给出改示例的入口,开发者可以在MainActivity调用
+ * Intent intent = new Intent(MainActivity.this, DetectLoginActivity.class);
+ * startActivity(intent);
+ */
+public abstract class FaceDetectActivity extends BaseNetActivity {
+
+    private final static int MSG_INITVIEW = 1001;
+    private TextView nameTextView;
+    private PreviewView previewView;
+    private View mInitView;
+    private FaceRoundView rectView;
+    private boolean mGoodDetect = false;
+    private static final double ANGLE = 15;
+    private ImageView closeIv;
+    private boolean mDetectStoped = false;
+    private ImageView mSuccessView;
+    private Handler mHandler;
+    private String mCurTips;
+    private boolean mUploading = false;
+    private long mLastTipsTime = 0;
+    private int mCurFaceId = -1;
+
+    private FaceDetectManager faceDetectManager;
+    private DetectRegionProcessor cropProcessor = new DetectRegionProcessor();
+    private WaveHelper mWaveHelper;
+    private WaveView mWaveview;
+    private int mBorderColor = Color.parseColor("#28FFFFFF");
+    private int mBorderWidth = 0;
+    private int mScreenW;
+    private int mScreenH;
+
+
+    @Override
+    protected int getLayoutId() {
+        return R.layout.activity_login_detected;
+    }
+
+    public void init() {
+        faceDetectManager = new FaceDetectManager(this);
+        initScreen();
+        initView();
+        mHandler = new InnerHandler(this);
+        mHandler.sendEmptyMessageDelayed(MSG_INITVIEW, 500);
+
+
+    }
+
+    private void initScreen() {
+        WindowManager manager = getWindowManager();
+        DisplayMetrics outMetrics = new DisplayMetrics();
+        manager.getDefaultDisplay().getMetrics(outMetrics);
+        mScreenW = outMetrics.widthPixels;
+        mScreenH = outMetrics.heightPixels;
+    }
+
+    private void initView() {
+        mInitView = findViewById(R.id.camera_layout);
+        previewView = (PreviewView) findViewById(R.id.preview_view);
+
+        rectView = (FaceRoundView) findViewById(R.id.rect_view);
+        final CameraImageSource cameraImageSource = new CameraImageSource(this);
+        cameraImageSource.setPreviewView(previewView);
+
+        faceDetectManager.setImageSource(cameraImageSource);
+        faceDetectManager.setOnFaceDetectListener(new FaceDetectManager.OnFaceDetectListener() {
+            @Override
+            public void onDetectFace(final int retCode, FaceInfo[] infos, ImageFrame frame) {
+                if (mGoodDetect) {
+                    return;
+                }
+                String str = "";
+                if (retCode == 0) {
+                    if (infos != null && infos[0] != null) {
+                        FaceInfo info = infos[0];
+                        boolean distance = false;
+                        if (info != null && frame != null) {
+                            if (info.mWidth >= (0.9 * frame.getWidth())) {
+                                distance = false;
+                                str = getResources().getString(R.string.detect_zoom_out);
+                            } else if (info.mWidth <= 0.4 * frame.getWidth()) {
+                                distance = false;
+                                str = getResources().getString(R.string.detect_zoom_in);
+                            } else {
+                                distance = true;
+                            }
+                        }
+                        boolean headUpDown;
+                        if (info != null) {
+                            if (info.headPose[0] >= ANGLE) {
+                                headUpDown = false;
+                                str = getResources().getString(R.string.detect_head_up);
+                            } else if (info.headPose[0] <= -ANGLE) {
+                                headUpDown = false;
+                                str = getResources().getString(R.string.detect_head_down);
+                            } else {
+                                headUpDown = true;
+                            }
+
+                            boolean headLeftRight;
+                            if (info.headPose[1] >= ANGLE) {
+                                headLeftRight = false;
+                                str = getResources().getString(R.string.detect_head_left);
+                            } else if (info.headPose[1] <= -ANGLE) {
+                                headLeftRight = false;
+                                str = getResources().getString(R.string.detect_head_right);
+                            } else {
+                                headLeftRight = true;
+                            }
+
+                            if (distance && headUpDown && headLeftRight) {
+                                mGoodDetect = true;
+                            } else {
+                                mGoodDetect = false;
+                            }
+
+                        }
+                    }
+                } else if (retCode == 1) {
+                    str = getResources().getString(R.string.detect_head_up);
+                } else if (retCode == 2) {
+                    str = getResources().getString(R.string.detect_head_down);
+                } else if (retCode == 3) {
+                    str = getResources().getString(R.string.detect_head_left);
+                } else if (retCode == 4) {
+                    str = getResources().getString(R.string.detect_head_right);
+                } else if (retCode == 5) {
+                    str = getResources().getString(R.string.detect_low_light);
+                } else if (retCode == 6) {
+                    str = getResources().getString(R.string.detect_face_in);
+                } else if (retCode == 7) {
+                    str = getResources().getString(R.string.detect_face_in);
+                } else if (retCode == 10) {
+                    str = getResources().getString(R.string.detect_keep);
+                } else if (retCode == 11) {
+                    str = getResources().getString(R.string.detect_occ_right_eye);
+                } else if (retCode == 12) {
+                    str = getResources().getString(R.string.detect_occ_left_eye);
+                } else if (retCode == 13) {
+                    str = getResources().getString(R.string.detect_occ_nose);
+                } else if (retCode == 14) {
+                    str = getResources().getString(R.string.detect_occ_mouth);
+                } else if (retCode == 15) {
+                    str = getResources().getString(R.string.detect_right_contour);
+                } else if (retCode == 16) {
+                    str = getResources().getString(R.string.detect_left_contour);
+                } else if (retCode == 17) {
+                    str = getResources().getString(R.string.detect_chin_contour);
+                }
+
+                boolean faceChanged = true;
+                if (infos != null && infos[0] != null) {
+                    if (infos[0].face_id == mCurFaceId) {
+                        faceChanged = false;
+                    } else {
+                        faceChanged = true;
+                    }
+                    mCurFaceId = infos[0].face_id;
+                }
+
+                if (faceChanged) {
+                    showProgressBar(false);
+                    onRefreshSuccessView(false);
+                }
+
+                final int resultCode = retCode;
+                if (!(mGoodDetect && retCode == 0)) {
+                    if (faceChanged) {
+                        showProgressBar(false);
+                        onRefreshSuccessView(false);
+                    }
+                }
+
+                if (retCode == 6 || retCode == 7 || retCode < 0) {
+                    rectView.processDrawState(true);
+                } else {
+                    rectView.processDrawState(false);
+                }
+
+                mCurTips = str;
+                runOnUiThread(new Runnable() {
+                    @Override
+                    public void run() {
+                        if ((System.currentTimeMillis() - mLastTipsTime) > 1000) {
+                            nameTextView.setText(mCurTips);
+                            mLastTipsTime = System.currentTimeMillis();
+                        }
+                        if (mGoodDetect && resultCode == 0) {
+                            LogUtil.i("gong", "成功了");
+                            nameTextView.setText("");
+                            onRefreshSuccessView(true);
+                            showProgressBar(true);
+                        }
+                    }
+                });
+
+                if (infos == null) {
+                    mGoodDetect = false;
+                }
+            }
+        });
+        faceDetectManager.setOnTrackListener(new FaceFilter.OnTrackListener() {
+            @Override
+            public void onTrack(final FaceFilter.TrackedModel trackedModel) {
+                if (trackedModel.meetCriteria() && mGoodDetect && !mUploading) {
+                    mGoodDetect = false;
+                    mDetectStoped = true;
+                    mUploading = true;
+                    runOnUiThread(new Runnable() {
+                        @Override
+                        public void run() {
+                            stopDetect();
+                            faceAlready(trackedModel);
+                        }
+                    });
+
+                }
+            }
+        });
+
+        cameraImageSource.getCameraControl().setPermissionCallback(new PermissionCallback() {
+            @Override
+            public boolean onRequestPermission() {
+                ActivityCompat.requestPermissions(FaceDetectActivity.this,
+                        new String[]{Manifest.permission.CAMERA}, 100);
+                return true;
+            }
+        });
+
+        rectView.getViewTreeObserver().addOnGlobalLayoutListener(new ViewTreeObserver.OnGlobalLayoutListener() {
+            @Override
+            public void onGlobalLayout() {
+                start();
+                if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN) {
+                    rectView.getViewTreeObserver().removeOnGlobalLayoutListener(this);
+                }
+            }
+        });
+        ICameraControl control = cameraImageSource.getCameraControl();
+        control.setPreviewView(previewView);
+        // 设置检测裁剪处理器
+        faceDetectManager.addPreProcessor(cropProcessor);
+
+        int orientation = getResources().getConfiguration().orientation;
+        boolean isPortrait = (orientation == Configuration.ORIENTATION_PORTRAIT);
+
+        if (isPortrait) {
+            previewView.setScaleType(PreviewView.ScaleType.FIT_WIDTH);
+        } else {
+            previewView.setScaleType(PreviewView.ScaleType.FIT_HEIGHT);
+        }
+        int rotation = getWindowManager().getDefaultDisplay().getRotation();
+        cameraImageSource.getCameraControl().setDisplayOrientation(rotation);
+        //   previewView.getTextureView().setScaleX(-1);
+        nameTextView = (TextView) findViewById(R.id.name_text_view);
+        closeIv = (ImageView) findViewById(R.id.closeIv);
+        closeIv.setOnClickListener(new View.OnClickListener() {
+            @Override
+            public void onClick(View v) {
+                finish();
+            }
+        });
+        mSuccessView = (ImageView) findViewById(R.id.success_image);
+
+        mSuccessView.getViewTreeObserver().addOnGlobalLayoutListener(new ViewTreeObserver.OnGlobalLayoutListener() {
+            @Override
+            public void onGlobalLayout() {
+                if (mSuccessView.getTag() == null) {
+                    Rect rect = rectView.getFaceRoundRect();
+                    RelativeLayout.LayoutParams rlp = (RelativeLayout.LayoutParams) mSuccessView.getLayoutParams();
+                    int w = (int) getResources().getDimension(R.dimen.success_width);
+                    rlp.setMargins(
+                            rect.centerX() - (w / 2),
+                            rect.top - (w / 2),
+                            0,
+                            0);
+                    mSuccessView.setLayoutParams(rlp);
+                    mSuccessView.setTag("setlayout");
+                }
+                mSuccessView.setVisibility(View.GONE);
+                if (Build.VERSION.SDK_INT < Build.VERSION_CODES.JELLY_BEAN) {
+                    mSuccessView.getViewTreeObserver().removeGlobalOnLayoutListener(this);
+                } else {
+                    mSuccessView.getViewTreeObserver().removeOnGlobalLayoutListener(this);
+                }
+            }
+        });
+        initFaceSDKManager();
+    }
+
+
+    /**
+     * 已经获取到面部资源
+     *
+     * @param trackedModel
+     */
+    public abstract void faceAlready(FaceFilter.TrackedModel trackedModel);
+
+    public void reDetectStart() {
+        mUploading = false;
+        faceDetectManager.start();
+    }
+
+
+
+    private void initWaveview(Rect rect) {
+        RelativeLayout rootView = (RelativeLayout) findViewById(R.id.root_view);
+        RelativeLayout.LayoutParams waveParams = new RelativeLayout.LayoutParams(
+                rect.width(), rect.height());
+        waveParams.setMargins(rect.left, rect.top, rect.left, rect.top);
+        waveParams.addRule(RelativeLayout.ALIGN_PARENT_LEFT, RelativeLayout.TRUE);
+        waveParams.addRule(RelativeLayout.ALIGN_PARENT_TOP, RelativeLayout.TRUE);
+
+        mWaveview = new WaveView(this);
+        rootView.addView(mWaveview, waveParams);
+
+        // mWaveview = (WaveView) findViewById(R.id.wave);
+        mWaveHelper = new WaveHelper(mWaveview);
+
+        mWaveview.setShapeType(WaveView.ShapeType.CIRCLE);
+        mWaveview.setWaveColor(
+                Color.parseColor("#28FFFFFF"),
+                Color.parseColor("#3cFFFFFF"));
+        mBorderColor = Color.parseColor("#28f16d7a");
+        mWaveview.setBorder(mBorderWidth, mBorderColor);
+    }
+
+    private void visibleView() {
+        mInitView.setVisibility(View.INVISIBLE);
+    }
+
+
+    private void initBrightness() {
+        int brightness = BrightnessTools.getScreenBrightness(FaceDetectActivity.this);
+        if (brightness < 200) {
+            BrightnessTools.setBrightness(this, 200);
+        }
+    }
+
+
+    private void initFaceSDKManager() {
+        FaceSDKManager.getInstance().getFaceConfig().setCheckFaceQuality(true);
+        // 该角度为上下,左右,偏头的角度的阀值,大于将无法检测出人脸,
+        FaceSDKManager.getInstance().getFaceConfig().setHeadYawValue(45);
+        FaceSDKManager.getInstance().getFaceConfig().setHeadRollValue(45);
+        FaceSDKManager.getInstance().getFaceConfig().setHeadPitchValue(45);
+        FaceSDKManager.getInstance().getFaceConfig().setVerifyLive(false);
+        initBrightness();
+    }
+
+    @Override
+    protected String getBaseUrl() {
+        return null;
+    }
+
+    private void start() {
+
+        Rect dRect = rectView.getFaceRoundRect();
+
+        //   RectF newDetectedRect = new RectF(detectedRect);
+        int preGap = getResources().getDimensionPixelOffset(R.dimen.preview_margin);
+        int w = getResources().getDimensionPixelOffset(R.dimen.detect_out);
+
+        int orientation = getResources().getConfiguration().orientation;
+        boolean isPortrait = (orientation == Configuration.ORIENTATION_PORTRAIT);
+        if (isPortrait) {
+            // 检测区域矩形宽度
+            int rWidth = mScreenW - 2 * preGap;
+            // 圆框宽度
+            int dRectW = dRect.width();
+            // 检测矩形和圆框偏移
+            int h = (rWidth - dRectW) / 2;
+            //  Log.d("liujinhui hi is:", " h is:" + h + "d is:" + (dRect.left - 150));
+            int rLeft = w;
+            int rRight = rWidth - w;
+            int rTop = dRect.top - h - preGap + w;
+            int rBottom = rTop + rWidth - w;
+
+            //  Log.d("liujinhui", " rLeft is:" + rLeft + "rRight is:" + rRight + "rTop is:" + rTop + "rBottom is:" + rBottom);
+            RectF newDetectedRect = new RectF(rLeft, rTop, rRight, rBottom);
+            cropProcessor.setDetectedRect(newDetectedRect);
+        } else {
+            int rLeft = mScreenW / 2 - mScreenH / 2 + w;
+            int rRight = mScreenW / 2 + mScreenH / 2 + w;
+            int rTop = 0;
+            int rBottom = mScreenH;
+
+            RectF newDetectedRect = new RectF(rLeft, rTop, rRight, rBottom);
+            cropProcessor.setDetectedRect(newDetectedRect);
+        }
+
+
+        faceDetectManager.start();
+        initWaveview(dRect);
+    }
+
+    @Override
+    protected void onStop() {
+        super.onStop();
+        stopDetect();
+    }
+
+    private void stopDetect() {
+        faceDetectManager.stop();
+        onRefreshSuccessView(false);
+        if (mWaveview != null) {
+            mWaveview.setVisibility(View.GONE);
+            mWaveHelper.cancel();
+        }
+    }
+
+    private void showProgressBar(final boolean show) {
+        runOnUiThread(new Runnable() {
+            @Override
+            public void run() {
+                if (show) {
+                    if (mWaveview != null) {
+                        mWaveview.setVisibility(View.VISIBLE);
+                        mWaveHelper.start();
+                    }
+                } else {
+                    if (mWaveview != null) {
+                        mWaveview.setVisibility(View.GONE);
+                        mWaveHelper.cancel();
+                    }
+                }
+
+            }
+        });
+    }
+
+    @Override
+    protected void onPause() {
+        super.onPause();
+        if (mWaveview != null) {
+            mWaveHelper.cancel();
+            mWaveview.setVisibility(View.GONE);
+        }
+    }
+
+    @Override
+    protected void onResume() {
+        super.onResume();
+        if (mDetectStoped && !mUploading) {
+            faceDetectManager.start();
+            mDetectStoped = false;
+        }
+
+    }
+
+    private void onRefreshSuccessView(final boolean isShow) {
+
+        runOnUiThread(new Runnable() {
+            @Override
+            public void run() {
+                mSuccessView.setVisibility(isShow ? View.VISIBLE : View.INVISIBLE);
+            }
+        });
+    }
+
+    private static class InnerHandler extends Handler {
+        private WeakReference<FaceDetectActivity> mWeakReference;
+
+        public InnerHandler(FaceDetectActivity activity) {
+            super();
+            this.mWeakReference = new WeakReference<FaceDetectActivity>(activity);
+        }
+
+        @Override
+        public void handleMessage(Message msg) {
+            if (mWeakReference == null || mWeakReference.get() == null) {
+                return;
+            }
+            FaceDetectActivity activity = mWeakReference.get();
+            if (activity == null) {
+                return;
+            }
+            if (msg == null) {
+                return;
+
+            }
+            switch (msg.what) {
+                case MSG_INITVIEW:
+                    activity.visibleView();
+                    break;
+                default:
+                    break;
+            }
+        }
+    }
+
+}

+ 16 - 16
app_modular/faceplatform-ui/src/main/java/com/baidu/idl/face/platform/ui/FaceVeriftyActivity.java → app_modular/faceplatform-ui/src/main/java/com/baidu/idl/face/platform/ui/activity/FaceVeriftyActivity.java

@@ -1,13 +1,14 @@
-package com.baidu.idl.face.platform.ui;
+package com.baidu.idl.face.platform.ui.activity;
 
 import android.text.TextUtils;
 
 import com.alibaba.fastjson.JSON;
 import com.alibaba.fastjson.JSONArray;
 import com.alibaba.fastjson.JSONObject;
+import com.baidu.aip.face.FaceFilter;
 import com.baidu.idl.face.platform.ui.config.FaceConfig;
 import com.baidu.idl.face.platform.ui.model.FaceVerify;
-import com.baidu.idl.face.platform.ui.widget.VeriftyDialog;
+import com.baidu.idl.face.platform.utils.BitmapUtils;
 import com.common.LogUtil;
 import com.common.data.JSONUtil;
 import com.common.data.ListUtils;
@@ -17,6 +18,7 @@ import com.me.network.app.http.HttpClient;
 import com.me.network.app.http.Method;
 import com.me.network.app.http.rx.Result2Listener;
 import com.me.network.app.http.rx.ResultSubscriber;
+import com.modular.apputils.widget.VeriftyDialog;
 
 public class FaceVeriftyActivity extends FaceDetectActivity {
 
@@ -27,15 +29,14 @@ public class FaceVeriftyActivity extends FaceDetectActivity {
     }
 
 
-    //成功获取到Base64数据
     @Override
-    public void saveBmpBase64Ok(String bmpBase64) {
+    public void faceAlready(FaceFilter.TrackedModel trackedModel) {
+        String bmpBase64 = BitmapUtils.bitmapToJpegBase64(trackedModel.cropFace(), 100);
         String master = CommonUtil.getMaster();
         String imid = MyApplication.getInstance().getLoginUserId();
         verify(bmpBase64, master, imid);
     }
 
-
     private void showRegisterDialog(final String faceBase64, final String group_id_list, final String user_id) {
         new VeriftyDialog.Builder(this)
                 .setCanceledOnTouchOutside(false)
@@ -92,7 +93,6 @@ public class FaceVeriftyActivity extends FaceDetectActivity {
         } else {
             message = result;
         }
-        final boolean needReset = message.equals("活体检测未通过,是否重新验证?");
         new VeriftyDialog.Builder(this)
                 .setCanceledOnTouchOutside(false)
                 .setContent(message)
@@ -100,10 +100,10 @@ public class FaceVeriftyActivity extends FaceDetectActivity {
                 .build(new VeriftyDialog.OnDialogClickListener() {
                     @Override
                     public void result(boolean clickSure) {
-                        if (needReset && clickSure) {
-                            mIsCompletion = false;
+                        if (clickSure) {
+                            reDetectStart();
                         } else {
-                            //TODO 其他情况
+                            finish();
                         }
                     }
                 });
@@ -112,11 +112,11 @@ public class FaceVeriftyActivity extends FaceDetectActivity {
     /**
      * 校验身份
      *
-     * @param faceBase64    脸部信息
-     * @param group_id_list 组Id
-     * @param user_id       用户Id
+     * @param faceBase64 脸部信息
+     * @param emUU       组Id
+     * @param imid       用户Id
      */
-    private void verify(final String faceBase64, final String group_id_list, final String user_id) {
+    private void verify(final String faceBase64, final String emUU, final String imid) {
         showProgress();
         FaceConfig.loadToken(new FaceConfig.FaceTokenListener() {
             @Override
@@ -129,9 +129,9 @@ public class FaceVeriftyActivity extends FaceDetectActivity {
                         .add("image", faceBase64)
                         .add("image_type", "BASE64")
                         .add("liveness_control", "HIGH")
-                        .add("user_id", user_id)
+                        .add("user_id", imid)
                         .isDebug(true)
-                        .add("group_id_list", group_id_list)
+                        .add("group_id_list", emUU)
                         .method(Method.POST).build(), new ResultSubscriber<>(new Result2Listener<Object>() {
                     @Override
                     public void onResponse(Object o) {
@@ -143,7 +143,7 @@ public class FaceVeriftyActivity extends FaceDetectActivity {
                                 JSONObject result = JSONUtil.getJSONObject(object, "result");
                                 JSONArray user_list = JSONUtil.getJSONArray(result, "user_list");
                                 if (ListUtils.isEmpty(user_list)) {
-                                    showRegisterDialog(faceBase64, group_id_list, user_id);
+                                    showRegisterDialog(faceBase64, emUU, imid);
                                 } else {
                                     FaceVerify mFaceVerify = new FaceVerify();
                                     for (int i = 0; i < user_list.size(); i++) {

+ 3 - 6
app_modular/faceplatform-ui/src/main/java/com/baidu/idl/face/platform/ui/config/FaceConfig.java

@@ -1,9 +1,5 @@
-/*
- * Copyright (C) 2017 Baidu, Inc. All Rights Reserved.
- */
 package com.baidu.idl.face.platform.ui.config;
 
-
 import android.content.Context;
 import android.text.TextUtils;
 
@@ -33,10 +29,11 @@ public class FaceConfig {
 
     // 为了apiKey,secretKey为您调用百度人脸在线接口的,如注册,识别等。
     // 为了的安全,建议放在您的服务端,端把人脸传给服务器,在服务端端进行人脸注册、识别放在示例里面是为了您快速看到效果
-    public static String apiKey = "8B4k81ViOG3XWAoG4dDgSB2I";
-    public static String secretKey = "hryH0Lhmmt0yvGSXTveTwcMIRCA7rfIK";
+    public static String apiKey ="8B4k81ViOG3XWAoG4dDgSB2I";
+    public static String secretKey ="hryH0Lhmmt0yvGSXTveTwcMIRCA7rfIK";
     public static String licenseID = "UUFaceID-face-android";
     public static String licenseFileName = "idl-license.face-android";
+
     public static String accessToken;
 
     public static void initFace(Context context) {

+ 3 - 3
app_modular/faceplatform-ui/src/main/java/com/baidu/idl/face/platform/ui/utils/BrightnessTools.java

@@ -40,7 +40,7 @@ public class BrightnessTools {
         int nowBrightnessValue = 0;
         ContentResolver resolver = activity.getContentResolver();
         try {
-            nowBrightnessValue = Settings.System.getInt(
+            nowBrightnessValue = android.provider.Settings.System.getInt(
                     resolver, Settings.System.SCREEN_BRIGHTNESS);
         } catch (Exception e) {
             e.printStackTrace();
@@ -112,10 +112,10 @@ public class BrightnessTools {
      * @param brightness
      */
     public static void saveBrightness(ContentResolver resolver, int brightness) {
-        Uri uri = Settings.System
+        Uri uri = android.provider.Settings.System
                 .getUriFor("screen_brightness");
 
-        Settings.System.putInt(resolver, "screen_brightness",
+        android.provider.Settings.System.putInt(resolver, "screen_brightness",
                 brightness);
         // resolver.registerContentObserver(uri, true, myContentObserver);
         resolver.notifyChange(uri, null);

+ 2 - 2
app_modular/faceplatform-ui/src/main/java/com/baidu/idl/face/platform/ui/utils/CameraUtils.java

@@ -1,5 +1,5 @@
-/**
- * Copyright (C) 2017 Baidu Inc. All rights reserved.
+/*
+ * Copyright (C) 2017 Baidu, Inc. All Rights Reserved.
  */
 package com.baidu.idl.face.platform.ui.utils;
 

+ 2 - 2
app_modular/faceplatform-ui/src/main/java/com/baidu/idl/face/platform/ui/utils/VolumeUtils.java

@@ -1,5 +1,5 @@
-/**
- * Copyright (C) 2017 Baidu Inc. All rights reserved.
+/*
+ * Copyright (C) 2017 Baidu, Inc. All Rights Reserved.
  */
 package com.baidu.idl.face.platform.ui.utils;
 

+ 24 - 10
app_modular/faceplatform-ui/src/main/java/com/baidu/idl/face/platform/ui/widget/FaceDetectRoundView.java → app_modular/faceplatform-ui/src/main/java/com/baidu/idl/face/platform/ui/widget/FaceRoundView.java

@@ -1,7 +1,8 @@
-/**
- * Copyright (C) 2017 Baidu Inc. All rights reserved.
- */
 package com.baidu.idl.face.platform.ui.widget;
+/*
+ * Copyright (C) 2017 Baidu, Inc. All Rights Reserved.
+ */
+
 
 import android.content.Context;
 import android.graphics.Canvas;
@@ -22,9 +23,9 @@ import com.baidu.idl.face.platform.utils.DensityUtils;
 /**
  * 人脸检测区域View
  */
-public class FaceDetectRoundView extends View {
+public class FaceRoundView extends View {
 
-    private static final String TAG = FaceDetectRoundView.class.getSimpleName();
+    private static final String TAG = "FaceRoundView";
 
     public static final float SURFACE_HEIGHT = 1000f;
     public static final float SURFACE_RATIO = 0.75f;
@@ -36,7 +37,10 @@ public class FaceDetectRoundView extends View {
     public static final int PATH_SMALL_SPACE = 12;
     public static final int PATH_WIDTH = 4;
 
-    public static final int COLOR_BG = Color.parseColor("#2F2F33");
+    //  public static final int COLOR_BG = Color.parseColor("#2F2F33");
+    //  public static final int COLOR_RECT = Color.parseColor("#FFFFFF");
+    //  public static final int COLOR_ROUND = Color.parseColor("#FFA800");
+    public static final int COLOR_BG = Color.parseColor("#FFFFFF");
     public static final int COLOR_RECT = Color.parseColor("#FFFFFF");
     public static final int COLOR_ROUND = Color.parseColor("#FFA800");
 
@@ -54,7 +58,7 @@ public class FaceDetectRoundView extends View {
     private float mR;
     private boolean mIsDrawDash = true;
 
-    public FaceDetectRoundView(Context context, AttributeSet attrs) {
+    public FaceRoundView(Context context, AttributeSet attrs) {
         super(context, attrs);
 
         setLayerType(View.LAYER_TYPE_SOFTWARE, null);
@@ -116,9 +120,19 @@ public class FaceDetectRoundView extends View {
         float canvasWidth = right - left;
         float canvasHeight = bottom - top;
 
-        float x = canvasWidth / 2;
-        float y = (canvasHeight / 2) - ((canvasHeight / 2) * HEIGHT_RATIO);
-        float r = (canvasWidth / 2) - ((canvasWidth / 2) * WIDTH_SPACE_RATIO);
+        float x = 0;
+        float y = 0;
+        float r = 0;
+        if (canvasWidth < canvasHeight) {
+            x = canvasWidth / 2;
+            y = (canvasHeight / 2) - ((canvasHeight / 2) * HEIGHT_RATIO);
+            r = (canvasWidth / 2) - ((canvasWidth / 2) * WIDTH_SPACE_RATIO);
+        } else {
+            x = canvasWidth / 2;
+            y = canvasHeight / 2;
+            r = (canvasHeight / 2) - ((canvasHeight / 2) * WIDTH_SPACE_RATIO);
+        }
+
 
         if (mFaceRect == null) {
             mFaceRect = new Rect((int) (x - r),

+ 2 - 3
app_modular/faceplatform-ui/src/main/res/layout/activity_face_detect_v3100.xml

@@ -8,7 +8,7 @@
     <FrameLayout
         android:id="@+id/detect_surface_layout"
         android:layout_width="match_parent"
-        android:layout_height="match_parent"/>
+        android:layout_height="match_parent"></FrameLayout>
 
     <com.baidu.idl.face.platform.ui.widget.FaceDetectRoundView
         android:id="@+id/detect_face_round"
@@ -64,7 +64,6 @@
         android:layout_width="wrap_content"
         android:layout_height="wrap_content"
         android:layout_margin="20dp"
-        android:visibility="gone"
         android:src="@mipmap/ic_close_ext" />
 
     <ImageView
@@ -72,7 +71,7 @@
         android:layout_width="wrap_content"
         android:layout_height="wrap_content"
         android:layout_alignParentRight="true"
-        android:layout_margin="@dimen/padding"
+        android:layout_margin="20dp"
         android:src="@mipmap/ic_enable_sound_ext" />
 
     <ImageView

+ 57 - 0
app_modular/faceplatform-ui/src/main/res/layout/activity_login_detected.xml

@@ -0,0 +1,57 @@
+<?xml version="1.0" encoding="utf-8"?><!--
+  ~ Copyright (C) 2017 Baidu, Inc. All Rights Reserved.
+  -->
+<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
+    android:id="@+id/root_view"
+    android:layout_width="match_parent"
+    android:layout_height="match_parent">
+
+    <RelativeLayout
+        android:layout_width="match_parent"
+        android:layout_height="match_parent"
+        android:layout_margin="50dp">
+
+        <com.baidu.aip.face.TexturePreviewView
+            android:id="@+id/preview_view"
+            android:layout_width="match_parent"
+            android:layout_height="match_parent" />
+    </RelativeLayout>
+
+
+
+    <FrameLayout
+        android:id="@+id/camera_layout"
+        android:layout_width="match_parent"
+        android:layout_height="match_parent"
+        android:background="#ffffff" />
+
+    <com.baidu.idl.face.platform.ui.widget.FaceRoundView
+        android:id="@+id/rect_view"
+        android:layout_width="match_parent"
+        android:layout_height="match_parent" />
+
+    <TextView
+        android:id="@+id/name_text_view"
+        android:layout_width="wrap_content"
+        android:layout_height="wrap_content"
+        android:layout_centerHorizontal="true"
+        android:layout_marginTop="50dp"
+        android:textColor="@android:color/holo_orange_light"
+        android:textSize="24sp" />
+
+    <ImageView
+        android:id="@+id/closeIv"
+        android:layout_width="wrap_content"
+        android:layout_height="wrap_content"
+        android:layout_margin="20dp"
+        android:src="@mipmap/ic_close" />
+
+    <ImageView
+        android:id="@+id/success_image"
+        android:layout_width="45dp"
+        android:layout_height="45dp"
+        android:src="@mipmap/ic_success"
+        android:visibility="gone" />
+
+
+</RelativeLayout>

+ 11 - 0
app_modular/faceplatform-ui/src/main/res/values/dimens.xml

@@ -0,0 +1,11 @@
+<!--
+  ~ Copyright (C) 2017 Baidu, Inc. All Rights Reserved.
+  -->
+<resources>
+    <!-- Default screen margins, per the Android Design guidelines. -->
+    <dimen name="success_width">45dp</dimen>
+    <dimen name="detect_out">2dp</dimen>
+    <dimen name="preview_margin">50dp</dimen>
+    <dimen name="preview_land_margin">20dp</dimen>
+    <dimen name="head_width">200dp</dimen>
+</resources>

+ 12 - 6
app_modular/faceplatform-ui/src/main/res/values/strings.xml

@@ -1,16 +1,22 @@
 <resources>
-    <string name="app_name">Baidu-IDL-FaceSDK</string>
     <string name="detect_no_face">未检测到人脸</string>
     <string name="detect_face_in">把脸移入框内</string>
     <string name="detect_zoom_in">手机拿近一点</string>
     <string name="detect_zoom_out">手机拿远一点</string>
-    <string name="detect_head_up">建议略微抬头</string>
-    <string name="detect_head_down">建议略微低头</string>
-    <string name="detect_head_left">建议略微向左转头</string>
-    <string name="detect_head_right">建议略微向右转头</string>
+    <string name="detect_head_up">头抬高些</string>
+    <string name="detect_head_down">头放低些</string>
+    <string name="detect_head_left">向左调整下头部角度</string>
+    <string name="detect_head_right">向右调整下头部角度</string>
     <string name="detect_occ_face">脸部有遮挡</string>
+    <string name="detect_occ_left_eye">左眼有遮挡</string>
+    <string name="detect_occ_right_eye">右眼有遮挡</string>
+    <string name="detect_occ_nose">鼻子有遮挡</string>
+    <string name="detect_occ_mouth">嘴部有遮挡</string>
+    <string name="detect_left_contour">左脸颊有遮挡</string>
+    <string name="detect_right_contour">右脸颊有遮挡</string>
+    <string name="detect_chin_contour">下巴有遮挡</string>
     <string name="detect_low_light">光线再亮些</string>
-    <string name="detect_keep">请保持不动</string>
+    <string name="detect_keep">请握稳手机,视线平视手机</string>
     <string name="detect_standard">请正对手机</string>
     <string name="detect_timeout">检测超时</string>
     <string name="liveness_eye">眨眨眼</string>

+ 2 - 2
settings.gradle

@@ -19,7 +19,7 @@ include ':apptasks'
 include ':apputils'
 include  ':appmusic'
 include  ':faceplatform-ui'
-include  ':faceplatform-release'
+//include  ':faceplatform-release'
 //第三库模块
 
 include ':lib-zxing'
@@ -53,7 +53,7 @@ project(':apptasks').projectDir = new File('app_modular/apptasks')
 project(':apputils').projectDir = new File('app_modular/apputils')
 project(':appmusic').projectDir = new File('app_modular/appmusic')
 project(':faceplatform-ui').projectDir = new File('app_modular/faceplatform-ui')
-project(':faceplatform-release').projectDir = new File('app_modular/faceplatform-release')
+//project(':faceplatform-release').projectDir = new File('app_modular/faceplatform-release')
 //第三库模块
 
 project(':lib-zxing').projectDir = new File('app_third/lib-zxing')