致命异常:java.lang.IllegalArgumentException:接收器未注册:android.hardware.camera2.CameraManager。

8

我正在开发一个手电筒应用程序,可以打开/关闭系统的闪光灯。

我在Android M(v6.0)上遇到了崩溃问题:

Crashlytics

以下是问题详情和堆栈跟踪:

Fatal Exception: java.lang.IllegalArgumentException: Receiver not registered: android.hardware.camera2.CameraManager$1@49e5f1b
   at android.app.LoadedApk.forgetReceiverDispatcher(LoadedApk.java:789)
   at android.app.ContextImpl.unregisterReceiver(ContextImpl.java:1222)
   at android.hardware.camera2.CameraManager$3.run(CameraManager.java:1266)
   at android.os.Handler.handleCallback(Handler.java:815)
   at android.os.Handler.dispatchMessage(Handler.java:104)
   at android.os.Looper.loop(Looper.java:207)
   at android.app.ActivityThread.main(ActivityThread.java:5728)
   at java.lang.reflect.Method.invoke(Method.java)
   at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:789)
   at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:679)

我拥有以下的Manifest权限和硬件特性:
<uses-feature android:name="android.hardware.camera" />
<uses-feature android:name="android.hardware.camera.flash" />

并且。
<uses-permission android:name="android.permission.CAMERA" />
<uses-permission android:name="android.permission.FLASHLIGHT" />

****编辑:****

这是我正在使用的访问摄像头的代码:

// Here, I am checking if SDK >= M
if (VersionUtils.isMarshmallowOrGreater()) {

        cameraManager = (CameraManager) getSystemService(Context.CAMERA_SERVICE);

        if (cameraManager != null) {

            try {
                cameraId = cameraManager.getCameraIdList()[0];
            } catch (CameraAccessException | ArrayIndexOutOfBoundsException e) {
                e.printStackTrace();
            }
        }

} else {

        if (camera == null || camera.getParameters() == null) {

            try {
                camera = Camera.open();
                params = camera.getParameters();
            } catch (RuntimeException e) {
                e.printStackTrace();
            }
        }

}

以下是打开闪光灯的代码:

if (VersionUtils.isMarshmallowOrGreater()) {

            try {
                cameraManager.setTorchMode(cameraId, true);
            } catch (Exception e) {
                e.printStackTrace();
            }

 } else {

            if (camera == null || params == null || camera.getParameters() == null) {
                getCamera();
                return;
            }

            params = camera.getParameters();
            params.setFlashMode(Parameters.FLASH_MODE_TORCH);
            camera.setParameters(params);

            startCameraPreview();

 }

此外,以下是关闭相机闪光灯的代码:
if (VersionUtils.isMarshmallowOrGreater()) {

            try {
                cameraManager.setTorchMode(cameraId, false);
            } catch (Exception e) {
                e.printStackTrace();
            }

 } else {

            if (camera == null || params == null || camera.getParameters() == null) {
                return;
            }

            try {

                params = camera.getParameters();
                params.setFlashMode(Parameters.FLASH_MODE_OFF);
                camera.setParameters(params);
                stopCameraPreview();
                camera.release();
                camera = null;

            } catch (Exception e) {
                e.printStackTrace();
            }
 }

startCameraPreview() 方法的代码:

private void startCameraPreview() {
    try {
        camera.startPreview();
    } catch (Exception e) {
        e.printStackTrace();
    }
}

除了小部件提供程序类之外,我的应用程序中没有任何接收器,但我没有任何代码行来执行(注册/注销)接收器!

我搜索并阅读了许多关于此问题的链接资源,但我无法找到确切知道导致此问题的代码行。

有遇到这个问题的人,你们的帮助将不胜感激。


你在AndroidManifest.xml文件中添加了<uses-feature android:name="android.hardware.camera" />吗?请查看我的Github存储库:https://github.com/ChiragSavsani/FlashLightWidget - Chirag Savsani
@ChiragSavsani,好的,我会在清单中更新使用的权限。 - blueware
看这个 https://dev59.com/7lwY5IYBdhLWcg3wwp84 - Chirag Savsani
@ChiragSavsani,感谢分享链接。我之前看过那个问题,但是没有找到解决我的问题的线索 :( - blueware
@PerracoLabs,是的,我正在询问用户是否允许或拒绝相机权限。 - blueware
@PerracoLabs,我的应用程序中没有任何接收器需要注册。如果有的话,我可以轻松处理它,但奇怪的是我无法重现这个问题,也不知道崩溃隐藏在哪一行代码中。 - blueware
3个回答

4

我之前也遇到了同样的问题(或类似的问题)。我的堆栈跟你完全一样。我通过确保在我的应用程序代码中,只有当我的应用程序之前打开了手电筒时,才尝试关闭手电筒来解决了我的问题。

当我连续两次调用cameraManager.setTorchMode(cameraId, false)时,就会发生崩溃。

因此,我在我的应用程序中保持一个布尔标志,显示当前手电筒状态。在cameraManager.setTorchMode(cameraId, true)调用后将其设置为true,并且如果标志不为true,则不执行cameraManager.setTorchMode(cameraId, false)。在成功执行cameraManager.setTorchMode(cameraId, false)后,将该标志设置为false。

希望这能有所帮助...


我可以从我的Activity和一个IntentService类中访问CameraManager,第二个可以打开/关闭闪光灯。根据你所说的,我需要在活动和意图服务中都使用这个布尔值吗? - blueware
1
你需要一个标记,在Activity和IntentService两个地方都可见。 - denisxor

1

Camera.Parameters在API 21中已被弃用。请改用CameraManager

对于Camera.Parameters中的setFlashMode(String value),在CameraManager中有一个等效的方法setTorchMode(String cameraId, boolean enabled)


如果你仔细阅读异常信息,会发现它是在使用“CameraManager”时发生的。在我的代码中,我使用了旧的和新的方式来访问相机并进行权限检查。这真的是一个非常奇怪的异常。 - blueware
我编辑了我的问题。请注意,由于我的应用程序中没有接收器来重现崩溃,因此我无法确定问题所在和哪一行出现问题。 - blueware
1
实际上这是我在logcat中得到的唯一信息 :( 。如果我有更多的信息,我会很乐意将其发布出来。 - blueware
我有两个问题。1)在Marshmallow中运行代码时,您是否每次都会遇到此错误,还是很少见?2)这个开/关代码是在什么情况下执行的?我的意思是在哪些操作上? - Bertram Gilfoyle
1
Q1) 这是一个罕见的情况。 Q2) 当用户点击开/关按钮时,执行开和关代码。我使用布尔值来检查闪光灯是否开启/关闭以进行此逻辑。根据您的下一个评论,我没有任何BroadcastReceiver在我的Activity中调用register/unregister。我只有一个AppWidgetProvider类,用于在用户的主屏幕上填充小部件,这个类在Manifest文件中注册为<receiver>...</receiver>,就这些。 - blueware
显示剩余2条评论

0

我已经在那篇帖子上发表了评论,但不幸的是,所有者无法帮助我,因为他忘记了代码是如何编写的。 - blueware

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