Camera2设置SENSOR_SENSITIVITY等参数不生效且报错求助
问题分析与修复方案
一、触发报错的直接原因
重复添加同一个Surface到捕获会话
代码中创建CameraCaptureSession时传入了listOf(imageReader.surface, imageReader!!.surface),同一个Surface被重复添加,会导致相机会话配置逻辑异常,触发底层清理请求错误。
修复:将列表改为listOf(imageReader.surface)即可。会话关闭时机不合理
在onCaptureCompleted回调中直接调用session.close(),此时相机可能仍在处理后续资源清理操作,强制关闭会引发报错。建议不要在此处立即关闭会话,可根据业务逻辑延迟关闭或交由外部生命周期管理。
二、SENSOR_SENSITIVITY和SENSOR_EXPOSURE_TIME不生效的问题
参数值超出设备支持范围
- 你设置的
SENSOR_EXPOSURE_TIME为10000000000纳秒(10秒),绝大多数安卓设备的最大曝光时间远低于该值(通常在几百毫秒到几秒区间),超出范围的参数会被硬件自动忽略。 SENSOR_SENSITIVITY(ISO)设为2000,部分设备可能不支持这么高的数值,需先确认设备支持范围。
修复:通过CameraCharacteristics获取设备合法参数范围后再设置:
val characteristics = cameraManager.getCameraCharacteristics(cameraId) // 获取ISO支持范围 val isoRange = characteristics.get(CameraCharacteristics.SENSOR_INFO_SENSITIVITY_RANGE)!! val validIso = 2000.coerceIn(isoRange.lower, isoRange.upper) // 获取曝光时间支持范围(单位:纳秒) val exposureRange = characteristics.get(CameraCharacteristics.SENSOR_INFO_EXPOSURE_TIME_RANGE)!! val validExposure = 10000000000.coerceIn(exposureRange.lower, exposureRange.upper)使用
validIso和validExposure作为最终设置值。- 你设置的
未完全关闭自动控制模式
仅设置CONTROL_AE_MODE_OFF不够,若CONTROL_MODE仍为默认自动模式,会覆盖手动设置的参数。需添加:captureRequest.set(CaptureRequest.CONTROL_MODE, CaptureRequest.CONTROL_MODE_OFF)
三、修复后的完整代码片段
cameraManager.openCamera(cameraId, object : CameraDevice.StateCallback() { override fun onOpened(camera: CameraDevice) { cameraDevice = camera // 获取相机特性,确认参数合法范围 val characteristics = cameraManager.getCameraCharacteristics(cameraId) val isoRange = characteristics.get(CameraCharacteristics.SENSOR_INFO_SENSITIVITY_RANGE)!! val exposureRange = characteristics.get(CameraCharacteristics.SENSOR_INFO_EXPOSURE_TIME_RANGE)!! val captureRequestBuilder = camera.createCaptureRequest(CameraDevice.TEMPLATE_STILL_CAPTURE) // 完全关闭自动控制 captureRequestBuilder.set(CaptureRequest.CONTROL_MODE, CaptureRequest.CONTROL_MODE_OFF) captureRequestBuilder.set(CaptureRequest.CONTROL_AE_MODE, CaptureRequest.CONTROL_AE_MODE_OFF) // 设置合法的ISO和曝光时间 captureRequestBuilder.set(CaptureRequest.SENSOR_SENSITIVITY, 2000.coerceIn(isoRange.lower, isoRange.upper)) captureRequestBuilder.set(CaptureRequest.SENSOR_EXPOSURE_TIME, 10000000000.coerceIn(exposureRange.lower, exposureRange.upper)) imageReader = ImageReader.newInstance( 3000, 3000, ImageFormat.JPEG, 1 ) // 仅添加一次Surface val surfaces = listOf(imageReader.surface) camera.createCaptureSession(surfaces, object : CameraCaptureSession.StateCallback() { override fun onConfigured(session: CameraCaptureSession) { try { val captureRequest = captureRequestBuilder.build() session.capture(captureRequest, object : CameraCaptureSession.CaptureCallback() { override fun onCaptureCompleted( session: CameraCaptureSession, request: CaptureRequest, result: TotalCaptureResult ) { // 避免立即关闭会话,根据业务逻辑处理生命周期 } }, null) } catch (e: CameraAccessException) { e.printStackTrace() } } override fun onConfigureFailed(session: CameraCaptureSession) { session.close() } }, null) } override fun onDisconnected(camera: CameraDevice) { camera.close() } override fun onError(camera: CameraDevice, error: Int) { camera.close() } }, null)
额外注意事项
- 权限检查:确保已申请并获取
CAMERA运行时权限。 - 设备兼容性:部分低端设备可能不支持完全手动控制,可通过
CameraCharacteristics.INFO_SUPPORTED_HARDWARE_LEVEL判断设备支持级别。 - 异常捕获:添加完整的
CameraAccessException捕获逻辑,避免程序崩溃。
内容的提问来源于stack exchange,提问作者Vova2124
相关产品推荐
相关产品推荐

