开发者中心

名称: 上海璟梦信息科技有限公司实人认证 SDK 集成文档
版本: V3.0.0.2
日期: 2022-04-29

合规性说明

SDK名称 场景描述 收集个人信息的类型 第三方机构名称 数据是否加密传输 第三方隐私政策链接
实名认证SDK 活体检测 实名认证SDK提供活体检测服务过程中收集和使用的信息包括:
用户的面部识别信息(静态及/或动态)、用户的设备摄像头权限:用于活体检测服务中人脸检测、人脸检索、人脸比对;
上海璟梦信息科技有限公司 https://sdk.253.com/commit-detail/rcc5zd/fd21s8

一、活体检测模块

(一)、集成指南

1. 申请 APP_KEY, APP_SECRET

  1. 开发者平台申请

2. 导入 SDK 模块包

在根目录下的build.gradle 下加入

allprojects {
    repositories {
        google()
        mavenCentral()
        jcenter() // Warning: this repository is going to shut down soon
        maven {
            url "https://nexus-sdk.cm253.com/repository/maven-public/"
        }
    }
}

在app目录下的build.gradle加入


dependencies {
    implementation "com.jingmeng.sdk.android:base:1.0.0.5"
    implementation('com.jingmeng.sdk.android:alive:1.0.1.12')
    implementation('com.jingmeng.sdk.android:alive-ui:1.0.1.4')
}

3. 配置 AndroidManifest.xml

注: 此处为配置 HTTP 访问(非强制)

<application
    .....
    android:requestLegacyExternalStorage="true"
    android:usesCleartextTraffic="true">
</application>

(二)、接口调用

1. 活体检测模块初始化

AliveUiManager.getInstance().init(context); // 子模块必须在 Base 模块前先初始化
//开启日志开关
CLBaseManager.setDebuggable(true);
CLBaseManager.setWarnDeprecated(true);
CLBaseManager.init(context, 申请的APP_KEY);

2. 活体检测配置接口

// 设置动作数量 1-3 分别代表 1-3 个动作,4 代表 1-3 个动作随机,不设置默认是 1
AliveUiEngine.getInstance().setActionSize(1);
// 安全级别 0:低 1:高 (不设置默认为0) 低级别随机动作,高级别将包含局部和全脸动作
// 安全等级为高时最低检测动作数为 2
AliveUiEngine.getInstance().setSecurityLevel(0);
// 每个动作的执行时间,单位为秒(推荐设置为 3 秒)
AliveUiEngine.getInstance().setActionSecond(3);
// 设置是否有结果页面
AliveUiEngine.getInstance().setHasResultPage(true);
// 人脸检测超时时间,不大于 120s,且不小于 10s,不设置默认为 30s
AliveUiEngine.getInstance().setTimeout(30);

3. (不推荐)活体检测获取 Token 接口

注: 建议 获取token放在服务端,防止APP_KEY和APP_SECRET 泄漏后盗刷

 if(NetworkUtils.isNetWorkAvailable(this)){
     AliveManager.getInstance().getToken(您的APP_KEY, 您的APP_SECRET, new AliveDetectedListener() {
         @Override
         public void success(String token) {
             aliveToken = token;
         }

         @Override
         public void fail(String code, String msg) {
             Log.d(TAGALIVE, "code= " + code + " msg=" + msg);
         }
     });
 } else {
     Toast.makeText(getApplicationContext(), "请检查网络状态", Toast.LENGTH_LONG).show();
     finish();
 }

4. 活体检测模块调用

注: mScore 为你调用人像比对接口的判断条件, 此变量为您自己定义

// distance 为人脸检测距离,默认是 3f(值为 3f - 5f ),值越小需要脸贴越近
AliveUiManager.getInstance().startActivity(context, 您获取的token, distance, true, new AliveDetectedResultListener() {
    @Override
    public void success(double score) {
        Log.d(TAGALIVE, "score = " + score);
        mScore = score;
    }

    @Override
    public void cancel(String msg) {
        Log.d(TAGALIVE, "cancel msg = " + msg);
        mScore = 0;
    }

    @Override
    public void fail(String msg) {
        Log.d(TAGALIVE, "fail msg = " + msg);
        mScore = 0;
    }
});

