Browse Source

车牌识别

ifengouy 1 year ago
parent
commit
9c9a08deb3

+ 699 - 0
app/src/main/java/com/sunwin/visitorapp/baidu/BDActivity.java

@@ -0,0 +1,699 @@
+package com.sunwin.visitorapp.baidu;
+
+import android.Manifest;
+import android.app.Activity;
+import android.content.Intent;
+import android.content.pm.PackageManager;
+import android.database.Cursor;
+import android.graphics.Bitmap;
+import android.graphics.BitmapFactory;
+import android.graphics.Matrix;
+import android.graphics.Rect;
+import android.graphics.drawable.BitmapDrawable;
+import android.media.ExifInterface;
+import android.net.Uri;
+import android.os.Bundle;
+import android.provider.MediaStore;
+import android.view.View;
+import android.widget.ImageView;
+import android.widget.Toast;
+
+import androidx.annotation.NonNull;
+import androidx.annotation.Nullable;
+import androidx.core.app.ActivityCompat;
+import androidx.core.content.ContextCompat;
+
+import com.baidu.ai.cameraui.camera.CameraListener;
+import com.baidu.ai.cameraui.parameter.BaseParameter;
+import com.baidu.ai.cameraui.util.AutoTrigger;
+import com.baidu.ai.cameraui.util.CrashReporterHandler;
+import com.baidu.ai.cameraui.util.ImageUtil;
+import com.baidu.ai.cameraui.util.UiLog;
+import com.baidu.ai.cameraui.view.CropView;
+import com.baidu.ai.cameraui.view.MaskView;
+import com.baidu.ai.cameraui.view.PreviewView;
+import com.sunwin.visitorapp.BaseActivity;
+import com.sunwin.visitorapp.R;
+
+import java.io.File;
+import java.io.FileOutputStream;
+import java.io.IOException;
+
+import static com.baidu.ai.cameraui.parameter.BaseParameter.KEY_HAS_ALBUM_BUTTON;
+import static com.baidu.ai.cameraui.parameter.BaseParameter.KEY_HAS_FLASH_BUTTON;
+import static com.baidu.ai.cameraui.parameter.BaseParameter.KEY_MAIN;
+import static com.baidu.ai.cameraui.parameter.BaseParameter.KEY_MASK_TYPE;
+import static com.baidu.ai.cameraui.parameter.BaseParameter.KEY_OUTPUT_FILE_PATH;
+import static com.baidu.ai.cameraui.parameter.BaseParameter.KEY_TAKE_PICTURE_TYPE;
+import static com.baidu.ai.cameraui.parameter.BaseParameter.TYPE_MANUAL;
+
+abstract class BDActivity<T extends BaseParameter> extends BaseActivity {
+    static final int REQUEST_PERMISSION_CODE_CAMERA = 1;
+    static final int REQUEST_PERMISSION_CODE_STORAGE = 2;
+
+    static final int INTENT_CODE_PICK_IMAGE = 1;
+
+    private volatile boolean statusPreview = true;
+
+    private PreviewView mPreviewView;
+    private ImageView previewSnapshot;
+
+    private MaskView mMaskView;
+    private CropView mCropView;
+
+    private ImageView takePictureBtn;
+    private ImageView flashBtn;
+    private ImageView albumBtn;
+
+    private ImageView rotatePictureBtn;
+    private ImageView cancelBtn;
+    private ImageView confirmBtn;
+
+    private boolean isFlashOpen = false;
+
+    private boolean isAuto;
+
+    private boolean isToAlbumActivity = false;
+
+    protected T parameter;
+
+    protected abstract void onPictureProcess(Bitmap bitmap, @Nullable Bitmap origin, boolean isTriggerManual);
+
+    protected abstract void onDispatchCreate(@Nullable Bundle savedInstanceState);
+
+    protected void setParameter(T param) {
+        parameter = param;
+    }
+
+    protected T getParameter() {
+        return parameter;
+    }
+
+    /**
+     * 保存图片,供activity之间参数传递
+     * @param bitmap
+     */
+    protected void saveOutputFile(Bitmap bitmap) {
+        File file = new File(parameter.getResultImagePath());
+        try {
+            if (!file.exists()) {
+                file.createNewFile();
+            }
+            FileOutputStream fileOutputStream = new FileOutputStream(file);
+            boolean isSuccess = bitmap.compress(Bitmap.CompressFormat.JPEG, 100, fileOutputStream);
+            if (!isSuccess) {
+                UiLog.error("bitmap save output fail");
+            }
+            fileOutputStream.flush();
+            fileOutputStream.close();
+        } catch (IOException e) {
+            UiLog.error("bitmap save output exception" , e);
+            e.printStackTrace();
+        }
+    }
+
+    @Override
+    protected void onCreate(@Nullable Bundle savedInstanceState) {
+        super.onCreate(savedInstanceState);
+        CrashReporterHandler.init(this);
+        Bundle bundle = getIntent().getBundleExtra(KEY_MAIN);
+        onDispatchCreate(savedInstanceState);
+        if (parameter == null) {
+            parameter = (T) new BaseParameter();
+        }
+        if (bundle != null) {
+            parameter.setFlashShow(bundle.getBoolean(KEY_HAS_FLASH_BUTTON, true));
+            parameter.setAlbumShow(bundle.getBoolean(KEY_HAS_ALBUM_BUTTON, true));
+            parameter.setType(bundle.getInt(KEY_TAKE_PICTURE_TYPE, BaseParameter.TYPE_AUTO));
+            parameter.setMaskType(bundle.getInt(KEY_MASK_TYPE));
+            parameter.setResultImagePath(bundle.getString(KEY_OUTPUT_FILE_PATH, ""));
+        }
+        if (parameter.getType() == BaseParameter.TYPE_AUTO) {
+            isAuto = true;
+        }
+
+        requestPermissionCamera();
+    }
+
+    private void init() {
+        setContentView(R.layout.camera_view);
+
+        mPreviewView = (PreviewView) findViewById(R.id.preview_view);
+
+        // 预览按钮
+        takePictureBtn = findViewById(R.id.take_picture_btn);
+        initOptionBtns();
+
+        // 操作按钮
+        rotatePictureBtn = findViewById(R.id.rotate_picture_btn);
+        cancelBtn = findViewById(R.id.cancel_btn);
+        confirmBtn = findViewById(R.id.confirm_btn);
+        toggleActionBtns(false);
+
+        previewSnapshot = (ImageView) findViewById(R.id.preview_snapshot);
+        mMaskView = (MaskView) findViewById(R.id.maskview);
+        mCropView = (CropView) findViewById(R.id.cropview);
+        mCropView.setVisibility(View.GONE);
+
+        if (!isAuto) {
+            takePictureBtn.setOnClickListener(new View.OnClickListener() {
+                @Override
+                public void onClick(View v) {
+                    mPreviewView.takePicture(new CameraListener.TakePictureListener() {
+                        @Override
+                        public void onTakenPicture(Bitmap bitmap) {
+                            pictureTaken(bitmap);
+                        }
+                    });
+                }
+            });
+            takePictureBtn.setVisibility(View.VISIBLE);
+        } else {
+            takePictureBtn.setVisibility(View.GONE);
+        }
+
+
+        rotatePictureBtn.setOnClickListener(new View.OnClickListener() {
+            @Override
+            public void onClick(View v) {
+                rotatePicture();
+            }
+        });
+
+        cancelBtn.setOnClickListener(new View.OnClickListener() {
+            @Override
+            public void onClick(View v) {
+                returnToPreview();
+            }
+        });
+
+        confirmBtn.setOnClickListener(new View.OnClickListener() {
+            @Override
+            public void onClick(View v) {
+                Bitmap origin =   ((BitmapDrawable) previewSnapshot.getDrawable()).getBitmap();
+                Bitmap bitmap = doCropBitmap(origin);
+                onPictureProcess(bitmap, origin, true);
+            }
+        });
+
+        switch (parameter.getMaskType()) {
+            case BaseParameter.MASK_TYPE_BANKCARD:
+                mMaskView.setMaskType(MaskView.MASK_TYPE_BANKCARD);
+                mMaskView.setTipString(parameter.getDefaultTip());
+                break;
+            case BaseParameter.MASK_TYPE_IDCARD_FRONT:
+                mMaskView.setMaskType(MaskView.MASK_TYPE_IDCARD_FRONT);
+                mMaskView.setTipString(parameter.getDefaultTip());
+                break;
+            case BaseParameter.MASK_TYPE_IDCARD_BACK:
+                mMaskView.setMaskType(MaskView.MASK_TYPE_IDCARD_BACK);
+                mMaskView.setTipString(parameter.getDefaultTip());
+                break;
+            default:
+                mMaskView.setMaskType(MaskView.MASK_NONE);
+        }
+
+        if (isAuto) {
+            createAutoTakeTimer();
+        }
+    }
+
+    public void setTipString(final String tip) {
+        runOnUiThread(new Runnable() {
+            @Override
+            public void run() {
+                mMaskView.setTipStringAndUpdate(tip);
+            }
+        });
+
+    }
+
+
+    /**
+     * 开启自动拍照
+     */
+    private void createAutoTakeTimer() {
+        if (getParameter().getType() == BaseParameter.TYPE_AUTO) {
+            AutoTrigger.createAutoTakeTimerTask(new Runnable() {
+                @Override
+                public void run() {
+                    synchronized (this) {
+                        if (statusPreview) {
+                            mPreviewView.takePicture(new CameraListener.TakePictureListener() {
+                                @Override
+                                public void onTakenPicture(Bitmap bitmap) {
+                                    pictureTakenAndCrop(bitmap);
+                                }
+                            });
+                        }
+                    }
+                }
+            });
+        }
+    }
+
+    /**
+     * 关闭自动拍照
+     */
+    private void cancelAutoTakeTimer() {
+        if (getParameter().getType() == BaseParameter.TYPE_AUTO) {
+            AutoTrigger.cancelAutoTakeTimer();
+        }
+    }
+
+    /**
+     * 根据参数选择性展示按钮
+     */
+    private void initOptionBtns() {
+
+        albumBtn = findViewById(R.id.album_btn);
+        flashBtn = findViewById(R.id.flash_btn);
+
+        if (parameter.isFlashShow()) {
+            flashBtn.setVisibility(View.VISIBLE);
+            flashBtn.setOnClickListener(new View.OnClickListener() {
+                @Override
+                public void onClick(View v) {
+                    isFlashOpen = !isFlashOpen;
+                    refreshFlash();
+                }
+            });
+        } else {
+            flashBtn.setVisibility(View.GONE);
+        }
+
+        if (parameter.isAlbumShow()) {
+            albumBtn.setVisibility(View.VISIBLE);
+            albumBtn.setOnClickListener(new View.OnClickListener() {
+                @Override
+                public void onClick(View v) {
+                    requestPermissionAlbum();
+                }
+            });
+        } else {
+            albumBtn.setVisibility(View.GONE);
+        }
+    }
+
+
+    /**
+     * 裁剪图片
+     * @param bitmap
+     * @return
+     */
+    private Bitmap doCropBitmap(Bitmap bitmap) {
+        Rect crop = mCropView.getCropRect();
+        Matrix matrix = previewSnapshot.getImageMatrix();
+        Matrix inverted = new Matrix();
+        matrix.invert(inverted);
+        float[] pts = {crop.left, crop.top, crop.right, crop.bottom};
+        inverted.mapPoints(pts);
+        float x = pts[0] < 0 ? 0 : pts[0];
+        float y = pts[1] < 0 ? 0 : pts[1];
+        float width = pts[2] - pts[0] > bitmap.getWidth() ? bitmap.getWidth() : pts[2] - pts[0];
+        float height = pts[3] - pts[1] > bitmap.getHeight() ? bitmap.getHeight() : pts[3] - pts[1];
+        Bitmap bt = ImageUtil.createCropBitmap(bitmap, x,
+                y , width, height, new Matrix());
+        return bt;
+    }
+
+    /**
+     * 裁剪图片
+     * 不通过ImageView
+     *
+     * @param bitmap
+     * @return
+     */
+    private Bitmap doCropBitmapAutoPicture(Bitmap bitmap) {
+        Rect crop = mCropView.getCropRect();
+        float ratio = (float) previewSnapshot.getWidth() / bitmap.getWidth();
+        Matrix matrix = new Matrix();
+        matrix.postScale(ratio, ratio);
+        matrix.invert(matrix);
+        float[] pts = {crop.left, crop.top, crop.right, crop.bottom};
+        matrix.mapPoints(pts);
+        Bitmap bt = ImageUtil.createCropBitmap(bitmap, pts[0],
+                pts[1] , pts[2] - pts[0], pts[3] - pts[1], matrix);
+        return bt;
+    }
+
+    /**
+     * 动态申请相册权限
+     * 成功后打开相册
+     */
+    private void requestPermissionAlbum() {
+        // 判断是否已经赋予权限
+        if (ContextCompat.checkSelfPermission(this,
+                Manifest.permission.WRITE_EXTERNAL_STORAGE)
+                != PackageManager.PERMISSION_GRANTED) {
+            // 如果应用之前请求过此权限但用户拒绝了请求,此方法将返回 true。
+            ActivityCompat.requestPermissions(this,
+                    new String[]{Manifest.permission.WRITE_EXTERNAL_STORAGE}, REQUEST_PERMISSION_CODE_STORAGE);
+        } else {
+            openAlum();
+        }
+    }
+
+    /**
+     * 打开相册选图
+     */
+    private void openAlum() {
+        Intent intent = new Intent(Intent.ACTION_PICK);
+        isToAlbumActivity = true;
+        intent.setType("image/*");
+        startActivityForResult(intent, INTENT_CODE_PICK_IMAGE);
+    }
+
+    private String getRealPathFromURI(Uri contentURI) {
+        String result;
+        Cursor cursor = null;
+        try {
+            cursor = getContentResolver().query(contentURI, null, null, null, null);
+        } catch (Throwable e) {
+            e.printStackTrace();
+        }
+        if (cursor == null) {
+            result = contentURI.getPath();
+        } else {
+            cursor.moveToFirst();
+            int idx = cursor.getColumnIndex(MediaStore.Images.ImageColumns.DATA);
+            result = cursor.getString(idx);
+            cursor.close();
+        }
+        return result;
+    }
+
+    /**
+     * 从相册读取图片
+     * @param path
+     * @return
+     */
+    private Bitmap readFile(String path) {
+        BitmapFactory.Options option = new BitmapFactory.Options();
+
+        BitmapFactory.decodeFile(path, option);
+        option.inJustDecodeBounds = true;
+        if (option.outWidth > 1080 || option.outHeight > 1920) {
+            option.inSampleSize = 2;
+        }
+        option.inJustDecodeBounds = false;
+        Bitmap bitmap = BitmapFactory.decodeFile(path, option);
+        UiLog.info("pick image success");
+        return bitmap;
+    }
+
+    @Override
+    protected void onActivityResult(int requestCode, int resultCode, Intent data) {
+        super.onActivityResult(requestCode, resultCode, data);
+        if (requestCode == INTENT_CODE_PICK_IMAGE) {
+            if (resultCode == Activity.RESULT_OK) {
+                Uri uri = data.getData();
+                String path = getRealPathFromURI(uri);
+                UiLog.info("pick image url: " + path);
+                Bitmap bitmap = readFile(path);
+                ExifInterface exif = null;
+                int exifRotation = 0;
+                try {
+                    exif = new ExifInterface(path);
+                    exifRotation = exif.getAttributeInt(ExifInterface.TAG_ORIENTATION,
+                            ExifInterface.ORIENTATION_NORMAL);
+                } catch (IOException e) {
+                    UiLog.error("album selection picture get exif info error", e);
+                }
+
+                int rotation = ImageUtil.exifToDegrees(exifRotation);
+                Bitmap rotateBitmap = ImageUtil.createRotateBitmap(bitmap, rotation);
+                pictureFromAlbum(rotateBitmap);
+            } else {
+                // 取消的时候退出到的是预览界面
+                isToAlbumActivity = false;
+            }
+        }
+    }
+
+    private void refreshFlash() {
+        if (mPreviewView.isCameraOpened()) {
+            mPreviewView.getCameraControl().toggleFlash(isFlashOpen);
+            if (isFlashOpen) {
+                flashBtn.setImageResource(R.drawable.flash_on_btn);
+            } else {
+                flashBtn.setImageResource(R.drawable.flash_off_btn);
+            }
+        }
+    }
+
+    private int previewRotation = 0;
+
+    /**
+     * 旋转预览
+     */
+    private void rotatePicture() {
+        previewRotation -= 90;
+        Bitmap rotateBitmap = ImageUtil.createRotateBitmap(snapShotBitmap, previewRotation);
+        previewSnapshot.setImageBitmap(rotateBitmap);
+        setCropBound();
+    }
+
+    /**
+     * 设置边界
+     */
+    private void setCropBound() {
+        Matrix matrix = previewSnapshot.getImageMatrix();
+        float[] pts;
+        if (previewRotation % 180 != 0) {
+            pts = new float[]{0, 0, snapShotBitmap.getHeight(), snapShotBitmap.getWidth()};
+            matrix.mapPoints(pts);
+
+        } else {
+            pts = new float[]{0, 0, snapShotBitmap.getWidth(), snapShotBitmap.getHeight()};
+            matrix.mapPoints(pts);
+        }
+        mCropView.setBound((int) pts[0], (int) pts[1], (int) pts[2], (int) pts[3]);
+    }
+
+    private Bitmap snapShotBitmap;
+
+    /**
+     * 切换预览界面的按钮展示与否
+     * @param isShow
+     */
+    private void togglePreviewBtns(boolean isShow) {
+        int flag = isShow ? View.VISIBLE : View.GONE;
+        takePictureBtn.setVisibility(flag);
+        if (parameter.isFlashShow()) {
+            flashBtn.setVisibility(flag);
+        } else {
+            flashBtn.setVisibility(View.GONE);
+        }
+        if (parameter.isAlbumShow()) {
+            albumBtn.setVisibility(flag);
+        } else {
+            albumBtn.setVisibility(View.GONE);
+        }
+    }
+
+    /**
+     * 切换操作界面的按钮展示与否
+     * @param isShow
+     */
+    private void toggleActionBtns(boolean isShow) {
+        int flag = isShow ? View.VISIBLE : View.GONE;
+        rotatePictureBtn.setVisibility(flag);
+        confirmBtn.setVisibility(flag);
+        cancelBtn.setVisibility(flag);
+        confirmBtn.setVisibility(View.VISIBLE);
+    }
+
+    /**
+     * 点击拍照按钮,或者选择相册图片
+     * @param bitmap
+     */
+    private void pictureTaken(final Bitmap bitmap) {
+        snapShotBitmap = bitmap;
+        UiLog.info("takePictureSuccess");
+        runOnUiThread(new Runnable() {
+            @Override
+            public void run() {
+                previewSnapshot.setImageBitmap(bitmap);
+                changeToAction(false);
+                setCropBound();
+            }
+        });
+    }
+
+    private void pictureFromAlbum(final Bitmap bitmap) {
+        snapShotBitmap = bitmap;
+        UiLog.info("albumSelectPictureSuccess");
+        runOnUiThread(new Runnable() {
+            @Override
+            public void run() {
+                previewSnapshot.setImageBitmap(bitmap);
+                changeToAction(true);
+                setCropBound();
+            }
+        });
+    }
+
+    /**
+     * 自动拍照后裁剪
+     * @param bitmap
+     */
+    private void pictureTakenAndCrop(final Bitmap bitmap) {
+        UiLog.info("autoTakePictureSuccess");
+        if (mCropView.getCropRect() == null) {
+            mCropView.setCropRect(mMaskView.getMaskFrame());
+        }
+        Bitmap cropBitmap = doCropBitmapAutoPicture(bitmap);
+        onPictureProcess(cropBitmap, bitmap, false);
+    }
+
+    /**
+     * 旋转图片
+     */
+    private void changeToAction(boolean isFromAlbum) {
+        togglePreviewBtns(false);
+        toggleActionBtns(true);
+        mCropView.setVisibility(View.VISIBLE);
+        mMaskView.setVisibility(View.GONE);
+        mCropView.setCropRect(mMaskView.getMaskFrame());
+        previewSnapshot.setVisibility(View.VISIBLE);
+
+        mPreviewView.setVisibility(View.GONE);
+
+        isFlashOpen = false;
+        if (!isFromAlbum) {
+            mPreviewView.stopPreview();
+            refreshFlash();
+        }
+
+        statusPreview = false;
+
+    }
+
+    /**
+     * 从裁剪图片页面返回预览页面
+     */
+    private void returnToPreview() {
+        previewRotation = 0;
+        if (getParameter().getType() == TYPE_MANUAL) {
+            togglePreviewBtns(true);
+        }
+        toggleActionBtns(false);
+        mCropView.setVisibility(View.GONE);
+        mMaskView.setVisibility(View.VISIBLE);
+        previewSnapshot.setVisibility(View.GONE);
+        mPreviewView.getCameraControl().startPreviewForce();
+        mPreviewView.setVisibility(View.VISIBLE);
+        statusPreview = true;
+        if (isAuto) {
+            createAutoTakeTimer();
+        }
+    }
+
+    /**
+     * 请求相机权限
+     */
+    private void requestPermissionCamera() {
+        // 判断是否已经赋予权限
+        if (ContextCompat.checkSelfPermission(this,
+                Manifest.permission.CAMERA)
+                != PackageManager.PERMISSION_GRANTED) {
+            // 如果应用之前请求过此权限但用户拒绝了请求,此方法将返回 true。
+            ActivityCompat.requestPermissions(this,
+                    new String[]{Manifest.permission.CAMERA}, REQUEST_PERMISSION_CODE_CAMERA);
+        } else {
+            init();
+        }
+    }
+
+    /**
+     * 监听Back键按下事件,方法1:
+     * 注意:
+     * super.onBackPressed()会自动调用finish()方法,关闭
+     * 当前Activity.
+     * 若要屏蔽Back键盘,注释该行代码即可
+     */
+    @Override
+    public void onBackPressed() {
+        if (statusPreview) {
+            super.onBackPressed();
+        } else {
+            returnToPreview();
+        }
+
+    }
+
+    @Override
+    protected void onStop() {
+        super.onStop();
+        statusPreview = false;
+    }
+
+    @Override
+    protected void onPause() {
+
+        // 如果首次弹出权限框会导致暂时退出再返回
+        // 还有一种情况是手机助手类实现动态权限错误,导致相机未打开
+        // 此时不是真正的退出,无需做出反应
+        if (mPreviewView != null && mPreviewView.isCameraOpened()) {
+            // 关闭闪光灯
+            isFlashOpen = false;
+            refreshFlash();
+
+            cancelAutoTakeTimer();
+
+            // 停止mPreviewView预览
+            mPreviewView.getCameraControl().closeCamera();
+
+        }
+
+        UiLog.info("activity pause");
+        super.onPause();
+    }
+
+    @Override
+    protected void onResume() {
+
+        // 如果不是第一次启动就需要重新打开预览
+        if (mPreviewView != null && mPreviewView.getCameraControl() != null) {
+            UiLog.info("activity resume");
+            if (isAuto && !isToAlbumActivity) {
+                createAutoTakeTimer();
+            }
+            isToAlbumActivity = false;
+
+            mPreviewView.getCameraControl().startPreview();
+            statusPreview = true;
+
+        }
+        super.onResume();
+    }
+
+    @Override
+    public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions,
+                                           @NonNull int[] grantResults) {
+        super.onRequestPermissionsResult(requestCode, permissions, grantResults);
+        switch (requestCode) {
+            case REQUEST_PERMISSION_CODE_CAMERA:
+                if (grantResults[0] == -1) {
+                    Toast toast = Toast.makeText(this, "请选择权限", Toast.LENGTH_SHORT);
+                    toast.show();
+                    finish();
+                } else {
+                    init();
+                }
+                break;
+            case REQUEST_PERMISSION_CODE_STORAGE:
+                if (grantResults[0] == -1) {
+                    Toast toast = Toast.makeText(this, "请选择权限", Toast.LENGTH_SHORT);
+                    toast.show();
+                } else {
+                    openAlum();
+                }
+                break;
+            default:
+                break;
+        }
+
+    }
+}

