根据提示做出相应的活体动作,SDK 实时采集动态信息,判断用户是否为活体、真人。在黑灰产对抗激烈,“AI换脸”频发的场景下,活体检测SDK同时也集成了 风控设备环境检测能力,能够有效拦截摄像头被外部流注入的情况,同时独有的人脸鉴伪技术也能很好的识别合成脸攻击 > ⚠️ 接入活体SDK注意事项: 1. 本地手动依赖,默认提供了活体检测、风控设备环境检测能力(推荐) 2. 远程仓库依赖,仅集成了基础活体检测,不具备环境风险感知能力,如果您对SDK体积比较敏感,可以这种方式 3. 如果您的产品服务的用户主要在海外,请联系技术支持提供海外专属技术方案,耗时更低 ## 兼容性 条目 | 说明 适配版本 | minSdkVersion 21 及以上版本 cpu 架构 | 内部提供了 armeabi-v7a 和 arm64-v8a 两种 so ,对于不兼容 arm 的 x86 机型不适配 ## 资源引入 ### 本地手动依赖(推荐) #### 获取 SDK 从易盾后台下载活体检测相关 sdk 的 aar 包 #### SDK模块介绍 模块名称 | 功能说明 | 支持裁剪 | SDK包体积 | 编译后体积增量 livedetect-xxx.aar | 活体人脸检测 | 不可裁剪 | 3.7MB | 3.8MB crashreport-xxx.aar | 活体人脸检测异常上报 | 不可裁剪 | 172KB | 173KB base-core.aar | 活体人脸检测基本库 | 不可裁剪 | 34KB | 35KB HTProtectLib-xxx.aar | 风控设备环境检测 | 可裁剪 | 6.1MB | 6.4MB #### 添加 aar 包依赖 将获取到的 aar 文件拷贝到对应 module 的 libs 文件夹下(如没有该目录需新建),然后在 build.gradle 文件中增加如下代码 Code: android{ repositories { flatDir { dirs 'libs' } } } dependencies { implementation(name:'livedetect-xxx', ext: 'aar') implementation(name: 'crashreport-xxx', ext: 'aar') implementation(name: 'base-core-xxx', ext: 'aar') implementation(name: 'HTProtectLib-xxx', ext: 'aar') implementation 'com.squareup.okhttp3:okhttp:4.9.1' //若项目中原本存在无需添加 implementation 'com.google.code.gson:gson:2.8.6' //若项目中原本存在无需添加 } #### SDK包裁剪说明 如果您对 SDK 体积比较敏感,可以不集成 HTProtectLib-xxx.aar 包,但是这意味着您放弃了风控设备环境检测能力 ### 远程仓库依赖 #### 获取 SDK 确认 Project 根目录的 build.gradle 中配置了 mavenCentral 支持 Code: buildscript { repositories { mavenCentral() } ... } allprojects { repositories { mavenCentral() } } 在对应 module 的 build.gradle 中添加依赖 Code: implementation 'io.github.yidun:livedetect:3.3.8' #### 集成风控能力 如果需要在活体检测过程中检测设备环境,那需要额外接入风控 SDK,风控 SDK 仅提供本地依赖的方式 将易盾后台获取到的 aar 文件拷贝到对应 module 的 libs 文件夹下(如没有该目录需新建),然后在 build.gradle 文件中增加如下代码 Code: android{ repositories { flatDir { dirs 'libs' } } } dependencies { implementation(name: 'HTProtectLib-xxx', ext: 'aar') } ### 注意点 1. 在 app 的 build.gradle android 域下添加如下配置 Code: packagingOptions { doNotStrip "/arm64-v8a/libalive_detected.so" doNotStrip "/armeabi-v7a/libalive_detected.so" } 1. 如果同时使用易盾的活体检测和身份证 ocr sdk,请务必先引用 ocr sdk; 遇到 so 冲突,请用以下方式解决 Code: packagingOptions { pickFirst 'lib/arm64-v8a/libc++_shared.so' pickFirst 'lib/armeabi-v7a/libc++_shared.so' } ## 各种配置 ### 权限配置 SDK 依赖如下权限 Code ( ): 其中,所有活体检测模式均需要相机权限;RGB 活体模式还需要存储权限和设备状态权限。以上权限均属于隐私权限,Android 6.0 及以上版本需要在使用前动态申请。 Code: ActivityCompat.requestPermissions( this, new String[]{ Manifest.permission.CAMERA, Manifest.permission.WRITE_EXTERNAL_STORAGE, Manifest.permission.READ_PHONE_STATE }, 0 ); ### 申明与其他应用交互的意图范畴 在 Manifest 配置文件的权限配置下方添加如下配置 Code: ### 混淆配置 在 proguard-rules.pro 文件中添加如下混淆规则 Code: -keeppackagenames com.netease.nis.alivedetected -keep class com.netease.nis.alivedetected.**{*;} -dontwarn com.netease.nis.alivedetected.** -keep class com.netease.cloud.nos.yidun.**{*;} -dontwarn com.netease.cloud.nos.yidun.** -keep class com.netease.htprotect.**{*;} -keep class com.netease.mobsec.**{*;} ## 快速调用示例 ### 在 layout 布局文件中使用活体检测相机预览 View #### 注意点 - 为了避免在某些中低端机型上检测卡顿,建议预览控件的宽与高不要设置为全屏,过大的预览控件会导致处理的数据过大,降低检测流畅度 - 预览宽高不要随意设置,请遵守大部分相机支持的预览宽高比,3:4 或 9:16 - 最好限制竖屏,横屏会影响效果 #### 示例 Code: ### 在代码中调用相对应 api 开启活体检测 Code: public class DemoActivity extends AppCompatActivity { private AliveDetector aliveDetector; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_demo); NISCameraPreview cameraPreview = findViewById(R.id.surface_view); aliveDetector = AliveDetector.getInstance(); aliveDetector.init(this, cameraPreview, "申请的业务id"); aliveDetector.setDetectedListener(new DetectedListener() { @Override public void onReady(boolean isInitSuccess) { } @Override public void onActionCommands(ActionType[] actionTypes) { } @Override public void onStateTipChanged(ActionType actionType, String stateTip, int code) { //单步动作 actionType.getActionID()为 0:正视前方 1:向右转头 2:向左转头 3:张嘴动作 4:眨眼动作 5:动作错误 6:动作通过 } @Override public void onPassed(boolean isPassed, String token) { } @Override public void onCheck() { } @Override public void onError(int code, String msg, String token) { } @Override public void onOverTime() { } @Override public void onBackgroundColor(int color) { // RGB 活体模式下,根据 SDK 返回的颜色值更新检测页面背景颜色 } }); aliveDetector.startDetect(); } @Override protected void onDestroy() { super.onDestroy(); if (isFinishing()) { if (aliveDetector != null) { aliveDetector.stopDetect(); aliveDetector.destroy(); } } } } 更多使用场景请参考 demo (https://github.com/yidun/alive-detected-android-demo) ## SDK 方法说明 ### 1. 获取 AliveDetector 单例对象 #### 代码说明 Code: AliveDetector aliveDetector = AliveDetector.getInstance(); ### 2. 初始化 #### 代码说明 Code: aliveDetector.init(Context context, NISCameraPreview cameraPreview, String businessId) #### 参数说明 参数 | 类型 | 是否必填 | 默认值 | 描述 context | Context | 是 | 无 | 上下文 cameraPreview | NISCameraPreview | 是 | 无 | 相机预览 View businessId | String | 是 | 无 | 活体检测业务 id ### 3. 设置回调监听 #### 代码说明 代码添加在 init 之后 startDetect 之前调用 Code: aliveDetector.setDetectedListener(DetectedListener detectedListener) #### 参数说明 参数 | 类型 | 是否必填 | 默认值 | 描述 detectedListener | DetectedListener | 是 | 无 | 监听接口 #### DetectedListener 接口说明 Code: public interface DetectedListener { /** * 活体检测引擎初始化时回调 * * @param isInitSuccess 活体检测引擎是否初始化成功: * 1)true,初始化完成可以开始检测 * 2)false,初始化失败,可尝试重新启动活体检测流程 {@link AliveDetector#startDetect()} */ void onReady(boolean isInitSuccess); /** * 此次活体检测下发的待检测动作指令序列,{@link ActionType} * * @param actionTypes */ void onActionCommands(ActionType[] actionTypes); /** * 活体检测状态是否改变,当引擎检测到状态改变时会回调该接口 * * @param actionType 当前动作类型,枚举值,总共6种类型: * ACTION_STRAIGHT_AHEAD("0", "正视前方"), * ACTION_TURN_HEAD_TO_RIGHT("1", "向右转头"), * ACTION_TURN_HEAD_TO_LEFT("2", "向左转头"), * ACTION_OPEN_MOUTH("3", "张嘴动作"), * ACTION_BLINK_EYES("4", "眨眼动作"), * ACTION_ERROR("5", "动作错误"), * ACTION_PASSED("6", "动作通过") * * @param stateTip 引擎检测到的实时状态 * @param code 错误码,在ACTION_ERROR时用于国际化使用(0:手机抖动,请保持稳定、1:请移动人脸到摄像头视野中间、2:环境光线暗、3:环境光线过亮、4:图像质量模糊、5:多人脸、6:距离太远、7:距离太近) */ void onStateTipChanged(ActionType actionType, String stateTip, int code); /** * 活体检测是否通过回调 * * @param isPassed 活体检测是否通过,true:通过,false:不通过 * @param token 此次活体检测返回的易盾token */ void onPassed(boolean isPassed, String token); /** * 活体检测本地检测通过 * 启动远程检测 */ void onCheck(); /** * 活体检测过程中出现错误时回调 * * @param code 错误码 * 1:sdk内部异常 2:服务端返回数据异常 3:上传图片异常 * @param msg 出错原因 */ void onError(int code, String msg, String token); /** * 活体检测过程超时回调 */ void onOverTime(); /** * RGB 活体检测背景颜色变化回调 * * @param color SDK 返回的背景颜色值 */ void onBackgroundColor(int color); } #### onBackgroundColor 回调说明 RGB 活体模式会通过该回调返回检测页面需要展示的背景颜色。业务方收到回调后,应根据 color 更新活体检测页面的背景颜色。无 RGB 需求无需额外处理该回调。 ### 4. 开始活体检测 代码添加在 init 之后调用 #### 代码说明 Code: aliveDetector.startDetect() ### 5. 停止活体检测 #### 代码说明 可在onStop、onDestroy中调用 Code: aliveDetector.stopDetect() ### 6. 释放资源(建议放在 onDestroy) #### 代码说明 Code: aliveDetector.destroy() ### 7. 是否开启调试模式(非必须) #### 代码说明 Code: aliveDetector.setDebugMode(boolean isDebug) #### 参数说明 参数 | 类型 | 是否必填 | 默认值 | 描述 isDebug | boolean | 是 | false | 是否打印日志 ### 8. 设置检测动作灵敏度(非必须) #### 代码说明 Code: aliveDetector.setSensitivity(int sensitivity) #### 参数说明 参数 | 类型 | 是否必填 | 默认值 | 描述 sensitivity | int | 是 | AliveDetector.SENSITIVITY_NORMAL | 可取值 AliveDetector.SENSITIVITY_EASY = 0、AliveDetector.SENSITIVITY_NORMAL = 1、AliveDetector.SENSITIVITY_HARD = 2 分别对应容易、普通、难 ### 9. 设置超时时间(非必须) 代码添加在 startDetect 之前调用 #### 代码说明 Code: aliveDetector.setTimeOut(long timeout) #### 参数说明 参数 | 类型 | 是否必填 | 默认值 | 描述 timeout | long | 是 | 30000 | 单位毫秒 ### 10. 设置域名(非必须) 用于海外域名失效的场景,可以设置私有化的域名列表,内部会自动切换 #### 代码说明 Code: aliveDetector.setHosts(String[] hosts) #### 参数说明 参数 | 类型 | 是否必填 | 默认值 | 描述 hosts | String[] | 是 | 无 | 多域名 ### 11. 是否允许多人脸(非必须) #### 代码说明 Code: aliveDetector.setAllowMultipleFace(boolean allowMultipleFace) #### 参数说明 参数 | 类型 | 是否必填 | 默认值 | 描述 allowMultipleFace | boolean | 是 | false | 是否允许多人脸 ### 12. 设置设备抖动检测阈值(非必须) 值越小越灵敏 #### 代码说明 Code: aliveDetector.setShakeThreshold(int shakeThreshold) #### 参数说明 参数 | 类型 | 是否必填 | 默认值 | 描述 shakeThreshold | int | 是 | 35 | 抖动检测阈值 ### 13. 设置人脸占比阈值(非必须) #### 代码说明 Code: aliveDetector.setFaceThreshold(int faceThreshold) #### 参数说明 参数 | 类型 | 是否必填 | 默认值 | 描述 faceThreshold | int | 是 | 7 | 人脸占比阈值,范围7-50