活体检测资源释放,否则会导致内存泄露

@Override
protected void onDestroy() {
    super.onDestroy();
    AliveUiEngine.getInstance().release();
}

5. 自定义初始界面 UI

AliveUiEngine.getInstance().setLayoutAliveDetectedPreId(R.layout.jm_activity_alive_detected_pre);
<?xml version="1.0" encoding="utf-8"?>
<ScrollView xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent">

    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:orientation="vertical">

        <include layout="@layout/jm_alive_ui_common_title_layout" />

        <TextView
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_gravity="center_horizontal"
            android:layout_marginTop="25dp"
            android:layout_marginBottom="28dp"
            android:text="这里输入您的提示语"
            android:textColor="@color/purple_700"
            android:textSize="15sp"
            android:textStyle="bold" />

        <ImageView
            android:layout_width="169dp"
            android:layout_height="169dp"
            android:layout_gravity="center_horizontal"
            android:src="@mipmap/img"/>

        <TextView
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_marginLeft="12dp"
            android:layout_marginTop="50dp"
            android:text="1. 这里可以输入您的操作步骤 1 \n2. 这里可以输入您的操作步骤 2"
            android:textColor="#333333"
            android:textSize="15sp" />

        <LinearLayout
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:layout_marginTop="36dp"
            android:orientation="horizontal"
            android:paddingLeft="10dp"
            android:paddingRight="10dp">

            <TextView
                android:layout_width="0dp"
                android:layout_height="wrap_content"
                android:layout_weight="1"
                android:drawableTop="@mipmap/jm_alive_ui_online_alive1"
                android:drawablePadding="1dp"
                android:gravity="center"
                android:text="不能遮挡脸部" />

            <TextView
                android:layout_width="0dp"
                android:layout_height="wrap_content"
                android:layout_weight="1"
                android:drawableTop="@mipmap/jm_alive_ui_online_alive2"
                android:drawablePadding="1dp"
                android:gravity="center"
                android:text="不能在昏暗\n逆光下拍摄" />

            <TextView
                android:layout_width="0dp"
                android:layout_height="wrap_content"
                android:layout_weight="1"
                android:drawableTop="@mipmap/jm_alive_ui_online_alive3"
                android:drawablePadding="1dp"
                android:gravity="center"
                android:text="不能斜视手机" />
        </LinearLayout>

        <!-- 样式可以自定义, 但 ID 必须相同否则无法跳转 -->
        <Button
            android:id="@id/jm_alive_ui_id_alive_result_pre_btn_start_detected"
            android:layout_width="match_parent"
            android:layout_height="44dp"
            android:layout_marginLeft="20dp"
            android:layout_marginTop="45dp"
            android:layout_marginRight="20dp"
            android:layout_marginBottom="8dp"
            android:background="@drawable/jm_alive_ui_ocr_blue_button_selector"
            android:gravity="center"
            android:paddingStart="16dp"
            android:paddingLeft="16dp"
            android:text="这里设置您的跳转按钮"
            android:textColor="#FFFFFFFF"
            android:textSize="16sp" />

    </LinearLayout>
</ScrollView>

注: 跳转到活体检测页面的按钮 ID 必须为 jm_alive_ui_id_alive_result_pre_btn_start_detected

6. 活体检测页 UI

