请先参照开通服务页流程获得身份认证服务授权,再下载SDK包进行使用。
源码:
若无火山引擎销售人员与您对接,请点击此处申请试用,咨询问题请注明为身份认证。
repositories { flatDir{ dirs 'libs' } } dependencies { //本地依赖 implementation(name:'BytedCertSdk-release', ext:'aar') //远程依赖 implementation 'androidx.constraintlayout:constraintlayout:2.1.4' implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk7:1.3.10" implementation 'com.android.support:appcompat-v7:28.0.0' implementation 'com.squareup.okhttp3:okhttp:3.4.1' implementation 'com.amazonaws:aws-android-sdk-s3:2.12.7' }
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" /> <uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE"/> <uses-permission android:name="android.permission.CAMERA" /> <uses-permission android:name="android.permission.READ_PHONE_STATE" />
-keepattributes Signature -keepattributes Exceptions,InnerClasses -keep class ms.bz.bd.**{ *; } -keep class com.bytedance.** {*;} -keep class com.volcengine.mobsecBiz.**{ *; } -keep class kotlinx.coroutines.** {*;} # security sdk for com.volcengine.bizssdk:ml:7.0.1.mlBusiness -keepattributes Signature -keepattributes Exceptions,InnerClasses -keep class ms.bz.bd.**{ *; } -keep class com.volcengine.mobsecBiz.**{ *; } -keepnames class com.bytedance.applog.** #amazonaws s3 -keepnames class com.amazonaws.** -keepnames class com.amazon.** # Enums are not obfuscated correctly in combination with Gson -keepclassmembers enum * { *; } # Request handlers defined in request.handlers -keep class com.amazonaws.services.**.*Handler # The following are referenced but aren't required to run -dontwarn com.fasterxml.jackson.** -dontwarn org.apache.http.** # The SDK has several references of Apache HTTP client -dontwarn com.amazonaws.http.** -dontwarn com.amazonaws.metrics.**
本 Android SDK 基于 Java8 构建,支持的 minSDK 版本为 API 21。对于 minSDK 版本低于 API 26(不包括26)的 Android 应用,需额外进行如下设置才能正常运行
android { compileOptions { sourceCompatibility JavaVersion.VERSION_1_8 targetCompatibility JavaVersion.VERSION_1_8 } }
setSignAccessKeySecretAccessKey()
beginAuthorizationWithParams()
startBytedToken()
,或者业务自行通过服务获取。startFaceCert//启动活体+身份认证
BytedFaceLiveManager为kotlin单例对象
/** * @return BytedFaceLiveManager对象 */ //Java类中使用 BytedFaceLiveManager.INSTANCE;
/** * @param context: Android上下文 * @param stsToken: 鉴权配置 使用临时密钥需要传入ststoken, 使用长期密钥时传null,强烈推荐使用临时密钥的方式,安全性更强 * @param accessKey: 密钥ak * @param secretAccessKey: 密钥sk * @param callback: 接口回调,返回值为dev_token(设备稳定标识) * @return void * 默认使用正常采集模式进行风控数据采集,如需修改采集模版可以使用下面的方法设置securityMode参数实现。 */ public void setSignAccessKeySecretAccessKey(Context appContext, String stsToken, String accessKey, String secretAccessKey, SDKCallBack.StringResultCallback callback)
/** * @param context: Android上下文 * @param stsToken: 鉴权配置 使用临时密钥需要传入ststoken, 使用长期密钥时传null,强烈推荐使用临时密钥的方式,安全性更强 * @param accessKey: 密钥ak * @param secretAccessKey: 密钥sk * @param securityMode: 风控数据采集模版/可选字段开关。MODE_DEFAULT:正常模式,MODE_MINIMIZE:基础模式。基础模版不采集可选字段(不会采集BSSID、IMEI、MEID、Mac地址、MSIN/IMSI),风控识别能力低,建议使用DEFAULT模式。 * @param callback: 接口回调,返回值为dev_token(设备稳定标识) * @return void */ public void setSignAccessKeySecretAccessKey(Context appContext, String stsToken, String accessKey, String secretAccessKey,int securityMode SDKCallBack.StringResultCallback callback)
请求服务端接口时需要带上该参数。
/** * @return SecurityInfo 风控配置信息 */ public SecurityInfo getSecurityInfo()
Example:
BytedFaceLiveManager.getInstance().getSecurityInfo().getSecurityToken();
/** * @param tosInfo: tos配置,可空,当传空时,默认使用服务端端配置。 * @param callback: 视频上传callback, 注意:返回非主线程 * @return void */ public void configRecordeAndUploadParams(BytedCertTosInfo tosInfo, SDKCallBack.UploadVideoCallback callback)
Example:
BytedCertTosInfo bytedTosInfo = BytedCertTosInfo.createTosInfo("ak", "sk", "sts_token", "bucket", "tos-cn-beijing.volces.com", "cjq-test.tos-cn-beijing.volces.com"); BytedFaceLiveManager.getInstance().configRecordeAndUploadParams(bytedTosInfo, new SDKCallBack.UploadVideoCallback() { @Override public void onUploadFinsh(String bytedToken, final int errorCode, final String errorMsg, final String filePath) { bytedCertManager.executeInMainThread(new Runnable() { @Override public void run() { mUploadLog.setVisibility(View.VISIBLE); if (errorCode == 0) { mUploadLog.setText("上传视频成功:" + filePath); FileUtils.deleteFileByPath(filePath); }else { mUploadLog.setText(String.format("上传视频失败(%d): %s", errorCode, errorMsg)); } } }); } });
/** * @param context: Android上下文 * @param ocrCallback: ocr识别结果回调,详细参数见2.2 SDKCallBack.OcrCallback介绍 * @return void */ public void doOCRH5(Context context, SDKCallBack.OcrCallback ocrCallback)
Example:
BytedFaceLiveManager.getInstance().doOCRH5(mContext, new SDKCallBack.OcrCallback(){ @Override public void onOcrFinish(final int errorCode, final String errorMsg, final String identityCode, final String identityName) { runOnUiThread(new Runnable() { @Override public void run() { if (errorCode == 0) { Toast.makeText(mContext, "ocr识别成功, 姓名:" + identityName, Toast.LENGTH_SHORT).show(); } else { Toast.makeText(mContext, "ocr识别失败, " + errorMsg, Toast.LENGTH_SHORT).show(); } } }); } });
/** * @param refSource: true为有源比对,false为无源比对 * @param params: 活体配置参数,具体取值见3.params 活体配置参数介绍 * @param callback: 返回token结果的callback,详细参数见2.4 SDKCallBack.BytedTokenCallback介绍 * @return void */ public void startBytedToken(boolean refSource, Map<String, String> params, SDKCallBack.BytedTokenCallback callback)
Example:
//无源比对 HashMap<String, String> params = new HashMap<>(); params.put("risk_motion_list", ""risk_motion_list":{"free":["0","1","2","3"],"low":["0","1","2","3"], "medium":["0","1","2","3"],"high":["0","1","2","3"]}"); params.put("risk_motion_count", ""risk_motion_count":"free":2,"low":2,"medium":3,"high":4}"); params.put("liveness_timeout", 10); params.put("risk_fixed_motion_list", ""risk_fixed_motion_list":{"free":["0","1","2","3"],"low":["0","1","2","3"], "medium":["0","1","2","3"],"high":["0","1","2","3"]}"); params.put("max_liveness_trial", mMaxLivenessTrial); BytedFaceLiveManager.getInstance().startBytedToken(false, params, new SDKCallBack.BytedTokenCallback() { @Override public void onBytedTokenFinish(int errorCode, String errorMsg, String bytedToken, String clientConfig) { if (errorCode == 0 && !bytedToken.isEmpty() && !clientConfig.isEmpty()) { mBytedToken = bytedToken; mClientConfig = clientConfig } } });
/** * 认证相关配置 * @param needVerify: 是否需要进行后续服务的有源/无源比对,默认为true。 * @param refSource: true为有源比对,false为无源比对 * @param textSpeech: 文本播报功能 默认值为false,表示不进行语音播报。 */ class CertConfig( boolean needVerify, boolean refSource, boolean textSpeech ) /** * @param context: Android上下文 * @param certConfig: 认证相关配置 * @param bytedToken: 通过1.5的startBytedToken接口获取,或者通过服务端中TokenPro中获取。一般使用后者方式获取。 * @param clientConfig: 从startBytedToken获取,同时也可以使用服务端中TokenPro中返回的clientConfig * @param callback: 返回token结果的callback,详细参数见2.3 SDKCallBack.ResultCallback介绍 * @return void */ public void startFaceCert(Context context, CertConfig certConfig, String byteToken, String clientConfig, SDKCallBack.ResultCallback callback)
Example:
//有源比对 BytedFaceLiveManager.getInstance().startFaceCert(NativeFLN.this, new CertConfig(true, true, false), bytedToken, clientConfig, new SDKCallBack.ResultCallback(){ @Override public void onResultFinish(int errorCode, String errorMsg, JSONObject jsonData) { if (loadingDialog != null) { loadingDialog.dismiss(); } if (errorCode == 0) { Toast.makeText(mContext, "活体成功", Toast.LENGTH_SHORT).show(); } else { Toast.makeText(mContext, "活体失败:" + errorMsg, Toast.LENGTH_SHORT).show(); } } });
/** * 认证相关配置 * @param needVerify: 是否需要进行后续服务的有源/无源比对。 * @param refSource: true为有源比对,false为无源比对。 * @param textSpeech: 文本播报功能 默认值为false,表示不进行语音播报。 */ class CertConfig( boolean needVerify, boolean refSource, boolean textSpeech) /** * @param context: Android上下文 * @param certConfig: 认证相关配置 * @param params: 活体配置参数,具体取值见3.params 活体配置参数介绍介绍 * @param callback: 返回token结果的callback,详细参数见2.3 SDKCallBack.ResultCallback介绍 * @return void */ public void beginAuthorizationWithParams(Context context, CertConfig certConfig, Map<String, String> params, SDKCallBack.ResultCallback callback)
Example:
HashMap<String, String> params = new HashMap<>(); params.put("risk_motion_list", ""risk_motion_list":{"free":["0","1","2","3"],"low":["0","1","2","3"], "medium":["0","1","2","3"],"high":["0","1","2","3"]}"); params.put("risk_motion_count", ""risk_motion_count":"free":2,"low":2,"medium":3,"high":4}"); params.put("liveness_timeout", 10); params.put("risk_fixed_motion_list", ""risk_fixed_motion_list":{"free":["0","1","2","3"],"low":["0","1","2","3"], "medium":["0","1","2","3"],"high":["0","1","2","3"]}"); params.put("max_liveness_trial", mMaxLivenessTrial); BytedFaceLiveManager.getInstance().beginAuthorizationWithParams(WelcomeActivity.this, true, params, new SDKCallBack.ResultCallback(){ @Override public void onResultFinish(int errorCode, String errorMsg, JSONObject jsonData) { if (errorCode == 0) { Toast.makeText(mContext, "活体成功", Toast.LENGTH_SHORT).show(); } else { Toast.makeText(mContext, "活体成功失败:" + errorMsg, Toast.LENGTH_SHORT).show(); } } });
/** * onUploadFinsh参数 * @param bytedToken: 视频对应的bytedToken * @param errorCode: 错误码, 成功的话为0 * @param errorMsg: 错误信息 成功的话为"" * @param filePath: 录制的视频路径 失败的话为"" */ interface UploadVideoCallback { void onUploadFinsh(String bytedToken, int errorCode, String errorMsg, String filePath); }
/** * onOcrFinish参数 * @param errorCode 错误码 * @param errorMsg 错误信息 * @param identityCode 身份证id * @paramd entityName 姓名 */ interface OcrCallback { void onOcrFinish(int errorCode, String errorMsg, String identityCode, String identityName); }
返回数据jsonData的数据格式参考身份认证sdk返回内容说明
interface ResultCallback { //errorCode, 错误码 //errorMsg, 错误信息 //jsonData, 返回数据, 详细数据格式参考人脸核身服务端api的返回字段中的"resp_data" void onResultFinish(int errorCode, String errorMsg, JSONObject jsonData); }
/** * onResultFinish参数 * @param errorCode 错误码 * @param errorMsg 错误信息 * @param bytedToken, 返回的bytenToken值 * @paramd client_config 客户端配置,原样传给startFaceCert即可 */ interface BytedTokenCallback { void onResultFinish(int errorCode, String errorMsg, String bytedToken, String client_config); }
key | 说明 | 默认值 |
---|---|---|
idcard_name | 身份证名称, 有源比对需要传 | |
idcard_no | 身份证id,有源比对为需要传 | |
risk_liveness_type | 风险等级对应的活体类型,取值有 | "risk_liveness_type":{ "free":"motion", //无风险,动作活体 "low":"motion", //低风险, 动作活体 "medium":"motion",//中风险 , 动作活体 "high":"reflection"//高风险, 动作活体 } |
risk_motion_list | 风险等级对应的下发动作列表,取值有 | "risk_motion_list":{ "free":["0","1","2","3"],//无风险,全部下发 "low":["0","1","2","3"], //低风险, 全部下发 "medium":["0","1","2","3"],//中风险 , 全部下发 "high":["0","1","2","3"]//高风险, 全部下发 } |
risk_motion_count | 风险等级对应的下发动作数量,可选范围:[1, 4] | "risk_motion_count":{ ** "free":2, //无风险,下发两个动作* ** "low":2, //低风险, 下发两个动作* ** "medium":3, //中风险 , 下发三个动作* ** "high":4,//高风险, 下发两四动作* ** }* |
risk_fixed_motion_list | 风险等级对应的固定下发动作列表,取值有 | 默认不传 |
liveness_timeout | 端上活体超时时长,可选范围: [5, 60] | 10 |
max_liveness_trial | 端上动作活体最大尝试次数, 可选范围:[1, 100] | 10 |
身份认证包含活体检测和身份认证两个步骤, 如活体检测成功, 在启动活体/启动完整认证流程接口的回调里会把活体认证相关的结果(最佳帧数据和一小段视频数据)回调到ResultCallback的resp_data(JsonObject)信息中, 具体字段结构如下:
data = { "facelive_info": { "info": 认证信息 } } "info": { "image": Base64编码数据, "video": Base64编码数据 }
活体认证信息主要返回的信息为: 1. 认证过程中的最佳图片. 2. 认证过程中的最佳视频片段.
fun handleResultData(context: Context, resp_data: JSONObject?) { GlobalScope.launch(Dispatchers.IO) { resp_data?.optJSONObject("facelive_info")?.let { faceLiveInfoJsonObject -> faceLiveInfoJsonObject.optJSONObject("info")?.let { infoJsonObject -> //处理视频数据 infoJsonObject.optString("video").takeIf { it.isNotEmpty() } ?.let { videoData -> val base64dDecodeData = Base64.decode(videoData, Base64.NO_WRAP) val targetFilePath = "${context.externalCacheDir?.absolutePath ?: context.filesDir.absolutePath}/test.mp4" writeContentToFile( base64dDecodeData, targetFilePath ) Log.d(TAG, "writeContentToFile video finish path $targetFilePath") } //处理图片数据 infoJsonObject.optString("image").takeIf { it.isNotEmpty() } ?.let { imageData -> val base64dDecodeData = Base64.decode(imageData, Base64.NO_WRAP) val targetFilePath = "${context.externalCacheDir?.absolutePath ?: context.filesDir.absolutePath}/test.jpg" writeContentToFile(base64dDecodeData, targetFilePath) Log.d(TAG, "writeContentToFile image finish path $targetFilePath") } } } } }
错误代码 | 说明 |
---|---|
0 | 成功 |
-2 | 客户端上内部错误。一般出现在集成阶段,需检查logcat运行时的日志排查问题原因。 |
-4 | 您手动退出或因识别失败次数大于4次,导致客户端默认退出。 |
-1000 | 网络异常,请稍后再试 |
-1001 | 未知错误 |
-1002 | 活体中断 |
-1003 | 活体识别失败,请再试一次 |
-1004 | 算法初始化失败 |
-1005 | 活体参数设置失败 |
-1006 | 用户取消操作 |
-1007 | 用户取消证件识别 |
-1101 | 超过活体最大次数 |
-3001 | 网络数据包解析失败 |
-3002 | 请退出多屏模式,再重试一次 |
-3003 | 无法使用相机,请检查是否打开相机权限 |
-3006 | 相册图片获取失败 |
-3007 | 拍照失败 |
-5021 | 比对失败,请确认是本人 |
50000+ | 50000以上错误码,为透传服务端的错误码,请参考人脸核身服务端api的错误码说明 |