
Android 端集成人脸核身 SDK,涉及依赖引入、权限声明、混淆配置和接口调用几个环节。本文按实际集成顺序,给出完整的代码示例,把每一步的要点讲清楚。
集成前建议确认工程的最低支持版本,避免运行时报兼容问题。
从腾讯云慧眼 SDK 下载链接获取 SDK 包,包含以下 aar 文件:
├── HuiyanPublicEnhancedSDK-release-4.x.x.x.aar # 主 SDK
├── HuiYan-Secret4lib-1.0.1-release.aar # 国密库
├── tencent-ai-sdk-aicamera-2.0.1-release.aar # 摄像头组件
├── tencent-ai-sdk-common-2.0.1.1-release.aar # 公共组件
├── tencent-ai-sdk-network-2.0.1.3-release.aar # 网络组件
├── tencent-ai-sdk-youtu-base-1.0.1.44-release.aar # 优图基础库
├── huiyanmodels_1.0.2_release.aar # 模型库
└── huiyanaudios_1.0.2_release.aar # 语音播放组件(可选)(具体版本号以 SDK 交付件为准)
将 aar 文件放到 module 下的 libs 目录(注意不是工程根目录下的 libs):
├── app/ # 你的 module
│ ├── libs/
│ │ ├── HuiyanPublicEnhancedSDK-release-4.x.x.x.aar
│ │ ├── HuiYan-Secret4lib-1.0.1-release.aar
│ │ ├── tencent-ai-sdk-aicamera-2.0.1-release.aar
│ │ ├── tencent-ai-sdk-common-2.0.1.1-release.aar
│ │ ├── tencent-ai-sdk-network-2.0.1.3-release.aar
│ │ ├── tencent-ai-sdk-youtu-base-1.0.1.44-release.aar
│ │ └── huiyanmodels_1.0.2_release.aar
│ └── src/将申请到的 License 文件 YTFaceSDK.license 放入 app/src/main/assets/ 目录:
├── app/
│ └── src/
│ └── main/
│ ├── assets/
│ │ └── YTFaceSDK.license # 需要主动申请
│ ├── java/
│ └── res/注意:License 文件需要主动向腾讯云客服申请,不会随 SDK 自动下发。
在 module 的 build.gradle 中添加依赖:
dependencies {
// 慧眼主 SDK
implementation files("libs/HuiyanPublicEnhancedSDK-release-4.x.x.x.aar")
// 国密库
implementation files("libs/HuiYan-Secret4lib-1.0.1-release.aar")
// 慧眼基础组件库
implementation files("libs/tencent-ai-sdk-aicamera-2.0.1-release.aar")
implementation files("libs/tencent-ai-sdk-common-2.0.1.1-release.aar")
implementation files("libs/tencent-ai-sdk-network-2.0.1.3-release.aar")
implementation files("libs/tencent-ai-sdk-youtu-base-1.0.1.44-release.aar")
// 慧眼模型库
implementation files("libs/huiyanmodels_1.0.2_release.aar")
// 语音播放资源组件(可选)
implementation files("libs/huiyanaudios_1.0.2_release.aar")
// Java 8 支持
compileOptions {
sourceCompatibility JavaVersion.VERSION_1_8
targetCompatibility JavaVersion.VERSION_1_8
}
}如果提示 invoke-custom are only supported starting with Android O (--min-api 26) 错误,需要确保上面的 compileOptions 配置正确。
在 AndroidManifest.xml 中添加权限声明:
<!-- 摄像头权限(必需) -->
<uses-permission android:name="android.permission.CAMERA" />
<uses-feature
android:name="android.hardware.camera"
android:required="true" />
<!-- 网络权限(必需) -->
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
<!-- 读取手机状态(可选,用于风控) -->
<uses-permission android:name="android.permission.READ_PHONE_STATE" />对于 Android 6.0(API 23)及以上版本,除了声明权限外,还需要在运行时动态申请:
public class FaceVerifyActivity extends AppCompatActivity {
private static final int REQUEST_CAMERA_PERMISSION = 1001;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
checkAndRequestPermission();
}
private void checkAndRequestPermission() {
if (ContextCompat.checkSelfPermission(this, Manifest.permission.CAMERA)
!= PackageManager.PERMISSION_GRANTED) {
ActivityCompat.requestPermissions(
this,
new String[]{Manifest.permission.CAMERA},
REQUEST_CAMERA_PERMISSION
);
} else {
// 权限已授予,可以初始化 SDK
initSDK();
}
}
@Override
public void onRequestPermissionsResult(int requestCode, String[] permissions,
int[] grantResults) {
super.onRequestPermissionsResult(requestCode, permissions, grantResults);
if (requestCode == REQUEST_CAMERA_PERMISSION) {
if (grantResults.length > 0 && grantResults[0] == PackageManager.PERMISSION_GRANTED) {
initSDK();
} else {
Toast.makeText(this, "需要摄像头权限才能完成人脸核身", Toast.LENGTH_SHORT).show();
}
}
}
}如果开启了代码混淆,在 proguard-rules.pro 中添加以下 keep 规则:
# 慧眼模块
-keep class com.tencent.cloud.huiyan.** {*;}
-keep class com.tencent.youtu.** {*;}
# 安全模块
-keep class com.tencent.turingcam.** {*;}
-keep class com.tencent.turingfd.** {*;}
-keep class com.tencent.turingface.** {*;}
-keep class com.tenpay.utils.** {*;}
# 公共组件库
-keep class com.tencent.cloud.aicamare.** {*;}
-keep class com.tencent.cloud.component.** {*;}
-keep class com.tencent.cloud.ai.network.** {*;}
# 如果使用 AndResGuard 资源混淆,还需添加:
# for HuiYanSDK
"R.string.ocr_*",
"R.string.rst_*",
"R.string.net_*",
"R.string.msg_*",
"R.string.fl_*",在 Application 中调用初始化(确保在用户同意隐私政策之后):
public class MyApp extends Application {
@Override
public void onCreate() {
super.onCreate();
instance = this;
// 确保用户已同意隐私政策后再初始化
if (hasUserAgreedPrivacyPolicy()) {
HuiYanAuth.init(getApp());
}
}
private boolean hasUserAgreedPrivacyPolicy() {
// 检查用户是否已同意隐私政策
return true;
}
}public class FaceVerifyActivity extends AppCompatActivity {
private String token; // 从服务端获取的 SdkToken
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
// 从服务端获取 Token 后启动核身
getFaceIdTokenFromServer();
}
private void getFaceIdTokenFromServer() {
// 请求服务端获取 SdkToken
Request request = new Request.Builder()
.url("https://your-domain.com/api/getFaceIdToken")
.post(RequestBody.create(null, ""))
.build();
// 使用 OkHttp 或其他网络库
client.newCall(request).enqueue(new Callback() {
@Override
public void onResponse(Call call, Response response) {
try {
JSONObject json = new JSONObject(response.body().string());
token = json.getString("FaceIdToken");
runOnUiThread(() -> startFaceVerify());
} catch (Exception e) {
e.printStackTrace();
}
}
@Override
public void onFailure(Call call, IOException e) {
runOnUiThread(() -> {
Toast.makeText(FaceVerifyActivity.this,
"网络请求失败", Toast.LENGTH_SHORT).show();
});
}
});
}
private void startFaceVerify() {
// 构造配置信息
AuthConfig authConfig = new AuthConfig();
// 设置 License 文件名(存放在 assets 目录下)
authConfig.setAuthLicense("YTFaceSDK.license");
// 设置从服务端获取的 SdkToken
authConfig.setSdkToken(token);
// 启动活体核身
HuiYanAuth.startHuiYanAuth(authConfig, new HuiYanAuthResultListener() {
@Override
public void onSuccess(String faceIdToken) {
// 核身成功,faceIdToken 用于服务端拉取结果
Log.i("FaceVerify", "认证成功, faceIdToken: " + faceIdToken);
verifyResult(faceIdToken);
}
@Override
public void onFail(int errorCode, String errorMsg, String faceIdToken) {
// 核身失败
Log.e("FaceVerify",
"认证失败, code: " + errorCode +
", msg: " + errorMsg +
", faceIdToken: " + faceIdToken);
handleVerifyError(errorCode, errorMsg);
}
});
}
private void verifyResult(String faceIdToken) {
// 通知服务端拉取最终结果
// 服务端调用 GetFaceIdResult 接口
}
private void handleVerifyError(int code, String msg) {
String userMsg;
switch (code) {
case -1:
userMsg = "网络异常,请重试";
break;
case -2:
userMsg = "摄像头未开启";
break;
default:
userMsg = "验证失败:" + msg;
}
Toast.makeText(this, userMsg, Toast.LENGTH_SHORT).show();
}
@Override
protected void onDestroy() {
super.onDestroy();
// 释放 SDK 资源
HuiYanAuth.release();
}
}客户端回调中的 faceIdToken 本身不代表核身结论,正确的做法是:
faceIdToken 传给业务服务端GetFaceIdResult 接口拉取最终结果服务端拉取结果示例(Python):
def get_face_id_result(face_id_token):
from tencentcloud.common import credential
from tencentcloud.faceid.v20180301 import faceid_client, models
cred = credential.Credential("SecretId", "SecretKey")
client = faceid_client.FaceidClient(cred, "ap-guangzhou")
req = models.GetFaceIdResultRequest()
req.FaceIdToken = face_id_token
resp = client.GetFaceIdResult(req)
return {
'success': resp.Result and resp.Result.ErrCode == 0,
'description': resp.Result.Desc if resp.Result else None
}这样做的好处是结论由服务端把关,客户端无法伪造。
在页面或应用退出时,调用 SDK 提供的释放方法:
@Override
protected void onDestroy() {
super.onDestroy();
// 主动资源释放
HuiYanAuth.release();
}如果终端用户撤销了对个人信息处理的授权,也应及时调用释放接口。
原因:Java 版本不兼容。
解决方案:在 build.gradle 中添加:
compileOptions {
sourceCompatibility JavaVersion.VERSION_1_8
targetCompatibility JavaVersion.VERSION_1_8
}原因:资源被混淆。
解决方案:在混淆配置中保留 SDK 相关的资源名称:
"R.string.ocr_*",
"R.string.rst_*",
"R.string.net_*",
"R.string.msg_*",
"R.string.fl_*",排查步骤:
原因:License 文件路径配置错误。
解决方案:
authConfig.setAuthLicense() 设置的文件名是否正确assets 目录腾讯云慧眼人脸核身提供 Android 端腾讯云慧眼 SDK 接入方式,并配套集成文档与示例工程。该系列产品正在限时特惠活动中,低至3.3折:https://cloud.tencent.com/act/pro/happynewyears
原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。
如有侵权,请联系 cloudcommunity@tencent.com 删除。