AliveUiEngine.getInstance().setLayoutAliveDetectedId(R.layout.jm_alive_ui_activity_alive_detected);
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical">

    <include layout="@layout/jm_alive_ui_common_title_layout" />

    <RelativeLayout
        android:layout_width="match_parent"
        android:layout_height="wrap_content">

        <ImageView
            android:id="@id/jm_alive_ui_id_alive_iv_sound"
            android:layout_width="30dp"
            android:layout_height="30dp"
            android:layout_centerVertical="true"
            android:layout_marginStart="20dp"
            android:layout_marginLeft="20dp"
            android:layout_marginTop="8dp"
            android:scaleType="fitXY"
            android:src="@mipmap/jm_alive_ui_online_alive_blue" />

        <com.jingmeng.sdk.android.alive.ui.widget.CountTimeProgressView
            android:id="@id/jm_alive_ui_id_alive_pv_count_time"
            android:layout_width="36dp"
            android:layout_height="36dp"
            android:layout_alignParentEnd="true"
            android:layout_alignParentRight="true"
            android:layout_centerVertical="true"
            android:layout_marginTop="8dp"
            android:layout_marginEnd="16dp"
            android:layout_marginRight="16dp"
            android:visibility="visible"
            app:backgroundColorCenter="@android:color/transparent"
            app:borderBottomColor="@android:color/darker_gray"
            app:borderDrawColor="#7C49F2"
            app:borderWidth="2dp"
            app:clockwise="true"
            app:countTime="30000"
            app:textStyle="second"
            app:titleCenterColor="#FF222222"
            app:titleCenterSize="12sp" />
    </RelativeLayout>

    <TextView
        android:id="@id/jm_alive_ui_id_alive_tv_detect_tips"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_gravity="center_horizontal|top"
        android:gravity="center"
        android:text="请面向屏幕"
        android:textColor="#333333"
        android:textSize="18sp"
        android:textStyle="bold" />

    <FrameLayout
        android:layout_width="match_parent"
        android:layout_height="wrap_content">

        <com.jingmeng.sdk.android.alive.ui.widget.AliveDetectSurfaceView
            android:id="@id/jm_alive_ui_id_alive_surface_view_preview"
            android:layout_width="210dp"
            android:layout_height="210dp"
            android:layout_gravity="center"
            android:background="@android:color/transparent" />

        <com.jingmeng.sdk.android.alive.ui.widget.CircleBorderView
            android:id="@id/jm_alive_ui_id_alive_round_view"
            android:layout_width="240dp"
            android:layout_height="240dp"
            android:layout_gravity="center" />

        <ImageView
            android:id="@id/jm_alive_ui_id_alive_iv_face_outline"
            android:layout_width="120dp"
            android:layout_height="160dp"
            android:layout_gravity="center"
            android:src="@mipmap/jm_alive_ui_face_border_red" />

        <com.jingmeng.sdk.android.alive.ui.widget.CircleScanView
            android:id="@id/jm_alive_ui_id_alive_cs_view"
            android:layout_width="210dp"
            android:layout_height="210dp"
            android:layout_gravity="center"
            android:background="@android:color/transparent"
            android:visibility="gone" />
    </FrameLayout>

    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:orientation="vertical">

        <com.jingmeng.sdk.android.alive.ui.widget.GifImageView
            android:id="@id/jm_alive_ui_id_alive_gif_image_view"
            android:layout_width="123dp"
            android:layout_height="111dp"
            android:layout_gravity="center"
            android:src="@mipmap/jm_alive_ui_online_alive_default"
            android:visibility="invisible" />

        <LinearLayout
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_gravity="center_horizontal">

            <TextView
                android:id="@id/jm_alive_ui_id_alive_tv_step1"
                android:layout_width="20dp"
                android:layout_height="20dp"
                android:layout_margin="4dp"
                android:background="@drawable/jm_alive_ui_circle_tv_focus"
                android:gravity="center"
                android:text="1"
                android:textColor="#FFFFFFFF"
                android:textSize="10sp"
                android:visibility="gone" />

            <TextView
                android:id="@id/jm_alive_ui_id_alive_tv_step2"
                android:layout_width="20dp"
                android:layout_height="20dp"
                android:layout_margin="4dp"
                android:background="@drawable/jm_alive_ui_circle_tv_un_focus"
                android:gravity="center"
                android:text=""
                android:textColor="#FFFFFFFF"
                android:textSize="10sp"
                android:visibility="gone" />

            <TextView
                android:id="@id/jm_alive_ui_id_alive_tv_step3"
                android:layout_width="20dp"
                android:layout_height="20dp"
                android:layout_margin="4dp"
                android:background="@drawable/jm_alive_ui_circle_tv_un_focus"
                android:gravity="center"
                android:text=""
                android:textColor="#FFFFFFFF"
                android:textSize="10sp"
                android:visibility="gone" />
        </LinearLayout>

    </LinearLayout>

