You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Compose中CameraX的takePicture()在SDK 29下无返回问题求助

Compose中CameraX在SDK 29下takePicture()无返回的问题

我在Compose中用CameraX实现了预览和拍照功能,最近收到不少SDK 29版本用户反馈无法拍照。在SDK 29模拟器上调试发现,takePicture()方法始终不返回。代码里没发现明显错误,谷歌搜索也没找到有效思路,想问有没有开发者遇到过相同问题或者有解决建议?

代码实现

val localContext = LocalContext.current
val lifecycleOwner = LocalLifecycleOwner.current

val cameraProviderFuture = remember {
    ProcessCameraProvider.getInstance(localContext)
}

val cam = remember { mutableStateOf<Camera?>(null) }
val imageCapture = remember { mutableStateOf<ImageCapture?>(null) }

Box(modifier = modifier) {
    AndroidView(
        factory = { context ->
            val previewView = PreviewView(context)
            val preview = Preview.Builder().build()
            val selector = CameraSelector.Builder()
                .requireLensFacing(CameraSelector.LENS_FACING_BACK)
                .build()
            preview.setSurfaceProvider(previewView.surfaceProvider)

            imageCapture.value = ImageCapture.Builder().build()

            cam.value = cameraProviderFuture.get().bindToLifecycle(
                lifecycleOwner,
                selector,
                preview,
                imageCapture.value
            )

            previewView
        },
        modifier = Modifier.fillMaxSize()
    )

    DisposableEffect(lifecycleOwner) {
        onDispose {
            cameraProviderFuture.get().unbindAll()
        }
    }

    LaunchedEffect(key1 = targetFile) {
        targetFile?.let {
            val outputFileOptions = ImageCapture.OutputFileOptions
                .Builder(targetFile)
                .build()
            imageCapture.value?.takePicture(   // 在SDK 29上无返回
                outputFileOptions,
                Executors.newSingleThreadExecutor(),
                object : ImageCapture.OnImageSavedCallback {
                    override fun onImageSaved(outputFileResults: ImageCapture.OutputFileResults) {
                        onPictureTakenClicked()
                    }

                    override fun onError(exception: ImageCaptureException) {
                    }
                }
            )
        }
    }
}

Manifest配置

<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.CAMERA" />

<uses-feature android:name="android.hardware.camera" android:required="true" />

Gradle依赖

implementation "androidx.camera:camera-camera2:1.3.0-alpha07"
implementation "androidx.camera:camera-lifecycle:1.3.0-alpha07"
implementation "androidx.camera:camera-video:1.3.0-alpha07"
implementation "androidx.camera:camera-view:1.3.0-alpha07"

更新说明

我尝试将图片保存至内部存储,代码如下:

val file = File(context.filesDir, System.currentTimeMillis().toString())
file.createNewFile()

可能的解决方向

  • 补全权限与文件操作异常处理:SDK 29对外部存储访问有严格限制,即使切换到内部存储,createNewFile()可能抛出IO异常,需添加try-catch捕获,避免异常导致流程静默卡住。
  • 替换回调线程:当前使用Executors.newSingleThreadExecutor()可能在SDK 29出现线程阻塞,建议改用ContextCompat.getMainExecutor(localContext)或CameraX推荐的线程池。
  • 升级CameraX版本:1.3.0-alpha07是测试版,存在兼容性bug概率高,建议升级到最新稳定版(如1.4.0),官方通常会修复旧版本的适配问题。
  • 明确ImageCapture配置:给ImageCapture.Builder()添加具体参数,比如设置捕获模式、目标分辨率,避免默认配置在SDK 29上不兼容:
    imageCapture.value = ImageCapture.Builder()
        .setCaptureMode(ImageCapture.CAPTURE_MODE_MINIMIZE_LATENCY)
        .setTargetResolution(Size(1920, 1080))
        .build()
    
  • 完善错误日志:给onError方法添加日志打印,比如Log.e("CameraX", "拍照失败: ${exception.message}", exception),方便定位具体异常原因。

内容的提问来源于stack exchange,提问作者IIIIIIIIIIIIIIIIIIIIII

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.18 15:15:44