Android开发:人脸采集后LivenessActivity重复弹出问题解决
解决人脸采集后LivenessActivity重复弹出的问题
看起来你遇到的核心问题是页面启动逻辑的循环触发,结合你的代码,我帮你梳理两个关键问题点,以及对应的修复方案:
问题1:UploadActivity启动LivenessActivity的时机错误
在你的UploadActivity的onCreate方法中,你直接在初始化阶段就触发了LivenessActivity的启动逻辑:
if (fileUri != null) //call LivenessActivity startActivity(new Intent(UploadActivity.this, LivenessActivity.class));
这里的问题在于:当你从LivenessActivity返回时,UploadActivity会重新执行onCreate(因为你在LivenessActivity里启动了新的UploadActivity实例),这就导致每次回到UploadActivity就立刻再次打开LivenessActivity,形成死循环。
修复方案:
- 把启动LivenessActivity的逻辑移到身份证采集完成后的点击事件里(也就是
btnCapturePicture的点击回调中),只有用户完成身份证采集并点击确定后,才会启动人脸采集页面。 - 改用
startActivityForResult(AndroidX可以用registerForActivityResult)启动LivenessActivity,这样能在人脸采集完成后接收返回结果,而不是创建新的UploadActivity实例。
修改后的UploadActivity按钮点击代码:
// 先定义请求码常量 private static final int REQUEST_CODE_LIVENESS = 1001; btnCapturePicture.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { captureImage(); // 身份证采集完成后,启动人脸活体采集页面 startActivityForResult(new Intent(UploadActivity.this, LivenessActivity.class), REQUEST_CODE_LIVENESS); } });
然后在UploadActivity中重写onActivityResult接收人脸数据:
// 定义成员变量存储人脸数据 private byte[] mFaceData; @Override protected void onActivityResult(int requestCode, int resultCode, @Nullable Intent data) { super.onActivityResult(requestCode, resultCode, data); if (requestCode == REQUEST_CODE_LIVENESS && resultCode == RESULT_OK && data != null) { // 接收人脸数据,保存到成员变量 mFaceData = data.getByteArrayExtra("image_best"); } }
问题2:LivenessActivity没有正确关闭,反而启动了新的UploadActivity
在你的LivenessActivity的onDetectionSuccess方法中,你启动了一个新的UploadActivity实例,却没有关闭当前的LivenessActivity:
Intent intent = new Intent(LivenessActivity.this, UploadActivity.class); intent.putExtra("image_best",face); setResult(PAGE_INTO_LIVENESS, intent); startActivity(intent);
这会导致旧的LivenessActivity留在栈中,加上UploadActivity的错误启动逻辑,进一步加剧循环。
修复方案:
- 不需要调用
startActivity(intent),设置返回结果后直接调用finish()关闭当前LivenessActivity,这样就能回到之前的UploadActivity实例,而不是创建新的。
修改后的LivenessActivity的onDetectionSuccess方法:
@Override public Detector.DetectionType onDetectionSuccess(DetectionFrame validFrame) { FaceIDDataStruct dataStruct = mDetector.getFaceIDDataStruct(); byte[] face = null; if (dataStruct != null) { face = dataStruct.images.get("image_best"); } // 兜底使用validFrame的数据 if (face == null) { face = validFrame.getCroppedFaceImageData(); } // 设置返回结果,关闭当前页面 Intent intent = new Intent(); intent.putExtra("image_best", face); setResult(RESULT_OK, intent); finish(); // 关键:关闭当前LivenessActivity,返回上一个页面 return DetectionType.DONE; }
额外优化:VIEWFACE按钮的逻辑调整
原来的VIEWFACE按钮从getIntent().getExtras()获取数据,但现在数据是从onActivityResult接收的,所以要改成读取成员变量:
btnviewface.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View view) { if (mFaceData == null) { Toast.makeText(UploadActivity.this, "请先完成人脸采集", Toast.LENGTH_SHORT).show(); return; } // 保存图片到本地(记得关闭流) try { Config.IMAGE_FACE = "/storage/emulated/0/Pictures/Android File Upload/IMG_face.jpg"; FileOutputStream stream = new FileOutputStream(Config.IMAGE_FACE); stream.write(mFaceData); stream.close(); } catch (FileNotFoundException e) { e.printStackTrace(); } catch (IOException e) { e.printStackTrace(); } // 显示人脸图片 Bitmap bmp = BitmapFactory.decodeByteArray(mFaceData, 0, mFaceData.length); imgFace.setImageBitmap(bmp); previewMedia(isImage); new UploadFileToServer(Config.IMAGE_DOC, Config.IMAGE_FACE).execute(); } });
修改后流程就会恢复正常:
- 用户在UploadActivity采集身份证,点击确定
- 启动LivenessActivity进行人脸活体采集
- 完成眨眼动作后,LivenessActivity自动关闭,返回UploadActivity
- 点击VIEWFACE按钮,显示人脸图像并执行上传
内容的提问来源于stack exchange,提问作者ann.kdr
相关产品推荐
相关产品推荐