</LinearLayout>

7. 自定义检测成功页 UI

AliveUiEngine.getInstance().setLayoutAliveDetectedSuccessId(R.layout.jm_alive_ui_activity_alive_detected_success);
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical">

    <include layout="@layout/jm_alive_ui_common_title_layout" />

    <ImageView
        android:id="@+id/iv_success"
        android:layout_width="200dp"
        android:layout_height="100dp"
        android:layout_centerHorizontal="true"
        android:layout_gravity="center"
        android:layout_marginTop="20dp"
        android:scaleType="fitCenter"
        android:src="@mipmap/img_1" />

    <TextView
        android:id="@+id/tv_success_tip"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_centerHorizontal="true"
        android:layout_gravity="center"
        android:text="自定义您的成功提示"
        android:textSize="22sp" />

    <Button
        android:id="@id/jm_alive_ui_id_alive_result_success_btn_back_to_demo"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_marginLeft="40dp"
        android:layout_marginTop="20dp"
        android:layout_marginRight="40dp"
        android:background="@drawable/jm_alive_ui_btn_shape_success"
        android:text="返回首页"
        android:textColor="#FFFFFF"
        android:textSize="18sp" />
</LinearLayout>

8. 自定义认证失败页 UI

AliveUiEngine.getInstance().setLayoutAliveDetectedFailId(R.layout.jm_alive_ui_activity_alive_detected_failure);
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical">

    <include layout="@layout/jm_alive_ui_common_title_layout" />

    <ImageView
        android:layout_width="128dp"
        android:layout_height="134dp"
        android:layout_centerHorizontal="true"
        android:layout_gravity="center"
        android:layout_marginTop="50dp"
        android:scaleType="fitCenter"
        android:src="@mipmap/img_2" />

    <TextView
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_centerHorizontal="true"
        android:layout_gravity="center"
        android:text="自定义您的错误提示"
        android:textSize="22sp" />

    <TextView
        android:id="@id/jm_alive_ui_id_alive_result_fail_tv_error_tips"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_marginLeft="48dp"
        android:layout_marginTop="16dp"
        android:layout_marginRight="48dp"
        android:gravity="center"
        android:lineSpacingExtra="4dp"
        android:textSize="16sp"
        tools:text="" />

    <Button
        android:id="@id/jm_alive_ui_id_alive_result_fail_btn_back_to_demo"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_marginLeft="40dp"
        android:layout_marginTop="60dp"
        android:layout_marginRight="40dp"
        android:background="@drawable/jm_alive_ui_btn_shape_success"
        android:text="返回首页"
        android:textColor="#FFFFFF"
        android:textSize="18sp" />

</LinearLayout>

9. 人像比对接口

注: 先要进行活体检测拿到人像分值后, 才可以进行人像比对

// token 活体检测后即可获取的 token
// id_card_no: 为用户身份证号码
// id_card_name: 为用户姓名
AliveManager.getInstance().faceAliveMatch(token, id_card_no, id_card_name, new AliveDetectedListener() {
    @Override
    public void success(String json) {
        try {
            JSONObject data = new JSONObject(json);
            StringBuffer stringBuffer = new StringBuffer();
            stringBuffer.append("比对结果: ").append(data.optString("match")).append("\n");
            stringBuffer.append("人像分值 范围[0,100]: ").append(data.optString("score")).append("\n");
            stringBuffer.append("比对结果描述: ").append(data.optString("desc")).append("\n");
        } catch (JSONException e) {
            e.printStackTrace();
        }
    }

    @Override
    public void fail(String s, String s1) {
        Log.e("TAG", "onFailure()call=" + s1.toString());
    }
});