+ 258 - 0
app/src/main/java/com/sunwin/visitorapp/baidu/IDCardReadActivity.java

@@ -0,0 +1,258 @@
+package com.sunwin.visitorapp.baidu;
+
+import android.content.Intent;
+import android.graphics.Bitmap;
+import android.os.Bundle;
+import android.util.Log;
+
+import androidx.annotation.Nullable;
+
+import com.baidu.ai.cameraui.parameter.BaseParameter;
+import com.baidu.vis.general.IdcardModel;
+import com.baidu.vis.general.Predictor;
+import com.baidu.vis.general.SDKExceptions;
+import com.baidu.vis.unified.license.AndroidLicenser;
+import com.baidu.vis.unified.license.BDLicenseActivator;
+import com.baidu.vis.unified.license.BDLicenseLocalInfo;
+import com.sunwin.visitorapp.utils.LogUtil;
+
+
+public class IDCardReadActivity extends IDcardCardActivity {
+
+    static final String KEY_RESULT = "result_text";
+    private boolean hasInitedIDcard = false;
+
+    private boolean init() {
+        if (hasInitedIDcard) {
+            return true;
+        }
+        // 获取鉴权相关本地设备及应用相关信息
+        BDLicenseLocalInfo bdLicenseLocalInfo = AndroidLicenser.getInstance().authGetLocalInfo(this, Predictor.getAlgorithmId());
+        Log.d(TAG, "BDLicenseLocalInfo :" + bdLicenseLocalInfo.toString());
+
+        /*AndroidLicenser.ErrorCode ret = AndroidLicenser.getInstance().authFromFile(SampleIdentifyCardFullActivity.this,
+                "yuekun_android", "idl_license_ocr_idcard_full", true, Predictor.getAlgorithmId());
+
+        if (ret != AndroidLicenser.ErrorCode.SUCCESS) {
+            Log.e(TAG, "ErrorMsg :" + AndroidLicenser.getInstance().getErrorMsg(Predictor.getAlgorithmId()));
+            return false;
+        }*/
+
+        // 在线自动激活
+        int ret = BDLicenseActivator.initLicenseOnLine(this, "",
+                "", Predictor.getAlgorithmId());
+        if (ret != 0) {
+            Log.e(TAG, "init: init license : " + ret);
+            return false;
+        }
+        hasInitedIDcard = true;
+        return true;
+    }
+
+    int initIDCard() {
+        String model_path = "general_assert.bundle";
+        int modelInit = 0;
+        try {
+            modelInit = Predictor.getInstance().initModel(
+                    this, model_path, 0);
+        } catch (SDKExceptions.IlleagleLicense illeagleLicense) {
+            illeagleLicense.printStackTrace();
+            Log.e(TAG, "illeagleLicense");
+            return -1;
+        } catch (SDKExceptions.MissingModleFileInAssetFolder
+                missingModleFileInAssetFolder) {
+            missingModleFileInAssetFolder.printStackTrace();
+            Log.e(TAG, "missingModleFileInAssetFolder");
+            return -2;
+        }
+        Log.e(TAG, "onCreate: model init : " + modelInit);
+        return 0;
+    }
+
+    @Override
+    protected synchronized void onPictureProcess(
+            Bitmap bitmap/*裁剪后的图片*/,
+            Bitmap origin/*完整图片*/,
+            boolean isTriggerManual/*如果是相册选择,或者MANUAL模式返回true,用于在自动模式下判断选择相册*/) {
+
+        if (!hasInitedIDcard) {
+            return;
+        }
+
+        // 用于传递普通结果
+        Intent intent = new Intent();
+
+        int result = 0;
+
+        if (getParameter().getType() == BaseParameter.TYPE_MANUAL || isTriggerManual)  {
+            // 手动拍照模式
+            try {
+                result = com.baidu.vis.general.Predictor.getInstance().predict(bitmap);
+                if (result == 0) {
+                    return;
+                }
+                IdcardModel resp;
+                if (parameter.getMaskType() == BaseParameter.MASK_TYPE_IDCARD_FRONT) {
+                    resp = com.baidu.vis.general.Predictor.getInstance().idcardDetection(1);
+                } else {
+                    resp = com.baidu.vis.general.Predictor.getInstance().idcardDetection(0);
+                }
+
+                if (resp.nErrorCode != 0) {
+
+                    LogUtil.e(TAG, "身份证质量异常,错误码:" + resp.nErrorCode);
+                    return;
+                }
+                LogUtil.e(TAG, "id:" + resp.number + "name:" + resp.name);
+
+                // 用于传递图片到其他activity,文件路径由调用这个activity时传入的KEY_OUTPUT_FILE_PATH参数指定
+                super.saveOutputFile(bitmap);
+
+            } catch (SDKExceptions.IlleagleLicense illeagleLicense) {
+                LogUtil.e(TAG, "SDKExceptions.IlleagleLicense:" + illeagleLicense);
+
+            } catch (SDKExceptions.NotInit notInit) {
+                LogUtil.e(TAG, "SDKExceptions.NotInit:" + notInit);
+            }finally {
+                // 返回银行卡识别结果
+                setResult(RESULT_OK, intent);
+                finish();
+            }
+
+        }
+        if (getParameter().getType() == BaseParameter.TYPE_AUTO)  {
+            // 自动拍照模式
+            try {
+
+                result = com.baidu.vis.general.Predictor.getInstance().predict(bitmap);
+                if (result == 0) {
+                    return;
+                }
+
+                IdcardModel resp;
+                if (parameter.getMaskType() == BaseParameter.MASK_TYPE_IDCARD_FRONT) {
+                    resp = com.baidu.vis.general.Predictor.getInstance().idcardDetection(1);
+                } else {
+                    resp = com.baidu.vis.general.Predictor.getInstance().idcardDetection(0);
+                }
+                if (resp.nErrorCode != 0) {
+                    intent.putExtra(KEY_RESULT, "身份证质量异常,错误码:" + resp.nErrorCode);
+                } else if (resp.bFlag) {
+                    if (parameter.getMaskType() == BaseParameter.MASK_TYPE_IDCARD_FRONT) {
+                        intent.putExtra(KEY_RESULT, genFrontResult(resp));
+                    } else {
+                        intent.putExtra(KEY_RESULT, genBackResult(resp));
+                    }
+                    // 用于传递图片到其他activity,文件路径由调用这个activity时传入的KEY_OUTPUT_FILE_PATH参数指定
+                    super.saveOutputFile(origin);
+
+                    // 返回银行卡识别结果
+                    setResult(RESULT_OK, intent);
+                    finish();
+                }
+
+            } catch (SDKExceptions.IlleagleLicense illeagleLicense) {
+                LogUtil.e(TAG, "SDKExceptions.IlleagleLicense:" + illeagleLicense);
+
+            } catch (SDKExceptions.NotInit notInit) {
+                LogUtil.e(TAG, "SDKExceptions.NotInit:" + notInit);
+            }
+        }
+    }
+
+    @Override
+    protected void onDispatchCreate(@Nullable Bundle savedInstanceState) {
+        super.onDispatchCreate(savedInstanceState);
+    }
+
+    @Override
+    protected void onStart() {
+        super.onStart();
+
+    }
+
+    @Override
+    protected void onCreate(@Nullable Bundle savedInstanceState) {
+        super.onCreate(savedInstanceState);
+    }
+
+    @Override
+    protected void onStop() {
+        super.onStop();
+
+    }
+
+    static final String breaker = "\n";
+
+    private String genFrontResult(IdcardModel resp) {
+        StringBuffer sb = new StringBuffer();
+        sb.append("名字:" + resp.name + breaker);
+        sb.append("地址:" + resp.address+ breaker);
+        sb.append("生日:" + resp.birthday+ breaker);
+        sb.append("名族:" + resp.nation+ breaker);
+        sb.append("身份证号:" + resp.number+ breaker);
+        return sb.toString();
+    }
+
+    private String genBackResult(IdcardModel resp) {
+        StringBuffer sb = new StringBuffer();
+        sb.append("发证日期:" + resp.issue_date+ breaker);
+        sb.append("发证机关:" + resp.issue_office+ breaker);
+        sb.append("过期日期:" + resp.expire_date+ breaker);
+        return sb.toString();
+    }
+
+    String testOneImage(Bitmap bitmap, int type) {
+        String result = "";
+        int predict = 0;
+        try {
+            predict = com.baidu.vis.general.Predictor.getInstance().predict(bitmap);
+        } catch (SDKExceptions.IlleagleLicense illeagleLicense) {
+            illeagleLicense.printStackTrace();
+        } catch (SDKExceptions.NotInit notInit) {
+            notInit.printStackTrace();
+        }
+
+        if (predict == 0) {
+            Log.e(TAG, "GeneralDetection num : 0");
+            return result;
+        } else if (predict < 0) {
+            Log.e(TAG, "GeneralDetection error: " + predict);
+            return result;
+        }
+
+        com.baidu.vis.general.IdcardModel cardResult = null;
+        if (type  == 0) {
+            try {
+                cardResult = com.baidu.vis.general.Predictor.getInstance().
+                        idcardDetection(1);
+            } catch (SDKExceptions.IlleagleLicense illeagleLicense) {
+                illeagleLicense.printStackTrace();
+            } catch (SDKExceptions.NotInit notInit) {
+                notInit.printStackTrace();
+            }
+            Log.e(TAG, "cardResult.nErrorCode: " + cardResult.nErrorCode);
+
+            result = "住址\t" + cardResult.address + "\n" +
+                    "出生\t" + cardResult.birthday + "\n" +
+                    "姓名\t" + cardResult.name + "\n" +
+                    "公民身份号码\t" + cardResult.number + "\n" +
+                    "性别\t" + cardResult.sex + "\n" +
+                    "民族\t" + cardResult.nation;
+        } else {
+            try {
+                cardResult = com.baidu.vis.general.Predictor.getInstance().
+                        idcardDetection(0);
+            } catch (SDKExceptions.IlleagleLicense illeagleLicense) {
+                illeagleLicense.printStackTrace();
+            } catch (SDKExceptions.NotInit notInit) {
+                notInit.printStackTrace();
+            }
+            result = "签发机关\t" + cardResult.issue_office + "\n" +
+                    "签发日期\t" + cardResult.issue_date + "\n" +
+                    "失效日期\t" + cardResult.expire_date;
+        }
+
+        return result;
+    }
+}

