└── src└── main├── AndroidManifest.xml├── assets├── java└── res├── values-zh-rCN│ └── custom_strings.xml└── values-zh-rHK└── custom_strings.xml
└── src└── main├── AndroidManifest.xml├── assets├── java└── res├── values-th-rTH│ └── custom_strings.xml <<<<<<<<<<< 以泰文为例,values-th-rTH├── values-zh-rCN│ └── custom_strings.xml└── values-zh-rHK└── custom_strings.xml
EkycHyConfig ekycHyConfig = new EkycHyConfig();ekycHyConfig.setLanguageStyle(LanguageStyle.CUSTOMIZE_LANGUAGE);ekycHyConfig.setLanguageCode("th-TH");
语言码 | 对应使用的国家或地区 |
af-ZA | 通用荷兰语 - 南非 |
sq-AL | 阿尔巴尼亚语 - 阿尔巴尼亚 |
ar-DZ | 阿拉伯语 - 阿尔及利亚 |
ar-BH | 阿拉伯语 - 巴林 |
ar-EG | 阿拉伯语 - 埃及 |
ar-IQ | 阿拉伯语 - 伊拉克 |
ar-JO | 阿拉伯语 - 约旦 |
ar-KW | 阿拉伯语 - 科威特 |
ar-LB | 阿拉伯语 - 黎巴嫩 |
ar-LY | 阿拉伯语 - 利比亚 |
ar-MA | 阿拉伯语 - 摩洛哥 |
ar-OM | 阿拉伯语 - 阿曼 |
ar-QA | 阿拉伯语 - 卡塔尔 |
eu-ES | 巴斯克语 - 巴斯克 |
be-BY | Belarusian - 白俄罗斯 |
bg-BG | 保加利亚语 - 保加利亚 |
ca-ES | 加泰罗尼亚语 - 加泰罗尼亚 |
zh-HK | 中文 - 中国香港 |
zh-MO | 中文 - 中国澳门 |
zh-CN | 中文 - 中国 |
zh-SG | 中文 - 新加坡 |
zh-TW | 中文 - 中国台湾 |
zh-CHS | 中文 (简体) |
zh-CHT | 中文 (繁体) |
hr-HR | 克罗地亚语 - 克罗地亚 |
cs-CZ | 捷克语 - 捷克 |
da-DK | 丹麦语 - 丹麦 |
div-MV | 迪维希语 - 马尔代夫 |
nl-BE | 荷兰语 - 比利时 |
nl-NL | 荷兰语 - 荷兰 |
en-AU | 英语 - 澳大利亚 |
en-CA | 英语 - 加拿大 |
en-ZA | 英语 - 南非 |
en-PH | 英语 - 菲律宾 |
en-NZ | 英语 - 新西兰 |
en-GB | 英语 - 英国 |
en-US | 英语 - 美国 |
fa-IR | 波斯语 - 伊朗 |
fi-FI | 芬兰语 - 芬兰 |
fr-FR | 法语 - 法国 |
fr-BE | 法语 - 比利时 |
fr-MC | 法语 - 摩纳哥 |
fr-CH | 法语 - 瑞士 |
gl-ES | 加利西亚 - 西班牙 |
ka-GE | 格鲁吉亚语 - 格鲁吉亚 |
de-DE | 德语 - 德国 |
de-LU | 德语 - 卢森堡 |
de-CH | 德语 - 瑞士 |
el-GR | 希腊语 - 希腊 |
gu-IN | Gujarati - 印度 |
he-IL | 希伯来 - 以色列 |
hi-IN | 北印度语 - 印度 |
hu-HU | 匈牙利语 - 匈牙利 |
is-IS | 冰岛语 - 冰岛 |
it-IT | 意大利语 - 意大利 |
ja-JP | 日语 - 日本 |
kk-KZ | Kazakh - 哈萨克 |
kn-IN | 卡纳达语 - 印度 |
ko-KR | 韩语 - 韩国 |
lv-LV | 拉脱维亚语 - 拉脱维亚 |
lt-LT | 立陶宛语 - 立陶宛 |
ms-BN | 马来 - 文莱 |
ms-MY | 马来 - 马来西亚 |
mr-IN | 马拉地语 - 印度 |
mn-MN | 蒙古语 - 蒙古 |
nn-NO | 挪威 (Nynorsk)- 挪威 |
pl-PL | 波兰语 - 波兰 |
pt-BR | 葡萄牙 - 巴西 |
pt-PT | 葡萄牙 - 葡萄牙 |
ro-RO | 罗马尼亚语 - 罗马尼亚 |
sa-IN | 梵文 - 印度 |
ru-RU | 俄语 - 俄罗斯 |
sk-SK | 斯洛伐克语 - 斯洛伐克 |
es-AR | 西班牙 - 阿根廷 |
es-ES | 西班牙 - 西班牙 |
sv-SE | 瑞典语 - 瑞典 |
th-TH | 泰语 - 泰国 |
tr-TR | 土耳其语 - 土耳其 |
uk-UA | 乌克兰语 - 乌克兰 |
ur-PK | Urdu - 巴基斯坦 |
vi-VN | 越南语 - 越南 |
EkycHyConfig 中分别配置 OcrUiConfig 和 FaceAuthUiConfig,可以实现完整的 UI 定制。resources/custom_layout/ 目录下提供了两个默认布局文件作为参考模板:ocr_detect_fragment.xml:OCR 识别界面默认布局。huiyan_fragment_authing.xml:活体人脸比对页面默认布局。ocr_detect_fragment.xml 是 OCR 证件识别界面的布局模板,根布局为 RelativeLayout。android:id 均不可修改,但可以调整其位置、尺寸、颜色等属性:View ID | 类型 | 说明 |
camera_surface_view | TextureView | 摄像头预览 |
ocr_mask_view | CameraMaskView | |
ocr_tips_tv | OcrDetectTipsView | 识别提示文字,SDK 实时更新内容 |
album_image_button | ImageButton | 相册选择按钮 |
take_picture_button | ImageButton | 拍照按钮 |
light_image_button | ImageButton | 闪光灯开关按钮 |
txy_detect_back | ImageView | 默认返回按钮(默认不可见,由 SDK 控制显隐) |
setOcrEventCallBack() 的 onMainViewCreate 回调为新增控件绑定事件。ocr_mask_view 支持以下 XML 自定义属性(使用 app: 命名空间):属性 | 类型 | 说明 |
txy_mask_color | color | 遮罩背景颜色 |
txy_mask_margin | dimension | 遮罩边距,仅在 txy_position_flag="margin" 时生效 |
txy_position_flag | enum | 识别框定位模式: center(居中)/ margin(按边距定位) |
属性 | 类型 | 说明 |
txy_tip_text | string | 提示文字内容 |
txy_tip_color | color | 默认状态文字颜色 |
txy_tip_light_color | color | 高亮状态文字颜色(识别成功时) |
txy_tip_error_color | color | 错误状态文字颜色 |
txy_tip_size | dimension | 文字大小 |
txy_tip_margin | dimension | 文字与识别框的间距 |
txy_tip_show | boolean | 是否显示提示文字 |
txy_tip_textStyle | flag | 字体样式: normal / bold / italic / bold_italic |
属性 | 类型 | 说明 |
txy_bottom_tips_txt | string | 底部提示文字内容 |
txy_bottom_tip_size | dimension | 底部文字大小 |
txy_bottom_tip_color | color | 底部文字颜色 |
txy_bottom_tip_margin_top | dimension | 底部文字与识别框底边的间距 |
txy_bottom_tip_show | boolean | 是否显示底部提示文字 |
txy_bottom_tips_textStyle | flag | 字体样式: normal / bold / italic / bold_italic |
属性 | 类型 | 说明 |
txy_line_color | color | 角线默认颜色 |
txy_line_light_color | color | 识别成功时高亮颜色 |
txy_line_error_color | color | 错误状态颜色 |
txy_line_width | dimension | 角线线宽 |
txy_line_length | dimension | 角线长度 |
txy_line_padding | dimension | 角线与识别框内边缘的间距 |
txy_line_margin | dimension | 角线与屏幕边缘的间距 |
属性 | 类型 | 说明 |
txy_front_head_icon | reference | 证件正面人像区域引导图标 |
txy_front_head_scale_size | float | 人像图标缩放比例 |
txy_front_head_margin_top | dimension | 人像图标与识别框顶边的间距 |
txy_front_head_margin_right | dimension | 人像图标与识别框右边的间距 |
txy_back_emblem_icon | reference | 证件背面国徽区域引导图标 |
txy_back_emblem_scale_size | float | 国徽图标缩放比例 |
txy_back_emblem_margin_top | dimension | 国徽图标与识别框顶边的间距 |
txy_back_emblem_margin_left | dimension | 国徽图标与识别框左边的间距 |
属性 | 类型 | 说明 |
txy_maskView_view_type | flag | 证件类型样式: normal / id_front / id_back / hk_03 / hk_18 / hk_macao_pass |
txy_mask_view_use_type | flag | 布局方向: portrait(竖屏)/ landscape(横屏) |
txy_rect_height_weight_hor | integer | 横屏模式下识别框的高度比例 |
属性 | 类型 | 说明 |
txy_is_show_scanline | boolean | 是否显示扫描动效线 |
txy_scanline_animator_time | integer | 扫描线动效时长(毫秒) |
txy_scanline_start_color | color | 扫描线起始渐变色 |
txy_scanline_mid_color | color | 扫描线中间渐变色 |
txy_scanline_end_color | color | 扫描线结束渐变色 |
txy_scanline_start_color_size_range | integer | 起始颜色渐变范围 |
txy_scanline_start_to_mid_color_size_range | integer | 起始到中间颜色的过渡范围 |
OcrUiConfig重叠的配置项。OcrUiConfig 的代码配置方法存在功能重叠,当两者同时设置时,代码配置优先级更高,会覆盖 XML 属性:XML 属性 | OcrUiConfig 方法 | 说明 |
txy_line_color | setCardFrameDefaultColor() | 角线默认颜色 |
txy_line_light_color | setCardFrameColor() | 识别成功高亮颜色 |
txy_line_error_color | setWarnErrorTextColor() | 错误状态颜色 |
txy_tip_color | setDefaultTipTextColor() | 提示文字默认颜色 |
txy_tip_light_color | setSuccessRemindTextColor() | 提示文字高亮颜色 |
txy_tip_error_color | setWarnErrorTextColor() | 提示文字错误颜色 |
txy_bottom_tips_txt | setBottomTipsContext() | 底部提示文字内容 |
OcrUiConfig配置,避免两边同时设置导致预期不一致。huiyan_fragment_authing.xml 是活体人脸比对页面的布局模板,根布局为 HuiYanReflectLayout(继承自 ConstraintLayout),SDK 在此布局上叠加摄像头采集和动效逻辑。android:id 均不可修改,但可以调整其位置、尺寸、颜色等属性(不建议调整 txy_camera_gather_view,txy_auth_common_background_views 和 txy_auth_loading_front_animator_view ):View ID | 类型 | 说明 |
txy_auth_layout_bg | HuiYanReflectLayout | 根布局 |
txy_cancel_txt_btn | TextView | 取消/返回按钮,SDK 绑定点击事件用于退出活体流程 |
txy_count_down_txt_view | TextView | 倒计时文本,SDK 控制其显隐和内容 |
txy_auth_feed_back_txt | TextView | 活体检测主提示文字,SDK 实时更新内容 |
txy_camera_gather_view | CameraDateGatherView | 摄像头预览 |
txy_auth_common_background_views | CommonAuthBackView | 人脸圆环背景动效 |
txy_camera_prepare_img | ImageView | 准备阶段头像引导图 |
txy_auth_loading_front_animator_view | LoadingFrontAnimatorView | Loading 前台动效 |
txy_auth_feed_back_extra_tip_txt | TextView | 副提示文字(额外警告信息) |
txy_hud_view | HudView | 反光检测副提示视图 |
setAuthEventCallBack() 的 onMainViewCreate 回调为新增控件绑定事件。OcrUiConfig.setPortraitLayoutResId() 实现,传入自定义布局的 Resource ID:EkycHyConfig ekycHyConfig = new EkycHyConfig();OcrUiConfig ocrUiConfig = new OcrUiConfig();ocrUiConfig.setPortraitLayoutResId(R.layout.custom_ocr_layout);ekycHyConfig.setOcrUiConfig(ocrUiConfig);
android:id。建议以 ocr_detect_fragment.xml 为模板进行修改。FaceAuthUiConfig.setAuthLayoutResId() 实现,传入自定义布局的 Resource ID:EkycHyConfig ekycHyConfig = new EkycHyConfig();FaceAuthUiConfig faceAuthUiConfig = new FaceAuthUiConfig();faceAuthUiConfig.setAuthLayoutResId(R.layout.custom_face_auth_layout);ekycHyConfig.setFaceAuthUiConfig(faceAuthUiConfig);
android:id 必须与活体人脸比对 SDK 要求的一致,这些 View 会参与界面事件绑定。建议以 huiyan_fragment_authing.xml 为模板进行修改。setAuthEventCallBack() 方法为新增的 UI 控件进行事件绑定。在活体人脸检测主界面被创建时,会回调 HuiYanAuthEventCallBack.onMainViewCreate(View) 方法,此时可以获取自定义布局中的控件并注册事件监听:EkycHySdk.setAuthEventCallBack(new HuiYanAuthEventCallBack() {@Overridepublic void onMainViewCreate(View authView) {if (authView == null) {return;}// 获取自定义布局中的控件Button customButton = authView.findViewById(R.id.custom_button_id);if (customButton != null) {customButton.setOnClickListener(v -> {// 处理自定义按钮点击事件Log.d(TAG, "Custom button clicked");});}}@Overridepublic void onMainViewDestroy() {// 界面销毁时的清理工作Log.d(TAG, "Auth view destroyed");}});
huiyan_fragment_authing.xml 为基础,将原来独立的 txy_cancel_txt_btn 放入导航栏容器内,并添加标题文字。注意 txy_cancel_txt_btn 的 ID 必须保留,SDK 会自动为其绑定退出活体流程的点击事件。<!-- 自定义导航栏容器,可自由设置背景色、高度 --><FrameLayoutandroid:id="@+id/custom_nav_bar"android:layout_width="match_parent"android:layout_height="56dp"android:background="#2196F3"app:layout_constraintTop_toTopOf="parent"app:layout_constraintStart_toStartOf="parent"app:layout_constraintEnd_toEndOf="parent"><!-- 返回按钮:ID 必须为 txy_cancel_txt_btn,SDK 负责绑定退出事件 --><TextViewandroid:id="@+id/txy_cancel_txt_btn"android:layout_width="24dp"android:layout_height="24dp"android:layout_gravity="center_vertical|start"android:layout_marginStart="15dp"android:background="@drawable/ic_arrow_left" /><!-- 自定义标题,ID 自定义,需在 onMainViewCreate 中更新文字 --><TextViewandroid:id="@+id/custom_nav_title"android:layout_width="wrap_content"android:layout_height="wrap_content"android:layout_gravity="center"android:text="Face Verification"android:textColor="@android:color/white"android:textSize="18sp" /></FrameLayout>
FaceAuthUiConfig faceAuthUiConfig = new FaceAuthUiConfig();faceAuthUiConfig.setAuthLayoutResId(R.layout.custom_face_auth_layout);faceAuthUiConfig.setStatusBarColor(color); // 设置状态栏背景颜色,一般和自定义导航栏的背景一致EkycHyConfig ekycHyConfig = new EkycHyConfig();ekycHyConfig.setFaceAuthUiConfig(faceAuthUiConfig);
setOcrCloudEventListener 是 Token 模式下新增的 OCR 采集事件监听接口,允许调用方拦截 SDK 内部的各类弹窗和 UI 事件,实现完全自定义的 UI 交互。// 在 startEkycCheck() 之前注册EkycHySdk.setOcrCloudEventListener(listener);// 取消注册传 nullEkycHySdk.setOcrCloudEventListener(null);
true 表示调用方自行处理(SDK 不展示默认 UI),返回 false 则 SDK 展示默认弹窗。所有弹窗回调都是 default 方法,默认返回 false,可按需覆写。// 1. 注册事件监听器(在 startEkycCheck 之前)EkycHySdk.setOcrCloudEventListener(new IOcrCloudEventListener() {@Overridepublic void onMainViewCreate(View mainView) {// SDK OCR 识别页面主 View 创建,可在此添加自定义浮层}@Overridepublic void onMainViewDestroy() {// 界面销毁,清理资源}@Overridepublic void onEventParamMap(HashMap<String, Object> map) {// 接收 SDK 透传的额外参数}@Overridepublic boolean onShowCloudErrorDialog(HashMap<String, Object> info,View parentView,Runnable retryBlock,Runnable exitBlock) {// info 包含: "title"(String), "message"(String), "errorCode"(Integer,可能不存在)String title = (String) info.get("title");String message = (String) info.get("message");new AlertDialog.Builder(parentView.getContext()).setTitle(title).setMessage(message)// retryBlock 为 null 时表示不可重试.setPositiveButton(retryBlock != null ? "重试" : null,retryBlock != null ? (d, w) -> retryBlock.run() : null).setNegativeButton("退出", (d, w) -> exitBlock.run()).setCancelable(false).show();return true; // 自行处理,SDK 不展示默认弹窗}@Overridepublic boolean onShowBestFrameConfirmDialog(HashMap<String, Object> info,View parentView,ImageView imageView,Runnable confirmBlock,Runnable cancelBlock) {// imageView 已设好最佳帧图片,直接添加到布局中展示LinearLayout layout = new LinearLayout(parentView.getContext());layout.setOrientation(LinearLayout.VERTICAL);layout.setPadding(32, 32, 32, 0);imageView.setLayoutParams(new LinearLayout.LayoutParams(LinearLayout.LayoutParams.MATCH_PARENT, 400));imageView.setScaleType(ImageView.ScaleType.FIT_CENTER);layout.addView(imageView);new AlertDialog.Builder(parentView.getContext()).setTitle("最佳帧确认").setView(layout).setPositiveButton("确认使用", (d, w) -> confirmBlock.run()).setNegativeButton("重新拍摄", (d, w) -> cancelBlock.run()).setCancelable(false).show();return true;}@Overridepublic boolean onShowCameraPermissionDialog(HashMap<String, Object> info,View parentView,Runnable settingsBlock,Runnable cancelBlock) {// settingsBlock: 跳转系统设置页 cancelBlock: 取消退出String title = (String) info.get("title");String message = (String) info.get("message");new AlertDialog.Builder(parentView.getContext()).setTitle(title).setMessage(message).setPositiveButton("前往设置", (d, w) -> settingsBlock.run()).setNegativeButton("取消", (d, w) -> cancelBlock.run()).setCancelable(false).show();return true;}@Overridepublic boolean onShowNextSideDialog(HashMap<String, Object> info,View parentView,Runnable confirmBlock) {// 双面证件翻面提示String title = (String) info.get("title");String message = (String) info.get("message");new AlertDialog.Builder(parentView.getContext()).setTitle(title).setMessage(message).setPositiveButton("确认翻面", (d, w) -> confirmBlock.run()).setCancelable(false).show();return true;}@Overridepublic boolean onShowChangeModeDialog(HashMap<String, Object> info,View parentView,Runnable confirmBlock,Runnable cancelBlock) {// 自动模式超时,提示切换手动拍照String title = (String) info.get("title");String message = (String) info.get("message");new AlertDialog.Builder(parentView.getContext()).setTitle(title).setMessage(message).setPositiveButton("切换手动", (d, w) -> confirmBlock.run()).setNegativeButton("继续等待", (d, w) -> cancelBlock.run()).setCancelable(false).show();return true;}private ProgressDialog progressDialog;@Overridepublic boolean onShowUploadLoading(View parentView) {// 自定义上传 loading,与 onHideUploadLoading 成对使用progressDialog = new ProgressDialog(parentView.getContext());progressDialog.setMessage("正在上传识别中...");progressDialog.setCancelable(false);progressDialog.show();return true; // 拦截 SDK 默认 loading}@Overridepublic void onHideUploadLoading() {// 上传流程结束(成功、失败或重试)时回调,在此隐藏自定义 loadingif (progressDialog != null && progressDialog.isShowing()) {progressDialog.dismiss();progressDialog = null;}}});// 2. 启动 eKYC 流程EkycHySdk.startEkycCheck(activity, ekycToken, serverParamInfo, ekycHyConfig, ekycHyCallBack);
startEkycCheck() 之前注册监听器。onShowCloudErrorDialog 中 retryBlock 为 null 表示不可重试,调用方无需展示重试按钮。onShowUploadLoading 返回 true 时,SDK 会在上传流程结束(成功、失败或重试)时回调 onHideUploadLoading(),调用方应在此隐藏自定义 loading。若 onShowUploadLoading 返回 false(使用 SDK 默认 loading),则不会触发 onHideUploadLoading。文档反馈