10. 自定义活体检测页相关逻辑

注: 此处为您不采用我们的 UI 包, 而自己想自定义您自己的活体检测页面的样式时使用。

// 自定义活体检测页相关逻辑
SdkConfiguration configuration = new SdkConfiguration.Builder()
    // 建议从服务端调用获取 authToken 接口获取
    .setAuthToken(aliveToken)
    // 设置动作数量 1-3 分别代表 1-3 个动作,4 代表 1-3 个动作随机,不设置默认是 4
    .setActionSize(1)
    // 每个动作的执行时间,单位为秒
    .setActionSecond(3)
    // 安全级别 0:低 1:高 (不设置默认为0) 低级别随机动作,高级别将包含局部和全脸动作
    .setSecurityLevel(0)
    // 设置当前 Activity 对象
    .setActivity(this)
    // 人脸检测超时时间,不大于 120s,且不小于 10s,不设置默认为 30s
    .setTimeout(30)
    // 设置相机配置,比如相机预览的大小等等
    .setICameraConfig(this::getCameraParameters)
    .build();
AliveManager.getInstance().start(configuration, new IAliveDetectedListener() {
    /**
             * 当准备好的时候
             */
    @Override
    public void onReady() {

    }

    /**
             * 当收到下发的动作序列时
             * @param actions 动作序列列表
             */
    @Override
    public void onReceivedActions(List<OnlineAliveBean> actions) {

    }

    /**
             * 当提示动作改变时的回调,比如提示做下一个动作时
             * @param index 动作下标,从 0 开始
             */
    @Override
    public void onActionChanged(final int index) {

    }

    /**
             * 当提示状态变化时的回调
             * @param tip 提示信息
             */
    @Override
    public void onStateTipChanged(String tip) {

    }

    /**
             * 当脸部状态变化时
             * @param isFullFace true:预览框检测到全脸,false 不是全脸
             */
    @Override
    public void onFaceStateChanged(boolean isFullFace) {

    }

    /**
             * 人脸已经就位,准备提示动作指令
             */
    @Override
    public void onFaceReady() {

    }

    /**
             * 服务端开始检测的回调,这个时候可以显示一些动画或者 Loading
             */
    @Override
    public void onStartDetect() {

    }

    /**
             * 服务端检测完成的回调,这个时候可以停止显示动画或者 Loading
             */
    @Override
    public void onDetectComplete() {

    }

    /**
             * 活体检测完成
             */
    @Override
    public void onPassed(String data) {
        // 返回数据示例: {"score":0.9667554498,"action_verify":"pass"}
        // action_verify 为 pass 时代表动作验证通过,score 为活体检测分数,
        // 请自行根据自身业务场景设置阈值进行判断是否通过
    }

    /**
             * 当活体检测有错误时的回调
             */
    @Override
    public void onError(String errCode, String errMsg) {

    }

    /**
             * 当活体检测超时时的回调
             */
    @Override
    public void onOverTime() {

    }
});

11. 将活体检测视频保存到自己的服务器

AliveManager.getInstance().setIVideoRecordListener(new IVideoRecordListener() {
    @Override
    public void onComplete(String videoPath, IVideoUploadListener listener) {

    }
});

12. 活体检测响应数据

