提供的相机选择器无法解析给定用例的相机

问题描述 投票:0回答:4

我在构图时使用相机拍照。相机预览代码^

@Composable
fun CameraPreview(
    modifier: Modifier = Modifier,
    scaleType: PreviewView.ScaleType = PreviewView.ScaleType.FILL_CENTER,
    onUseCase: (UseCase) -> Unit = { }
) {
    AndroidView(
        modifier = modifier,
        factory = { context ->
            val previewView = PreviewView(context).apply {
                this.scaleType = scaleType
                layoutParams = ViewGroup.LayoutParams(
                    ViewGroup.LayoutParams.MATCH_PARENT,
                    ViewGroup.LayoutParams.MATCH_PARENT
                )
            }
            onUseCase(
                Preview.Builder()
                .build()
                .also {
                    it.setSurfaceProvider(previewView.surfaceProvider)
                }
            )
            previewView
        }
    )
}

拍照密码

@Composable
fun CameraCapture(
    modifier: Modifier = Modifier,
    cameraSelector: CameraSelector = CameraSelector.DEFAULT_FRONT_CAMERA,
    onPhotoCreated: (Bitmap, String) -> Unit = { bitmap, string ->  bitmap; string},
    onClose: () -> Unit,
    onFullScreen: (Boolean) -> Unit = {},
    systemUiController: SystemUiController = rememberSystemUiController()
) {
    var isFullScreen by remember { mutableStateOf(true) }

    onFullScreen(isFullScreen)
    WindowCutoutMode(isFullScreen = isFullScreen)
    SystemBarColor(
        systemUiController = systemUiController,
        specialStatusColor = Color.Transparent
    )

    Box(modifier = modifier) {
        val context = LocalContext.current
        val lifecycleOwner = LocalLifecycleOwner.current
        var previewUseCase by remember { mutableStateOf<UseCase>(Preview.Builder().build()) }

        CameraPreview(
            modifier = Modifier.fillMaxSize(),
            onUseCase = {
                previewUseCase = it
            }
        )

        var newSelector by remember { mutableStateOf(cameraSelector) }

        val cameraProviderFuture = ProcessCameraProvider.getInstance(context)
        val cameraProvider = cameraProviderFuture.get()

        val cameraExecutor: ExecutorService = Executors.newSingleThreadExecutor()

        val imageCaptureUseCase by remember {
            mutableStateOf(
                ImageCapture.Builder()
                    .setCaptureMode(CAPTURE_MODE_MAXIMIZE_QUALITY)
                    .build()
            )
        }
        val coroutineScope = rememberCoroutineScope()

        Box(
            modifier = Modifier
                .align(Alignment.TopStart)
                .padding(top = 48.dp, start = 16.dp)
                .clip(CircleShape)
                .background(Colors.Background.transparent)
        ) {
            Icon(
                imageVector = Icons.Rounded.Close,
                contentDescription = null,
                modifier = Modifier
                    .clickable(
                        role = Role.Button
                    ) {
                      isFullScreen = false
                      onClose()
                    },
            )
        }

        Row(
            modifier = Modifier
                .fillMaxWidth()
                .background(Colors.Background.light)
                .align(Alignment.BottomCenter),
            horizontalArrangement = Arrangement.SpaceBetween,
            verticalAlignment = Alignment.CenterVertically
        ) {
            GalleryImagePicker(onPhotoCreated)

            Box(
                modifier = Modifier
                    .size(100.dp)
                    .padding(16.dp)
                    .clip(CircleShape)
                    .background(Color.White),
            ) {
                Box(
                    modifier = Modifier
                        .size(80.dp)
                        .padding(5.dp)
                        .clickable(
                            role = Role.Button
                        ) {
                            coroutineScope.launch(Dispatchers.IO) {
                                val imageFile = imageCaptureUseCase.takePicture(cameraExecutor)
                                onPhotoCreated(rotateByOrientation(imageFile), imageFile.name)
                            }
                        }
                        .clip(CircleShape)
                        .background(Color.Black),
                ) {

                }
            }

            Box(
                modifier = Modifier
                    .size(80.dp)
                    .padding(16.dp)
                    .clip(CircleShape)
                    .background(Color.White),
            ) {
                Box(
                    modifier = Modifier
                        .size(60.dp)
                        .padding(5.dp)
                        .clip(CircleShape)
                        .background(Color.Black),
                ) {
                    Icon(
                        imageVector = ImageVector.vectorResource(id = R.drawable.ic_camera_change),
                        contentDescription = "",
                        tint = Color.White,
                        modifier = Modifier
                            .align(Alignment.Center)
                            .clickable(
                                role = Role.Button
                            ) {
                                newSelector =
                                    if (newSelector == CameraSelector.DEFAULT_FRONT_CAMERA)
                                        CameraSelector.DEFAULT_BACK_CAMERA
                                    else
                                        CameraSelector.DEFAULT_FRONT_CAMERA
                            }
                    )
                }
            }
        }

        LaunchedEffect(newSelector) {
            try {
                cameraProvider.unbindAll()
                cameraProvider.bindToLifecycle(
                    lifecycleOwner,
                    newSelector,
                    previewUseCase,
                    imageCaptureUseCase
                )
            } catch (ex: Exception) {
                Log.e("CameraCapture", "Failed to bind camera use cases", ex)
            }
        }
    }
}

