在Nexus 7上使用新的Android Camera2 API

4
我在 Nexus 7 上使用 Android Camera2 API 遇到了问题。我开发了一个基于 Android 4.4.4 的应用程序,使用相机拍照,并希望将其更新为 Lollipop 版本。我遵循了此链接中的代码以使新的相机 API 工作:https://github.com/googlesamples/android-Camera2Basic/blob/master/Application/src/main/java/com/example/android/camera2basic/Camera2BasicFragment.java 我已在 Nexus 5 上测试了代码,一切正常,但如果我在 Nexus 7 上尝试它,就会出现错误日志:
12-17 17:01:15.517: W/LegacyRequestMapper(24382): convertRequestMetadata - control.awbRegions setting is not supported, ignoring value
12-17 17:01:15.517: W/LegacyRequestMapper(24382): Only received metering rectangles with weight 0.
12-17 17:01:15.518: W/LegacyRequestMapper(24382): Only received metering rectangles with weight 0.
12-17 17:01:15.519: W/LegacyRequestMapper(24382): mapAeAndFlashMode - Ignore control.aeMode == ON_AUTO_FLASH;camera does not support it
12-17 17:01:15.519: W/LegacyRequestMapper(24382): convertRequestToMetadata - Ignoring android.lens.focusDistance false, only 0.0f is supported
12-17 17:01:15.955: I/CameraDeviceState(24382): Legacy camera service transitioning to state CAPTURING
12-17 17:01:21.198: I/RequestQueue(24382): Repeating capture request cancelled.
12-17 17:01:21.198: I/RequestQueue(24382): Repeating capture request set.
12-17 17:01:21.215: W/LegacyRequestMapper(24382): convertRequestMetadata - control.awbRegions setting is not supported, ignoring value
12-17 17:01:21.215: W/LegacyRequestMapper(24382): Only received metering rectangles with weight 0.
12-17 17:01:21.215: W/LegacyRequestMapper(24382): Only received metering rectangles with weight 0.
12-17 17:01:21.216: W/LegacyRequestMapper(24382): mapAeAndFlashMode - Ignore control.aeMode == ON_AUTO_FLASH;camera does not support it
12-17 17:01:21.216: W/LegacyRequestMapper(24382): convertRequestToMetadata - Ignoring android.lens.focusDistance false, only 0.0f is supported
12-17 17:01:21.495: E/AndroidRuntime(24382): FATAL EXCEPTION: CameraBackground
12-17 17:01:21.495: E/AndroidRuntime(24382): Process: com.example.newapicamera, PID: 24382
12-17 17:01:21.495: E/AndroidRuntime(24382): java.lang.NullPointerException: Attempt to invoke virtual method 'int java.lang.Integer.intValue()' on a null object reference
12-17 17:01:21.495: E/AndroidRuntime(24382):    at com.example.newapicamera.Camera2BasicFragment$4.process(Camera2BasicFragment.java:285)
12-17 17:01:21.495: E/AndroidRuntime(24382):    at com.example.newapicamera.Camera2BasicFragment$4.onCaptureCompleted(Camera2BasicFragment.java:324)
12-17 17:01:21.495: E/AndroidRuntime(24382):    at java.lang.reflect.Method.invoke(Native Method)
12-17 17:01:21.495: E/AndroidRuntime(24382):    at java.lang.reflect.Method.invoke(Method.java:372)
12-17 17:01:21.495: E/AndroidRuntime(24382):    at android.hardware.camera2.dispatch.InvokeDispatcher.dispatch(InvokeDispatcher.java:39)
12-17 17:01:21.495: E/AndroidRuntime(24382):    at android.hardware.camera2.dispatch.HandlerDispatcher$1.run(HandlerDispatcher.java:65)
12-17 17:01:21.495: E/AndroidRuntime(24382):    at android.os.Handler.handleCallback(Handler.java:739)
12-17 17:01:21.495: E/AndroidRuntime(24382):    at  android.os.Handler.dispatchMessage(Handler.java:95)
12-17 17:01:21.495: E/AndroidRuntime(24382):    at android.os.Looper.loop(Looper.java:135)
12-17 17:01:21.495: E/AndroidRuntime(24382):    at android.os.HandlerThread.run(HandlerThread.java:61)
12-17 17:01:21.542: I/RequestQueue(24382): Repeating capture request cancelled.
12-17 17:01:21.580: E/BufferQueueProducer(24382): [unnamed-24382-2] dequeueBuffer: BufferQueue has been abandoned
12-17 17:01:21.580: E/BufferQueueProducer(24382): [unnamed-24382-2] dequeueBuffer: BufferQueue has been abandoned
12-17 17:01:21.596: E/BufferQueueProducer(24382): [unnamed-24382-2] queueBuffer: BufferQueue has been abandoned
12-17 17:01:21.605: W/Camera-JNI(24382): callback on dead camera object
12-17 17:01:21.620: E/BufferQueueProducer(24382): [unnamed-24382-2] queueBuffer: BufferQueue has been abandoned
12-17 17:01:21.651: E/BufferQueueProducer(24382): [unnamed-24382-2] queueBuffer: BufferQueue has been abandoned
12-17 17:01:21.688: E/BufferQueueProducer(24382): [unnamed-24382-2] queueBuffer: BufferQueue has been abandoned
12-17 17:01:21.721: E/BufferQueueProducer(24382): [unnamed-24382-2] queueBuffer: BufferQueue has been abandoned