错误码 错误信息 备注说明
权限相关(1开头)
10001 缺少相机权限 /
10002 缺少读写SD卡权限 /
参数相关(2开头)
20001 context为空,SDK没有初始化或者初始化失败 /
20002 appId为空,SDK没有初始化或者初始化失败 /
20003 网络异常,请检查网络连接 /
20004 请求超时,请检查网络连接或重试! /
业务相关(3、0或216开头)
30001 动作验证未通过,请按提示完成动作 /
30002 活体检测超时,请在规定时间内完成提示动作 /
30003 当前网络不稳定,请切换网络后再试 /
30004 返回数据解析异常 /
30005 活体检测视频解析失败,请重新再试
216434 人脸动作与提示动作不吻合,请重试 /
216501 没有检测到人脸,请重试 /
216507 检测到有多张人脸,请重试 /
216908 检测到人脸模糊,请重试 /
000400 令牌无效 authToken超过有效期或者使用的AppKey 和 AppSecret 不对
000998 账户金额预消耗失败 账号余额不足了
500003 活体检测视频太长 活体视频超过15秒

二、OCR 身份证识别模块

(一)、集成指南

1. 申请 APP_KEY, APP_SECRET

  1. 开发者平台申请

2. 导入 SDK 模块包

dependencies {
    implementation "com.jingmeng.sdk.android:base:1.0.0.4"
    implementation('com.jingmeng.sdk.android:ocr:1.0.0.8')
    implementation('com.jingmeng.sdk.android:ocr-ui:1.0.1.3')
}

3. 配置 AndroidManifest.xml

注: 此处为配置 HTTP 访问(非强制)

<application
    .....
    android:requestLegacyExternalStorage="true"
    android:usesCleartextTraffic="true">
</application>

(二)、接口调用

1. OCR 身份证识别模块初始化

OcrUiManager.getInstance().init(context); // 子模块必须在 Base 模块前先初始化
//开启日志开关
CLBaseManager.setDebuggable(true);
CLBaseManager.setWarnDeprecated(true);
CLBaseManager.init(context, 申请的APP_KEY);

2. (不推荐)OCR 身份证识别获取 Token 接口

注: 建议 获取token放在服务端,防止APP_KEY和APP_SECRET 泄漏后盗刷

if(NetworkUtils.isNetWorkAvailable(this)){
    OcrManager.getInstance().getToken(您的APP_KEY, 您的APP_SECRET, new OcrDetectedListener() {
        @Override
        public void success(String token) {
            ocrToken = token;
        }

        @Override
        public void fail(String code, String msg) {
            Log.d(TAGOCR, "code= " + code + " msg=" + msg);
        }
    });
} else {
    Toast.makeText(getApplicationContext(), "请检查网络状态", Toast.LENGTH_LONG).show();
    finish();
}

OCR 身份证识别模块调用

// token 建议通过服务端获取
OcrUiManager.getInstance().startActivity(context, 您获取的token, true, new OcrDetectedResultListener() {
    @Override
    public void success(String jsonResult) {
        Log.d(TAGOCR, "jsonResult = " + jsonResult);
    }

    @Override
    public void cancel(String msg) {
        Log.d(TAGOCR, "cancel msg = " + msg);
    }

    @Override
    public void fail(String jsonResult) {
        Log.d(TAGOCR, "fail jsonResult = " + jsonResult);
    }
});

OCR 身份证识别资源释放, 否则会导致内存泄露

@Override
protected void onDestroy() {
    super.onDestroy();
    OcrUiEngine.getInstance().release();
}

OCR 双面识别接口

入参 说明 备注
authToken 授权token,建议通过服务端获取 /
frontBytes 身份证正面文件的 byte 数组 /
backBytes 身份证反面文件的 byte 数组 /
IDetectedListener 监听器 /
// Param 1: 您的token
// Param 2: 用户选择的身份证正面照片的 byte 数组
// Param 3: 用户选择的身份证反面照片的 byte 数组
// Param 4: 结果监听器
OcrManager.getInstance().doubleSide(token, frontBytes, backBytes, new IDetectedListener() {
    @Override
    public void onSuccess(String result) {
        // 返回成功结果
    }

    @Override
    public void onFailed(int errorCode, String errorMsg) {
        // 返回失败码, 及失败信息
    }
});

