Android 为什么我在CameraDevice.StateCallback的OneError方法中得到错误的\u CAMERA\u设备
我已经实现了Camera2API。它在大多数设备上运行良好,但我从用户那里得到了一些报告,它不允许他们拍照。我从那些用户那里得到了日志。所有人都在打开前向摄像头时传入的CameraDevice.StateCallback的OneError方法中遇到错误\u CAMERA\u设备错误。此错误表示相机发生了致命错误,需要重新打开才能使用 我编写了重新打开相机的代码,但每次都会再次发生错误 有人知道为什么会发生这种情况,以及我如何解决它吗 以下是一些相关的实施:Android 为什么我在CameraDevice.StateCallback的OneError方法中得到错误的\u CAMERA\u设备,android,android-camera2,Android,Android Camera2,我已经实现了Camera2API。它在大多数设备上运行良好,但我从用户那里得到了一些报告,它不允许他们拍照。我从那些用户那里得到了日志。所有人都在打开前向摄像头时传入的CameraDevice.StateCallback的OneError方法中遇到错误\u CAMERA\u设备错误。此错误表示相机发生了致命错误,需要重新打开才能使用 我编写了重新打开相机的代码,但每次都会再次发生错误 有人知道为什么会发生这种情况,以及我如何解决它吗 以下是一些相关的实施: override fun open()
override fun open(): Boolean {
if (hasCamera) {
try {
val id = manager.cameraIdList[cameraId]
val characteristics = manager.getCameraCharacteristics(id)
val map = characteristics.get(CameraCharacteristics.SCALER_STREAM_CONFIGURATION_MAP)
map?.let {
imageDimension = map.getOutputSizes(SurfaceTexture::class.java)[0]
}
if (!isOpen) {
manager.openCamera(id, object : CameraDevice.StateCallback() {
override fun onOpened(camera: CameraDevice) {
isOpen = true
openCount++
this.cameraDevice = camera
startPreview(null)
}
override fun onDisconnected(camera: CameraDevice) {
this.cameraDevice = camera
close()
}
override fun onError(camera: CameraDevice, error: Int) {
this.cameraDevice = camera
close()
this.cameraDevice = null
if (openCount < 10) {
openCount++
open()
}
}
}, null)
}
} catch (e: Exception) {
Timber.e("open: $e")
} catch (e: SecurityException) {
Timber.e("open: $e")
}
}
return hasCamera
}
override fun startPreview(startPreviewFailCallback: (() -> Unit)?) {
cameraDevice?.let { cameraDevice ->
try {
val texture = textureView.surfaceTexture ?: return
imageDimension?.let {
texture.setDefaultBufferSize(it.width, it.height)
} ?: kotlin.run {
texture.setDefaultBufferSize(640, 480)
}
surface = Surface(texture)
captureRequestBuilder = cameraDevice.createCaptureRequest(CameraDevice.TEMPLATE_PREVIEW)
captureRequestBuilder.addTarget(surface)
val range = getRange()
range?.let {
captureRequestBuilder.set(CaptureRequest.CONTROL_AE_TARGET_FPS_RANGE, getRange())
}
cameraDevice.createCaptureSession(Arrays.asList(surface), object : CameraCaptureSession.StateCallback() {
override fun onConfigured(@NonNull cameraCaptureSession: CameraCaptureSession) {
//The camera is already closed
if (null == cameraDevice) {
return
}
// When the session is ready, we start displaying the preview.
this@CameraNew.cameraCaptureSession = cameraCaptureSession
updatePreview()
}
override fun onConfigureFailed(@NonNull cameraCaptureSession: CameraCaptureSession) {
this.cameraCaptureSession = cameraCaptureSession
}
}, null)
} catch (e: CameraAccessException) {
e.printStackTrace()
Timber.e("startPreview: $e")
} catch (e: SecurityException) {
Timber.e("startPreview: $e")
}
} ?: kotlin.run {
startPreviewFailCallback?.let {
it.invoke()
}
}
}
private fun updatePreview() {
if (null == cameraDevice) {
return
}
captureRequestBuilder.set(CaptureRequest.CONTROL_MODE, CameraMetadata.CONTROL_MODE_AUTO)
try {
cameraCaptureSession.setRepeatingRequest(captureRequestBuilder.build(), null, backgroundHandler)
} catch (e: CameraAccessException) {
e.printStackTrace()
Timber.e("updatePreview: $e")
} catch (e: IllegalStateException) {
Timber.e("updatePreview: $e")
}
}
override fun open():布尔值{
如果(照相机){
试一试{
val id=manager.cameraIdList[cameraId]
val characteristics=manager.getCameraCharacteristics(id)
val map=characteristics.get(CameraCharacteristics.SCALER\u流\u配置\u映射)
地图?让我看看{
imageDimension=map.getOutputSizes(SurfaceTexture::class.java)[0]
}
如果(!isOpen){
manager.openCamera(id,对象:CameraDevice.StateCallback(){
已打开覆盖功能(摄像头:CameraDevice){
等参=真
开放计数++
this.cameraDevice=照相机
startPreview(空)
}
已断开连接(摄像头:CameraDevice){
this.cameraDevice=照相机
关闭()
}
覆盖错误(摄像头:CameraDevice,错误:Int){
this.cameraDevice=照相机
关闭()
this.cameraDevice=null
如果(openCount<10){
开放计数++
开()
}
}
},空)
}
}捕获(e:例外){
木材.e(“开放:$e”)
}捕获(e:SecurityException){
木材.e(“开放:$e”)
}
}
回程照相机
}
覆盖有趣的startPreview(startPreviewFailCallback:(()->单位)?){
cameraDevice?让{cameraDevice->
试一试{
val texture=textureView.surfaceTexture?:返回
图像尺寸?让我们{
texture.setDefaultBufferSize(it.width,it.height)
}?:kotlin.run{
texture.setDefaultBufferSize(640480)
}
表面=表面(纹理)
captureRequestBuilder=cameraDevice.createCaptureRequest(cameraDevice.TEMPLATE\u预览)
captureRequestBuilder.addTarget(曲面)
val range=getRange()
射程?,让我来{
captureRequestBuilder.set(CaptureRequest.CONTROL\u AE\u TARGET\u FPS\u RANGE,getRange())
}
cameraDevice.createCaptureSession(Arrays.asList(surface),对象:CameraCaptureSession.StateCallback(){
覆盖未配置的乐趣(@NonNull cameraCaptureSession:cameraCaptureSession){
//摄像机已经关上了
如果(null==cameraDevice){
返回
}
//当会话准备就绪时,我们开始显示预览。
this@CameraNew.cameraCaptureSession=cameraCaptureSession
updatePreview()
}
覆盖配置文件(@NonNull cameraCaptureSession:cameraCaptureSession){
this.cameraCaptureSession=cameraCaptureSession
}
},空)
}捕获(e:CameraAccessException){
e、 printStackTrace()
Timber.e(“startPreview:$e”)
}捕获(e:SecurityException){
Timber.e(“startPreview:$e”)
}
}?:kotlin.run{
startPreviewFailCallback?让我们{
it.invoke()
}
}
}
私人娱乐更新预览(){
如果(null==cameraDevice){
返回
}
captureRequestBuilder.set(CaptureRequest.CONTROL_模式,CameraMetadata.CONTROL_模式自动)
试一试{
cameraCaptureSession.setRepeatingRequest(captureRequestBuilder.build(),null,backgroundHandler)
}捕获(e:CameraAccessException){
e、 printStackTrace()
Timber.e(“更新回顾:$e”)
}捕获(e:非法状态例外){
Timber.e(“更新回顾:$e”)
}
}
我终于明白了。纹理视图默认缓冲区大小使用的大小太大。我通过迭代摄影机特性图中的输出大小数组来修复它,并使用了960x1200以下的最大大小
val map = characteristics.get(CameraCharacteristics.SCALER_STREAM_CONFIGURATION_MAP)
map?.let {
val sizesArray = map.getOutputSizes(SurfaceTexture::class.java)
var smallest: Size = Size(0, 0)
for (item in sizesArray) {
Timber.i("jpegSize: width: ${item.width}, height: ${item.height}")
if (item.height > smallest.height && item.height < 960 && item.width < 1200) {
smallest = item
}
}
imageDimension = smallest
}
imageDimension?.let {
texture.setDefaultBufferSize(it.width, it.height)
}