抛出异常的代码行为:

int aeState = result.get(CaptureResult.CONTROL_AE_STATE);

出了什么问题?
4个回答

4

当使用新的camera2 API时,Nexus 7是一个LEGACY级设备,而LEGACY设备相对于实现了LIMITED或FULL级别的新API的设备有许多限制。

在CONTROL_AE_STATE的文档中,有一个注释:

Limited capability - Present on all camera devices that report being at least HARDWARE_LEVEL_LIMITED devices in the android.info.supportedHardwareLevel key

这意味着它不能保证在传统设备上存在,实际上也不会存在,因为这些设备不会产生AE状态信息。

2

在使用Camera2 API的任何功能之前,首先需要检查设备是否支持该功能。对于您的情况,可以按以下方式检查:

// CONTROL_AE_STATE can be null on some devices
                        Integer aeState = result.get(CaptureResult.CONTROL_AE_STATE);
                        if (aeState == null ||
                                aeState == CaptureResult.CONTROL_AE_STATE_CONVERGED) {
                            mState = STATE_WAITING_NON_PRECAPTURE;
                            captureStillPicture();
                        } else {
                            runPrecaptureSequence();
                        }

如果您想了解更多详情,可以在此处查看Google的官方示例代码:https://github.com/googlesamples/android-Camera2Basic


1
今天我读到,camera2 api 仅在安卓 5 版本的 Nexus 5 和 6 上得到了实现。

你在哪里看到这个的?camera2是Lollipop官方版本中支持的API。在预览版中它并没有完全被支持,但现在应该可以正常工作了。我可能是错的,但请提供你信息的来源。 - Daniel Smith
我看到Camera2之前也不支持预览,但现在Lollipop版本已经正式发布了!由于Camera API已被弃用,所以我无法在我的Lollipop设备上使用它。 - giozh
你仍然可以使用相机API。 - Daniel Smith
我的应用程序已经使用旧的相机API,但在Lollipop更新后,应用程序崩溃了。因此,我尝试使用Camera2 API。 - giozh
简单的Camera 2 API示例在我的Nexus 2013 wifi上的5.0.1上运行。但是,它没有使用任何酷炫的新高级功能。我读到Nexus 7没有硬件支持新的RAW输出。不确定它是否支持连拍模式或其他功能。我想知道它在相机API中能做什么,不能做什么。 - medloh

0

我的猜测是result是一个bundle,而get返回一个Integer对象(与语句左侧的int原始类型不同)。似乎CaptureResult.CONTROL_AE_STATE不在bundle中。这可能意味着您的设备不支持某些内容,但这并不清楚。

崩溃发生是因为Java自动将Integer拆箱为int,但此处的Integernull!这将抛出空指针异常,因为Java试图将null对象转换为int,因此会出现警告:

Attempt to invoke virtual method 'int java.lang.Integer.intValue()' on a null object reference

更安全的处理方法是将aeState设置为Integer,这样您就不会强制Java自动解包语句的右侧。Java试图帮助您,但可能会令人困惑!


好的,我明白问题出在哪里了,但我想知道为什么只有在Nexus 7上运行应用程序时才会发生! - giozh
这是一个特定于设备的问题。请参考Eddy Talvala的答案以获取有关Nexus7的信息。 - Daniel Smith

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接