+ 31 - 0
app/src/main/java/com/sunwin/visitorapp/baidu/IDcardCardActivity.java

@@ -0,0 +1,31 @@
+package com.sunwin.visitorapp.baidu;
+
+import android.os.Bundle;
+
+import androidx.annotation.Nullable;
+
+import com.baidu.ai.cameraui.parameter.IDcardParameter;
+import com.sunwin.visitorapp.BaseActivity;
+
+import static com.baidu.ai.cameraui.parameter.BaseParameter.KEY_MAIN;
+import static com.baidu.ai.cameraui.parameter.BaseParameter.KEY_MASK_TYPE;
+import static com.baidu.ai.cameraui.parameter.BaseParameter.MASK_TYPE_IDCARD_BACK;
+import static com.baidu.ai.cameraui.parameter.BaseParameter.MASK_TYPE_IDCARD_FRONT;
+
+public abstract class IDcardCardActivity extends BDActivity {
+
+    @Override
+    protected void onDispatchCreate(@Nullable Bundle savedInstanceState) {
+        IDcardParameter parameter = new IDcardParameter();
+        Bundle bundle = getIntent().getBundleExtra(KEY_MAIN);
+        if (bundle != null) {
+            if (bundle.getInt(KEY_MASK_TYPE) == MASK_TYPE_IDCARD_FRONT) {
+                parameter.setDefaultTip("请对正身份证头像页");
+            }
+            if (bundle.getInt(KEY_MASK_TYPE) == MASK_TYPE_IDCARD_BACK) {
+                parameter.setDefaultTip("请对正身份证国徽页");
+            }
+        }
+        setParameter(parameter);
+    }
+}