Android CameraX拍照后onImageSaved回调不触发问题求助
问题根因
ImageCapture.takePicture()是异步执行方法,你在调用拍照接口后立刻执行finish()销毁了当前Activity,此时拍照、文件写入流程尚未执行完成,Activity销毁后回调自然无法触发,同时文件写入被中断,导致你拿到的Uri对应的是空文件。
修复方案
把返回结果、关闭Activity的逻辑移动到OnImageSavedCallback的回调内部,确保拍照流程执行完成后再结束页面,修改后的代码如下:
private fun takePhoto(){ // 获取可修改的图片捕获用例的稳定引用 val imageCapture = imageCapture ?: return // 创建带时间戳的输出文件用于存储图片 val directory: File = applicationContext.getDir("imageDir", Context.MODE_PRIVATE) val photoFile = File(directory, "JPEG_${System.currentTimeMillis()}.jpg") // 创建包含文件和元数据的输出配置对象 val outputOptions = ImageCapture.OutputFileOptions.Builder(photoFile).build() // 转换文件路径为Uri val imageUri = Uri.fromFile(photoFile) // 设置图片捕获监听器,拍照完成后触发 imageCapture.takePicture( outputOptions, ContextCompat.getMainExecutor(this), object : ImageCapture.OnImageSavedCallback { override fun onError(exc: ImageCaptureException) { Log.e(TAG, "拍照失败: ${exc.message}", exc) // 出错时也返回结果关闭页面,可根据需求自定义返回码 val intent = Intent() intent.putExtra("error", exc.message) setResult(RESULT_CANCELED, intent) finish() } override fun onImageSaved(output: ImageCapture.OutputFileResults) { val msg = "拍照成功: $imageUri" Toast.makeText(baseContext, msg, Toast.LENGTH_SHORT).show() Log.d(TAG, msg) // 拍照保存成功后再返回结果关闭页面 val intent = Intent() intent.putExtra("ImageUri", imageUri) setResult(2, intent) finish() } }) // 移除原调用takePicture后立刻执行的finish相关逻辑 }
附加排查项
如果修改后问题仍存在,可检查以下配置:
- 确认
imageCapture实例初始化时配置的捕获模式,高画质模式CAPTURE_MODE_MAXIMIZE_QUALITY写入文件耗时更长,更要保证页面不会提前销毁 - 确认CameraX依赖为稳定正式版,推荐版本≥1.3.0,避免版本bug导致回调失效
- 拍照触发前不要提前销毁
Preview预览用例,部分机型会因预览停止导致拍照流程被中断
内容的提问来源于stack exchange,提问作者Ben Jackson
相关产品推荐
相关产品推荐

