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

如何在Android多摄像头设备中获取指定摄像头ID

多摄像头设备指定摄像头ID选择方案

你的代码当前遍历所有后置摄像头,但每次循环都会覆盖cameraId变量,最终只保留最后一个遍历到的摄像头ID——而超广角摄像头通常是遍历顺序的最后一个,所以才会只拿到它。要精准选择目标摄像头,可通过摄像头的硬件特性来筛选,以下是两种实用方法:

方法1:按等效焦距筛选

不同类型的摄像头等效焦距不同:主摄一般在24mm左右,超广角约16mm,长焦则在50mm以上。通过CameraCharacteristics.LENS_INFO_AVAILABLE_FOCAL_LENGTHS获取焦距,匹配目标即可:

private fun setupCamera(targetFocalLength: Float) {
    val cameraIds: Array<String> = cameraManager.cameraIdList

    for (id in cameraIds) {
        val cameraCharacteristics = cameraManager.getCameraCharacteristics(id)
        // 跳过前置摄像头
        if (cameraCharacteristics.get(CameraCharacteristics.LENS_FACING) == CameraCharacteristics.LENS_FACING_FRONT) {
            continue
        }
        // 获取该摄像头的可用焦距数组
        val focalLengths = cameraCharacteristics.get(CameraCharacteristics.LENS_INFO_AVAILABLE_FOCAL_LENGTHS)
        focalLengths?.let {
            // 允许微小误差,适配硬件参数偏差
            if (it.any { fl -> Math.abs(fl - targetFocalLength) < 0.1f }) {
                val streamConfigurationMap = cameraCharacteristics.get(CameraCharacteristics.SCALER_STREAM_CONFIGURATION_MAP)
                streamConfigurationMap?.let { scm ->
                    previewSize = scm.getOutputSizes(ImageFormat.JPEG).maxByOrNull { it.height * it.width }!!
                    imageReader = ImageReader.newInstance(
                        previewSize.width, previewSize.height, ImageFormat.JPEG, 1
                    )
                    initPreview()
                    imageReader.setOnImageAvailableListener(onImageAvailableListener, backgroundHandler)
                    cameraId = id
                    // 找到目标后直接跳出循环,避免被后续摄像头覆盖
                    return@setupCamera
                }
            }
        }
    }
}

调用示例:选主摄传24.0f,选超广角传16.0f。不确定参数的话,可先打印所有摄像头的焦距值确认。

方法2:按摄像头能力标识筛选

部分设备会通过CameraCharacteristics.REQUEST_AVAILABLE_CAPABILITIES标记摄像头类型,直接匹配对应标识即可:

private fun setupCamera(targetCapability: Int) {
    val cameraIds: Array<String> = cameraManager.cameraIdList

    for (id in cameraIds) {
        val cameraCharacteristics = cameraManager.getCameraCharacteristics(id)
        if (cameraCharacteristics.get(CameraCharacteristics.LENS_FACING) == CameraCharacteristics.LENS_FACING_FRONT) {
            continue
        }
        val capabilities = cameraCharacteristics.get(CameraCharacteristics.REQUEST_AVAILABLE_CAPABILITIES)
        capabilities?.let {
            if (it.contains(targetCapability)) {
                val streamConfigurationMap = cameraCharacteristics.get(CameraCharacteristics.SCALER_STREAM_CONFIGURATION_MAP)
                streamConfigurationMap?.let { scm ->
                    previewSize = scm.getOutputSizes(ImageFormat.JPEG).maxByOrNull { it.height * it.width }!!
                    imageReader = ImageReader.newInstance(
                        previewSize.width, previewSize.height, ImageFormat.JPEG, 1
                    )
                    initPreview()
                    imageReader.setOnImageAvailableListener(onImageAvailableListener, backgroundHandler)
                    cameraId = id
                    return@setupCamera
                }
            }
        }
    }
}

常用能力标识:

  • CameraCharacteristics.REQUEST_AVAILABLE_CAPABILITIES_BACKWARD_COMPATIBLE:主摄
  • CameraCharacteristics.REQUEST_AVAILABLE_CAPABILITIES_WIDE_ANGLE:超广角
  • CameraCharacteristics.REQUEST_AVAILABLE_CAPABILITIES_TELEPHOTO:长焦

调用示例:选主摄就传入CameraCharacteristics.REQUEST_AVAILABLE_CAPABILITIES_BACKWARD_COMPATIBLE。

核心修正点

你原来的代码没有在找到目标摄像头后终止循环,导致后续遍历的摄像头会覆盖之前的cameraId——这是只拿到超广角的核心原因。现在的代码在匹配到目标后立即return@setupCamera,确保只保留选中的摄像头ID。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.12 11:01:59