Android调用takePicture时报ImageCaptureException: Camera is closed异常求助
偶发ImageCaptureException: Camera is closed 问题修复方案
根因说明
- 该问题在Nokia 6.1 Plus Android 10机型上高频出现,源于该机型相机HAL层的实现兼容问题,低版本Jetpack CameraX的相机生命周期与拍照请求异步不同步的bug会进一步放大异常概率
- 未做拍照前状态校验:页面生命周期切换、其他应用临时抢占相机资源时,用户发起拍照请求会直接触发相机已关闭异常
- 无错误降级逻辑:异常触发后没有自动恢复相机能力的逻辑,导致用户无法继续操作
修复步骤
1. 升级CameraX依赖至稳定版
将项目内所有CameraX相关依赖升级到1.3.0及以上稳定版本,规避框架层已知的生命周期同步bug:
implementation "androidx.camera:camera-core:1.3.0" implementation "androidx.camera:camera-camera2:1.3.0" implementation "androidx.camera:camera-lifecycle:1.3.0" implementation "androidx.camera:camera-view:1.3.0"
2. 新增拍照前状态校验与防抖逻辑
新增两个全局变量标记相机状态和上次点击时间,调用takePicture前先做状态校验,避免无效请求:
// 全局变量 private boolean isCameraActive = false; private long lastTakePictureTime = 0L; // 相机用例绑定成功后设置 isCameraActive = true; // 拍照点击事件逻辑 takePictureBtn.setOnClickListener(v -> { // 300ms防抖,避免重复点击 if (System.currentTimeMillis() - lastTakePictureTime < 300) { return; } // 校验相机活跃状态 if (!isCameraActive || imageCapture == null) { Toast.makeText(getContext(), "相机初始化中,请稍后重试", Toast.LENGTH_SHORT).show(); return; } lastTakePictureTime = System.currentTimeMillis(); // 原有拍照逻辑 startTakePicture(); });
3. 错误回调增加降级恢复逻辑
在OnImageSavedCallback的onError方法中增加异常捕获和自动恢复逻辑:
imageCapture.takePicture(outputFileOptions, ContextCompat.getMainExecutor(getContext()), new ImageCapture.OnImageSavedCallback() { @Override public void onImageSaved(ImageCapture.OutputFileResults outputFileResults) { imagePath = FileProvider.getUriForFile(getContext(), getContext().getPackageName() + ".provider", imageFile); checkImageOrientation(); } @Override public void onError(ImageCaptureException error) { if (error.getMessage().contains("Camera is closed")) { isCameraActive = false; // 解绑现有相机用例,重新初始化 if (processCameraProvider != null) { processCameraProvider.unbindAll(); // 调用原有初始化相机绑定用例的方法 initCamera(); Toast.makeText(getContext(), "拍照异常,已自动恢复相机", Toast.LENGTH_SHORT).show(); } } else { // 其他异常处理逻辑 } } });
4. 适配页面生命周期状态锁
在页面onPause回调中置灰拍照按钮并设置isCameraActive = false,onResume相机重新绑定成功后再恢复按钮可点击状态,避免生命周期切换过程中发起无效拍照请求。
内容的提问来源于stack exchange,提问作者Akash Sarkar
相关产品推荐
相关产品推荐