OCR 单面识别接口

入参 说明 备注
authToken 授权token,建议通过服务端获取 /
side front 为正面,back 为反面 /
imageBytes 身份证照片文件的 byte 数组 /
IDetectedListener 监听器 /
// Param 1: 您的token
// Param 2: "front" 为正面, "back" 为反面
// Param 3: 用户选择的照片的 byte 数组
// Param 4: 结果监听器
OcrManager.getInstance().singleSide(token, "front", imageBytes, new IDetectedListener() {
    @Override
    public void onSuccess(String result) {
        // 返回成功结果
    }

    @Override
    public void onFailed(int errorCode, String errorMsg) {
        // 返回失败码, 及失败信息
    }
});

OCR 响应数据

{
    "code": "000000",
    "message": "成功",
    "data": {
        "order_no": "011634609037212683",
        "handle_time": "2021-10-19 10:03:57",
        "province": "湖南省",
        "city": "邵阳市",
        "country": "邵阳县",
        "birthday": "19760320",
        "age": "46",
        "gender": "1",
        "remark": "一致",
        "result": "01"
    }
}

身份证二要素认证

authToken 授权token,建议通过服务端获取 /
name 姓名 /
idNum 身份证号 /
IDetectedListener 监听器 /
// Param 1: 授权token,建议通过服务端获取
// Param 2: 姓名
// Param 3: 身份证号
// Param 4: 结果监听器
OcrManager.getInstance().verify(authToken, name, idNum, new IDetectedListener() {
    @Override
    public void onSuccess(String result) {
        Log.d("TAG", "json:" + result);
    }

    @Override
    public void onFailed(int errorCode, String errorMsg) {
        Log.e("TAG", "onFailure():call=" + errorCode);
    }
});

三、集合调用

(一)、集成指南

1. 申请 APP_KEY, APP_SECRET

  1. 开发者平台申请

2. 导入 SDK 模块包

dependencies {
    implementation "com.jingmeng.sdk.android:base:1.0.0.5"
    implementation('com.jingmeng.sdk.android:ocr:1.0.0.8')
    implementation('com.jingmeng.sdk.android:ocr-ui:1.0.1.3')
    implementation('com.jingmeng.sdk.android:alive:1.0.1.12')
    implementation('com.jingmeng.sdk.android:alive-ui:1.0.1.4')
}

3. 配置 AndroidManifest.xml

注: 此处为配置 HTTP 访问(非强制)

<application
    .....
    android:requestLegacyExternalStorage="true"
    android:usesCleartextTraffic="true">
</application>

(二)、接口调用

1. 初始化

OcrUiManager.getInstance().init(context); // 子模块必须在 Base 模块前先初始化
AliveUiManager.getInstance().init(context); // 子模块必须在 Base 模块前先初始化
// 自定义初始页面 UI
AliveUiEngine.getInstance().setLayoutAliveDetectedPreId(R.layout.jm_activity_alive_detected_pre);
// 自定义检测页
AliveUiEngine.getInstance().setLayoutAliveDetectedId(R.layout.jm_alive_ui_activity_alive_detected);
// 自定义检测成功页
AliveUiEngine.getInstance().setLayoutAliveDetectedSuccessId(R.layout.jm_alive_ui_activity_alive_detected_success);
// 自定义检测失败页
AliveUiEngine.getInstance().setLayoutAliveDetectedFailId(R.layout.jm_alive_ui_activity_alive_detected_failure);
//开启日志开关
CLBaseManager.setDebuggable(true);
CLBaseManager.setWarnDeprecated(true);
CLBaseManager.init(context, 申请的APP_KEY);

注: 具体接口调用参照模块调用说明

常见问题

  1. 启动后预览界面黑屏,是因为token是网络获取的,初始化不是第一时间,导致摄像头空指针了。

解决方案是:
image.png