通过阅读本文,您可以快速了解 IDRS Android SDK 本地双录的相关功能及调用方法。
创建项目工程
打开 Android Studio IDE,用 Android Studio 创建一个项目工程。
说明
Android Studio 下载地址请参见 Android Studio 下载文件归档。
引入 SDK
在 build.gradle 中添加依赖。
dependencies {
implementation ('com.mpaas.android:idrs-process:cp_change_23596.25')//本地双录能力库
implementation 'com.aliyun.openservices:aliyun-log-android-sdk:2.6.2'//日志库
implementation 'com.squareup.okhttp3:okhttp:3.11.0'//网络库
implementation 'com.squareup.okhttp3:logging-interceptor:3.5.0'//网络库
implementation "com.alibaba:fastjson:1.2.83"//json库
}
ProcessSDK 功能
初始化 ProcessSDK
初始化方法仅对 ProcessSDK 初始化所在的 activity 进行前台监听,因此为了精确地计算使用时长,您可以在 Application onCreate 中调用初始化方法。
public class ApplicationDemo extends Application {
@Override
public void onCreate() {
super.onCreate();
//****
IdrsAppLifecycle.init(this);
//****
}
}
在使用流程场景中初始化 ProcessSDK 的方法如下:
ProcessInitConfig config = new ProcessInitConfig();
config.processId = processId;
/**
* 此处以把 AccessKey 和 AccessKeySecret 保存在环境变量为例说明。您也可以根据业务需要,保存到配置文件里
* 强烈建议不要把 AccessKey 和 AccessKeySecret 保存到代码里,会存在密钥泄漏风险
*/
String appId = intent.getConfigStringExtra("appid"); // appId,在控制台申请的,和包名绑定
String ak = intent.getConfigStringExtra("securityAK");
String sk = intent.getConfigStringExtra("securitySK");
config.appId = appId;
config.ak = ak;
config.sk = sk;
config.uid = "test123"; // 账户系统的uid
config.fileDir = getExternalCacheDir().getAbsolutePath(); // 可选,用于指定缓存目录
File file = new File(config.fileDir);
if (!file.exists()) {
file.mkdirs();
}
ProcessSdk.getInstance().init(RecorderActivity.this, config, new ProcessSdkCallback())
开启摄像头
MPCameraView cameraView = mProcessSdk.startCamera(this, new InitCallback() {
@Override
public void initSuccess(int i, int i1) {
LogUtils.getInstance().debug(TAG, "startCamera success");
}
});
// 添加到布局中
cameraParent.addView(mMPCameraView, new LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.MATCH_PARENT));
切换摄像头
mProcessSdk.switchCamera();
开始流程
mProcessSdk.startFlow();
开始下一个检测项
mProcessSdk.startNextDetection();
上一章
mProcessSdk.executePrePhases();
重新检测当前项
mProcessSdk.repeatCurrentDetection();
重新播放当前章节
mProcessSdk.retryCurrenPhases();
暂停/恢复播放
mProcessSdk.flowPause();//播放暂停
mProcessSdk.flowResume();//恢复播放
清空默认路径下的视频及 meta/result 文件
mProcessSdk.clearCache();
销毁
请及时使用销毁、否则可能会影响下次初始化。
mProcessSdk.release();
ProcessSDK 回调
// 流程拉取回调,用于更新流程中的配置信息,包括名称、角色等
@Override
public String onEditFlowJson(String json) {
Log.i(TAG, "json: " + json);
try {
JSONObject jsonObject = new JSONObject(json);
JSONObject dataObject = jsonObject.optJSONObject("Data");
if (dataObject != null) {
String contentStr = dataObject.optString("Content");
if (contentStr != null) {
JSONObject contentJsonO = new JSONObject(contentStr);
JSONArray roleJsonArray = contentJsonO.optJSONArray("roles");
if (roleJsonArray != null) {
int size = roleJsonArray.length();
for (int index = size - 1; index >= 0; index--) {
roleJsonArray.remove(index);
}
List<RoleBean> roleBeanList = MainActivity.rolesCache;
for (RoleBean roleBean : roleBeanList) {
JSONObject roleItem = new JSONObject();
roleItem.put("id", roleBean.id);
roleItem.put("photo", roleBean.base64);
roleJsonArray.put(roleItem);
}
}
JSONArray phasesJsonArray = contentJsonO.optJSONArray("phases");
if (phasesJsonArray != null) {
for (int index = 0; index < phasesJsonArray.length(); index++) {
JSONObject itemJson = phasesJsonArray.optJSONObject(index);
if (itemJson != null) {
JSONObject voiceJson = itemJson.optJSONObject("voice");
if (voiceJson != null) {
JSONObject ttsJSON = voiceJson.optJSONObject("tts");
if (ttsJSON != null) {
String ttsText = ttsJSON.optString("ttsText");
if (!TextUtils.isEmpty(ttsText)) {
// 示例,根据后台实际配置
ttsText = ttsText.replaceAll("#twoName#", "");
ttsText = ttsText.replaceAll("#oneName#",
"");
ttsJSON.put("ttsText", ttsText);
}
}
}
}
}
}
dataObject.put("Content", contentJsonO.toString());
}
}
return jsonObject.toString();
} catch (Exception e) {
}
return null;
}
// 检测结果回调
@Override
public void onDetectionFail(AllDataBean.PhasesBean.DetectionsBean currenDetection) {
Log.d("mmm", currenDetection.getId() + "/" + "超时");
setSkipVISIBLE();
switch (currenDetection.getId()) {
case "id_card_recognize":
setCompleteViewError("识别身份证超时");
break;
case "sign_action_recognize":
setCompleteViewError("识别签字动作超时");
break;
case "sign_classify_recognize":
setCompleteViewError("识别手写签名超时");
break;
case "speech_word_detect":
setCompleteViewError("识别激活词超时");
break;
}
}
// 章节完成
@Override
public void onPhaseCompleted(AllDataBean.PhasesBean currenPhases) {
Log.d("mmm", currenPhases.getId() + "/" + "章节完成");
}
// 章节开始
@Override
public void onPhaseStarted(final AllDataBean.PhasesBean currenPhases) {
setCompleteViewINVISIBLE();
clearSurface();
setSkipINVISIBLE();
runOnUiThread(new Runnable() {
@Override
public void run() {
text.setText(currenPhases.getVoice().tts.ttsText);
}
});
}
// 整体流程完成
@Override
public void onFlowCompleted(List<UploadFileBean> allResultFiles) {
Log.d("mmm", "最后一个阶段");
runOnUiThread(new Runnable() {
@Override
public void run() {
mLoadingView.setVisibility(View.GONE);
findViewById(R.id.reupload).setVisibility(View.GONE);
finishFlow();
Toast.makeText(RecorderActivity.this, "流程结束", Toast.LENGTH_SHORT).show();
finish();
}
});
}
// 错误回调,错误码如下:
@Override
public void onError(final int code, final String msg) {
LogUtils.getInstance().debug("mmmerror", "error: " + code + " " + msg);
runOnUiThread(new Runnable() {
@Override
public void run() {
mLoadingView.setVisibility(View.GONE);
if (code == ProcessSdk.ERROR_TYPE_UPLOAD) { // 结果上传失败
findViewById(R.id.reupload).setVisibility(View.VISIBLE);
} else if (code == ProcessSdk.ERROR_TYPE_IDRS // idrs初始化失败
|| code == ProcessSdk.ERROR_TYPE_PROCESS_CONTENT // 流程内容获取失败
|| code == ProcessSdk.ERROR_TYPE_RECORD_ERROR) { // 录制失败
disableAllBtn();
}
errorTextV.setText(errorTextV.getText() + "\n 错误:" + code + " " + msg);
}
});
}
// 结果上传开始
@Override
public void onUploadStart() {
runOnUiThread(new Runnable() {
@Override
public void run() {
mLoadingView.setVisibility(View.VISIBLE);
errorTextV.setText(errorTextV.getText() + "\n 开始上传");
}
});
}
// 音频文件下载回调
@Override
public void onAudioDownloadProcess(final int process, final int index, final int size) {
runOnUiThread(new Runnable() {
@Override
public void run() {
if (mDownloadBeforeText == null) {
mDownloadBeforeText = errorTextV.getText().toString();
}
errorTextV.setText(mDownloadBeforeText + "\n音频下载进度:" + process + "% " + (index + 1) + "/" + size);
}
});
}
// 检测成功回调
@Override
public boolean onDetectionSuccess(AllDataBean.PhasesBean.DetectionsBean currenDetection, final String result) {
Log.d("mmm检测结果", currenDetection.getId() + "/" + result);
switch (currenDetection.getId()) {
case "id_card_recognize":
setCompleteView(result);
break;
case "sign_action_recognize":
setCompleteView("识别手写签字");
break;
case "sign_classify_recognize":
setCompleteView("识别手写签名");
break;
case "speech_word_detect":
setCompleteView(result);
break;
case "static_hand_recognize":
if (!TextUtils.isEmpty(result)) {
if (result.contains("5")) {
runOnUiThread(new Runnable() {
@Override
public void run() {
errorTextV.setText(errorTextV.getText() + "\n 手势结果:" + result);
clearSurface();
}
});
return true;
}
}
break;
}
return false;
}
// 开始检测回调
@Override
public void onStartDetection(AllDataBean.PhasesBean.DetectionsBean currenDetection) {
// Log.d("mmm开始检测", currenDetection.getId());
setCompleteViewINVISIBLE();
setSkipINVISIBLE();
setErrorINVISIBLE();
clearSurface();
mCurrenDetection = currenDetection;
runOnUiThread(new Runnable() {
@Override
public void run() {
if (mCurrenDetection != null) {
errorTextV.setText(errorTextV.getText() + "\n 开始检测:" + mCurrenDetection.getId());
}
}
});
}
// 手势实时结果
@Override
public void onHandDetectUi(ArrayList<HandDetectionResult> results, int angle, int degree, boolean isstatic) {
if (results != null) {
Facemanager.getInstance().drawLines(results, angle, degree, isstatic);
}
}
// 人脸实时结果
@Override
public void onFaceDetectUi(DectetResult[] dectetResults) {
Facemanager.getInstance().drawRect(dectetResults);
}
// 人脸实时结果
@Override
public void onFaceRecognizeUi(ArrayList<DectetResult> dectetResults) {
Facemanager.getInstance().drawResult(dectetResults, angle, degree, isAlive);
}
// 活体实时结果
@Override
public void onFaceLiveStatusChange(boolean isError, String message) {
Log.d("mmmcahgnge", isError + "/" + message);
isAlive = !isError;
}
@Override
public void onFaceNumChange(boolean isError, String message) {
Log.d("mmmcahgnge", isError + "/" + message);
//if (isError) {
// setErrorVISIBLE(message);
//} else {
// setErrorINVISIBLE();
//}
}
// tts识别过程回调
@Override
public void onTTSProcess(final String text, final int curIndex, final String currentText) {
runOnUiThread(new Runnable() {
@Override
public void run() {
int index = curIndex;
LogUtils.getInstance().debug(TAG, "ttsprocess: " + index);
String textAll = text;
if (!TextUtils.isEmpty(textAll)) {
SpannableString spannableString = new SpannableString(textAll);
if (index >= textAll.length() - 1) {
index = textAll.length();
}
spannableString.setSpan(new ForegroundColorSpan(Color.RED), 0, index, Spannable.SPAN_INCLUSIVE_INCLUSIVE);
if (index < textAll.length() - 1) {
spannableString.setSpan(new ForegroundColorSpan(Color.WHITE), index + 1,
textAll.length(), Spannable.SPAN_INCLUSIVE_EXCLUSIVE);
}
LogUtils.getInstance().debug(TAG, "ttsprocess: " + index + " " + spannableString.toString());
RecorderActivity.this.text.setText(spannableString);
}
}
});
}
// idrs sdk初始化成功回调
@Override
public void onInitSuccess() {
runOnUiThread(new Runnable() {
@Override
public void run() {
errorTextV.setText(errorTextV.getText() + "\n 初始化成功");
}
});
}
混淆配置
ProcessSDK 中的混淆配置如下:
-dontoptimize
-keep class com.mpaas.idrs.** { *; }
-keep class com.mpaas.idrs.process.** { *; }
## alinn
-keep class com.taobao.android.alinn.** { *; }
-keep class com.taobao.android.alinnkit.net.**{*;}
-keep class com.taobao.android.alinnkit.core.**{*;}
-keep class com.taobao.android.alinnkit.entity.**{*;}
-keep class com.taobao.android.alinnkit.json.**{*;}
## ocr
-keep class com.ant.phone.xmedia.**{*;}
-keep class com.alipay.xmedia.cache.**{*;}
-keep class com.alipay.xmedia.common.**{*;}
-keep class com.alipay.xmedia.gles.**{*;}
-keep class com.alipay.xmedia.serviceapi.**{*;}
-keep class com.alipay.xmedia.video.**{*;}
## 激活词
-keep class com.alibaba.idst.nui.**{*;}
-keep class com.aliyun.sls.android.producer.* { *; }
-keep interface com.aliyun.sls.android.producer.* { *; }
-keep class com.mpaas.idrs.** { *;}
## alinn
-keep class com.taobao.** { *; }
## ocr
-keep class com.ant.phone.xmedia.**{*;}
-keep class com.alipay.xmedia.**{*;}
-keep class com.mpaas.ocr.** {*;}
-keep class com.mpaas.**{*;}
-keep class com.alibaba.** {*;}
-keep class okhttp3.** {*;}
-keep class xnn.** {*;}
-ignorewarnings
文档内容是否对您有帮助?