androidandroid-broadcastreceiverandroid-camera2illegalargumentexceptionreceiver

Fatal Exception: java.lang.IllegalArgumentException: Receiver not registered: android.hardware.camera2.CameraManager


I am developing a flashlight app that switch on/off the system tourch.

I have a crash that shown on Android M (v6.0) on

Crashlytics

Here is the Issue details and stacktrace:

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)

I have the following Manifest permissions and hardware features:

<uses-feature android:name="android.hardware.camera" />
<uses-feature android:name="android.hardware.camera.flash" />

and

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

****EDIT:****

Here is the code I am using to access the camera:

// 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();
            }
        }

}

Here is the code to switch on the flash/tourch:

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();

 }

Also, here is the code of switching off the camera flash:

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();
            }
 }

Code of startCameraPreview() method:

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

I don't have any receiver in my app except the widget provider class but I don't have any line of code the do (register/unregister) a receiver!!

I searched and read many links resources regarding this issue but I could not find any clue to exactly know the line which causing it.

Anyone faced this issue, your help is appreciated.


Solution

  • I had the same issue (or similar). My stacktrace was exactly as yours. I've solved my problem by ensuring (in the code of my application) that I don't try to switch torch Off if the torch was not turned ON by my application previously.

    Crash occurred when I was calling cameraManager.setTorchMode(cameraId, false) two times sequentially.

    So I just maintain boolean flag in my application which shows exact torch state at the moment. Set it to true right after cameraManager.setTorchMode(cameraId, true) call and don't do cameraManager.setTorchMode(cameraId, false) if the flag in not true. Set the flag to false after successful cameraManager.setTorchMode(cameraId, false).

    Hope this helps...