Android接入Advance.Ai活体检测 Api (安卓活体检测)
通过摄像头实时采集动态影像、识别人物面部表情,以此检测、验证用户的真实性与可靠性。 advance.ai 系统已针对印度尼西亚、印度、菲律宾、越南、泰国这五个国家市场的本地使用环境,定制开发了性能优化方案
活体检测前提:安卓系统相机授权可点击此链接学习
1.advance活体检测动作
快速调用代码块(下方有详细操作)
String accessKey = "ADVANCE_ACCESS_KEY";
String secretKey = "ADVANCE_SECRET_KEY";
Market market = Market.Indonesia;
GuardianLivenessDetectionSDK.init(getApplication(), accessKey, secretKey, market);
GuardianLivenessDetectionSDK.setActionSequence(true,Detector.DetectionType.POS_YAW, Detector.DetectionType.MOUTH, Detector.DetectionType.BLINK);
2.advance官网
2.1 中文官网
https://www.advanceai.com.cn/cn/index/pageview/catid/122.html
2.2 印尼官网
https://in.advance.ai/
[ click (API Doc-> Liveness detection) 点击 (API文档->活体检测) ]
2.3 英文官网
https://www.advance.ai/liveness-detection
3. Android接入advance活体检测
Android接入AdvanceAI活体检测,通过摄像头实时采集检测详细说明如下:
3.0 Advance活性检测服务有三个步骤:
`
*步骤1:请求活动检测许可证授权以获得“许可证”
*步骤2:转到下载,下载Android或IOS SDK,将其集成到您的移动应用程序中,以进行活跃度检测,并将步骤1中获取的“许可证”作为请求参数
*步骤3:请求Liveness Detection,以步骤2返回的“livenessId”作为请求参数,获取Liveness分数及其对应的图像
`
官网参考: 活动检测许可证授权(步骤一) Android or IOS(步骤二) example Android sdk url address:SDK (如果访问不了外网,可下载我上传csdn的SDK资源包 或 AndroidX SDK)
当下载完SDK后,可进行如下操作:
3.1 集成 SDK 到您的工程中
3.1.1 打开SDK文件夹,得到如下文件。
文件/文件夹名称 | 解释 |
---|
liveness | 集成活体检测功能的模块 |
- liveness module 是集成了活体检测功能的UI模块,可直接引用到您的主工程中,根据实际需求进行个性化修改。
- 考虑到架构之间存在兼容性,以及每种架构的机型占比,如果对包大小有要求,建议选择如下方案:
android{
...
defaultConfig {
...
ndk {
abiFilters "armeabi","arm64-v8a","x86"
}
}
}
3.1.2 导入 liveness 模块到您的工程
导入模块时注意点说明:
①.liveness模块与app同级目录 ②.livenness模块内的build.gradle下的vision版本记得更改 compileSdkVersion、targetSdkVersion等 ③.app目录内的build.gradle下的dependencies依赖以及flatDir 加入:
repositories {
flatDir {
dirs project(':liveness').file('libs')
}
}
dependencies {
implementation project(":liveness")
}
④. 修改android目录下的setting.gradle文件,添加项目模块的引用
include ":liveness"
3.2 快速接入SDK
- 初始化 SDK。
- 在自定义的 application 中增加如下初始化代码:
GuardianLivenessDetectionSDK.init(this,your market);
JAVA Android 例子
String accessKey = "ADVANCE_ACCESS_KEY";
String secretKey = "ADVANCE_SECRET_KEY";
Market market = Market.Indonesia;
GuardianLivenessDetectionSDK.init(getApplication(), accessKey, secretKey, market);
Market |
---|
Indonesia | India | Philippines | Vietnam | Thailand | Malaysia | Mexico | Singapore | Aksata | Pakistan | Nigeria | CentralData |
最后一个参数 Market 是一个枚举类型,必须和您的账号所属国家的类别一致,否则无法通过授权。
- 设置 license (由您的服务端调用openAPI获取license)
String checkResult = GuardianLivenessDetectionSDK.setLicenseAndCheck(license);
if ("SUCCESS".equals(checkResult)) {
startLivenessActivity();
} else {
}
- 启动活体检测与获取检测结果。
SDK 默认不检查相机权限,如果您希望权限的申请交由 SDK 处理,可在 SDK 初始化方法调用后,调用如下方法,则 LivenessActivity 中会执行权限申请的操作:
GuardianLivenessDetectionSDK.letSDKHandleCameraPermission();
每次进行活体检测成功后,会返回唯一的 livenessId 和本次检测的 300*300 像素的清晰正面照片。
- 您需要将 livenessId 传给您的服务端,由服务端调用 openAPI 获取本次检测的分值。
- 您可以通过 SDK 提供的方法直接获取图片,也可以由服务端调用 openAPI 获取。
public static final int REQUEST_CODE_LIVENESS = xxxx;
private void startLivenessActivity() {
Intent intent = new Intent(this, LivenessActivity.class);
startActivityForResult(intent, REQUEST_CODE_LIVENESS);
}
@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
if (requestCode == REQUEST_CODE_LIVENESS) {
if (LivenessResult.isSuccess()) {
String livenessId = LivenessResult.getLivenessId();
Bitmap livenessBitmap = LivenessResult.getLivenessBitmap();
} else {
String errorCode = LivenessResult.getErrorCode();
String errorMsg = LivenessResult.getErrorMsg();
...
}
}
}
- 动作顺序说明
默认的动作顺序是 [眨眼]->[摇头],如需自定义动作顺序请参考如下代码:
在启动LivenessActivity页面前调用如下方法:
GuardianLivenessDetectionSDK.setActionSequence(true,Detector.DetectionType.POS_YAW, Detector.DetectionType.MOUTH, Detector.DetectionType.BLINK);
- 用户绑定(强烈建议)。
您可以通过该方法将自己的用户唯一标识传给我们,我们会根据该标识建立映射关系。当遇到问题时,方便同我们进行日志追踪。
GuardianLivenessDetectionSDK.bindUser(String userId)
- 开启遮挡检测
遮挡检测默认是关闭状态,如需开启遮挡检测,请在初始化SDK之后调用如下方法设置
GuardianLivenessDetectionSDK.isDetectOcclusion(true)
- liveness 模块的代码可以自行修改来满足定制化需求。
目前 SDK 支持中文,英文,印尼文,越南语,泰国语,印地语,西班牙语 七种语言/语音。根据手机当前语言自动切换,无需代码设置,如您仅支持一种语言,可自行删除其余国家的资源文件。
错误码 | 解释 |
---|
FACE_MISSING | 检测过程中人脸丢失 | ACTION_TIMEOUT | 动作超时 | MULTIPLE_FACE | 检测过程中出现多张人脸 | MUCH_MOTION | 检测过程中动作幅度过大 | AUTH_BAD_NETWORK | 授权请求网络失败 | CHECKING_BAD_NETWORK | 动作结束后图像上传网络请求失败 | DEVICE_NOT_SUPPORT | 该设备不支持活体检测 | USER_GIVE_UP | 用户中途放弃检测 | UNDEFINED | 未定义的其他错误类型 | AUTH_PARAMETER_ERROR | 授权请求参数错误 | AUTH_IAM_FAILED | 包名未备案 |
MainActivity 代码 (扫脸接口方法 initKeyTypeButton() ):
package ai.advance.integration.demo;
import android.Manifest;
import android.content.DialogInterface;
import android.content.Intent;
import android.content.pm.PackageManager;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.core.app.ActivityCompat;
import androidx.core.content.ContextCompat;
import androidx.appcompat.app.AlertDialog;
import androidx.appcompat.app.AppCompatActivity;
import android.os.Bundle;
import android.view.View;
import android.widget.Toast;
import ai.advance.liveness.lib.GuardianLivenessDetectionSDK;
import ai.advance.liveness.lib.LivenessResult;
import ai.advance.liveness.lib.Market;
import ai.advance.liveness.sdk.activity.LivenessActivity;
public class MainActivity extends AppCompatActivity {
static final int REQUEST_CODE_LIVENESS = 1000;
private static final int PERMISSIONS_REQUEST_CODE = 1;
@Override
protected void onCreate(@Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
initKeyTypeButton();
initTicketButton();
initLicenseButton();
}
private void initLicenseButton() {
findViewById(R.id.license_type_button).setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
String license = null;
if (license == null) {
new AlertDialog.Builder(MainActivity.this).setMessage("请在 MainActivity 中给 license 赋值").setPositiveButton("确定", null).create().show();
} else {
boolean packageNamePass = checkPackageName();
if (packageNamePass) {
GuardianLivenessDetectionSDK.init(getApplication(), Market.Indonesia);
String checkResult = GuardianLivenessDetectionSDK.setLicenseAndCheck(license);
if ("SUCCESS".equals(checkResult)) {
checkPermissions();
} else {
Toast.makeText(MainActivity.this, checkResult, Toast.LENGTH_SHORT).show();
}
}
}
}
});
}
private void initKeyTypeButton() {
findViewById(R.id.key_type_button).setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
String accessKey = "ADVANCE_ACCESS_KEY";
String secretKey = "ADVANCE_SECRET_KEY";
Market market = Market.Indonesia;
if (accessKey == null || secretKey == null || market == null) {
new AlertDialog.Builder(MainActivity.this).setMessage("请在 MainActivity 中给 Key 赋值").setPositiveButton("确定", null).create().show();
} else {
boolean packageNamePass = checkPackageName();
if (packageNamePass) {
GuardianLivenessDetectionSDK.init(getApplication(), accessKey, secretKey, market);
checkPermissions();
}
}
}
});
}
private void initTicketButton() {
findViewById(R.id.ticket_type_button).setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
String ticket = null;
String queryId = null;
if (ticket == null) {
new AlertDialog.Builder(MainActivity.this).setMessage("请在 MainActivity 中给 ticket 赋值").setPositiveButton("确定", null).create().show();
} else {
boolean packageNamePass = checkPackageName();
if (packageNamePass) {
GuardianLivenessDetectionSDK.init(getApplication(), Market.Indonesia);
GuardianLivenessDetectionSDK.setTicket(ticket);
GuardianLivenessDetectionSDK.setQueryId(queryId);
checkPermissions();
}
}
}
});
}
private boolean checkPackageName() {
if ("your.app.id".equals(getPackageName())) {
new AlertDialog.Builder(MainActivity.this).setMessage("请将 build.gradle 中的包名修改为您已备案的").setPositiveButton("确定", null).create().show();
return false;
}
return true;
}
@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
switch (requestCode) {
case REQUEST_CODE_LIVENESS:
if (LivenessResult.isSuccess()) {
Toast.makeText(this, "Success", Toast.LENGTH_SHORT).show();
} else {
Toast.makeText(this, LivenessResult.getErrorCode(), Toast.LENGTH_SHORT).show();
}
break;
}
}
private boolean allPermissionsGranted() {
for (String permission : getRequiredPermissions()) {
if (ContextCompat.checkSelfPermission(this, permission)
!= PackageManager.PERMISSION_GRANTED) {
return false;
}
}
return true;
}
public void checkPermissions() {
if (allPermissionsGranted()) {
onPermissionGranted();
} else {
ActivityCompat.requestPermissions(this, getRequiredPermissions(), PERMISSIONS_REQUEST_CODE);
}
}
public String[] getRequiredPermissions() {
return new String[]{Manifest.permission.CAMERA};
}
@Override
public void onRequestPermissionsResult(
int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {
super.onRequestPermissionsResult(requestCode, permissions, grantResults);
if (requestCode == PERMISSIONS_REQUEST_CODE) {
if (allGranted(grantResults)) {
onPermissionGranted();
} else {
onPermissionRefused();
}
}
}
public void onPermissionRefused() {
new AlertDialog.Builder(this).setMessage(getString(R.string.liveness_no_camera_permission)).setPositiveButton(getString(R.string.liveness_perform), new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
finish();
}
}).create().show();
}
private boolean allGranted(int[] grantResults) {
boolean hasPermission = true;
for (int i = 0; i < grantResults.length; i++) {
if (grantResults[i] != PackageManager.PERMISSION_GRANTED) {
hasPermission = false;
}
}
return hasPermission;
}
public void onPermissionGranted() {
Intent intent = new Intent(this, LivenessActivity.class);
startActivityForResult(intent, REQUEST_CODE_LIVENESS);
}
}
|