代码一直运行良好,但突然(本周)它开始引发异常,例如

java.lang.IllegalArgumentException: Provided camera selector unable to resolve a camera for the given use case
,带有消息无法绑定相机用例。当视图打开时,它只有黑屏。代码没有改变,我看不到错误。

版本:

"androidx.camera:camera-core:1.0.1""
"androidx.camera:camera-camera2:1.0.1""
"androidx.camera:camera-lifecycle:1.0.1""
"androidx.camera:camera-view:1.1.0-beta02"
"androidx.camera:camera-extensions:1.1.0-beta02"

更新

日志中的更多异常:

Camera LensFacing verification failed, existing cameras: []
CameraValidator$CameraIdListIncorrectException: Expected camera missing from device.

更新2

设备重新启动后异常消失,但预览是黑屏,并且每秒都会发送垃圾邮件日志消息,例如

D/Camera2CameraImpl: {Camera@739281d[id=1]} 转换相机内部状态:OPENED --> CLOSING

android android-camera android-jetpack-compose
4个回答
2
投票

我在模拟器上遇到了类似的问题,为了解决它,我需要将设备的显示高级设置下的虚拟设备配置(AVD)中的相机设置从

Virtual Scene
更改为
Emulated
在后置摄像头上。


0
投票

必须重新授予许可。

编辑:您是否确保目前没有其他应用程序正在使用相机?如果内部状态为 OPENED,则可能与使用该资源的另一个源发生冲突。


0
投票

当我遵循以下教程时,我遇到了同样的错误

使用带有 Jetpack Compose 的相机拍照

我能够通过改变来解决它

来自

val lensFacing = CameraSelector.LENS_FACING_BACK

val lensFacing = CameraSelector.LENS_FACING_FRONT

因此,如果您想使用前置后置摄像头,这就是区别。

就我而言,我只有一个前置摄像头

现在,来到上面的代码,我可以看到您使用具有 CameraSelector.DEFAULT_BACK_CAMERACameraSelector.DEFAULT_FRONT_CAMERAnewSelector 提供 LaunchedEffect

但是,正如我之前所说,CameraSelector.LENS_FACING_FRONT对我有用,所以我认为你需要将它们都更改为

 if (newSelector == CameraSelector.LENS_FACING_BACK)
     CameraSelector.LENS_FACING_BACK
 else
     CameraSelector.LENS_FACING_BACK

0
投票

就我而言,这是因为我同时请求前置和后置摄像头,而我的设备没有两个摄像头。

val cameraSelector: CameraSelector = CameraSelector.Builder()
    .requireLensFacing(CameraSelector.LENS_FACING_BACK)
    .requireLensFacing(CameraSelector.LENS_FACING_FRONT)
    .build()

修复非常简单,只需在分配之前检查相机是否可用即可

requireLensFacing
:

val cameraSelector: CameraSelector = CameraSelector.Builder()
    .apply {
        if (cameraProvider.hasCamera(CameraSelector.DEFAULT_BACK_CAMERA)) {
            requireLensFacing(CameraSelector.LENS_FACING_BACK)
        } else if (cameraProvider.hasCamera(CameraSelector.DEFAULT_FRONT_CAMERA)) {
            requireLensFacing(CameraSelector.LENS_FACING_FRONT)
        } else {
            throw IllegalArgumentException("No available cameras on the device")
        }
    }
    .build()
© www.soinside.com 2019 - 2024. All rights reserved.