8

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.

blueware
  • 5,205
  • 1
  • 40
  • 60
  • Have you add `` in your AndroidManifest.xml file? see my github repo at https://github.com/ChiragSavsani/FlashLightWidget – Chirag Savsani Sep 26 '18 at 13:02
  • @ChiragSavsani, yes, I will update my question with permissions used in the manifest – blueware Sep 26 '18 at 13:03
  • Look at this https://stackoverflow.com/questions/32259429/java-lang-illegalargumentexception-receiver-not-registered – Chirag Savsani Sep 26 '18 at 13:11
  • @ChiragSavsani, Thanks for sharing the link. I read that question before and did not find a clue to solve my issue :( – blueware Sep 26 '18 at 14:13
  • @PerracoLabs, yes I am asking the user either to allow or deny the Camera permission – blueware Sep 29 '18 at 19:38
  • @PerracoLabs, I don't have any receiver to register in my app. If I have then I can easily handle it but the weird thing is that I can't reproduce the issue and In which line the crash hides. – blueware Sep 29 '18 at 19:53

3 Answers3

4

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...

blueware
  • 5,205
  • 1
  • 40
  • 60
denisxor
  • 66
  • 3
  • I have access to `CameraManager` from both my `Activity` and an `IntentService` class which the second can turn on/off the flash. According to what you said, I need to use this boolean in both activity and intent service ? – blueware Oct 03 '18 at 10:26
  • 1
    You need one flag which will be visible in both places: Activity and IntentService. – denisxor Oct 03 '18 at 18:50
1

Camera.Parameters is deprecated in API level 21. Use CameraManager instead.

For setFlashMode (String value) in Camera.Parameters, there is an equivalent method setTorchMode (String cameraId, boolean enabled) in CameraManager

Bertram Gilfoyle
  • 9,899
  • 6
  • 42
  • 67
  • If you carefully read the exception, its happening when using the 'CameraManager'. In my code, I'm using the old and the new way to access the camera with permission check. Its really weird exception. – blueware Sep 30 '18 at 07:34
  • I edited my question. Note that, I can't figure out where the problem is and in which line as I don't have any receiver in my app to reproduce the crash. – blueware Sep 30 '18 at 10:38
  • Hi the log cat you have posted looks like only a small part. Is there anything else? – Bertram Gilfoyle Sep 30 '18 at 11:28
  • 1
    Actually this is the only thing I got in the logcat :( . If I have some more, I would be happy to post it out – blueware Sep 30 '18 at 11:34
  • I have two questions. 1) Do you get this error every time when you run the code in Marshmallow or is it a rare case? 2) When does this on/of code executes? I mean on what actions? – Bertram Gilfoyle Sep 30 '18 at 12:07
  • Also can you elaborate "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" ? What is widget provider class? – Bertram Gilfoyle Sep 30 '18 at 13:27
  • 1
    Q1) Its a rare case. Q2) on and off codes are executed when user clicks on the switch on/off button. I am using a boolean to check if flash is on/off to do this logic. As per your next comment, I don't have any `BroadcastReceiver` to call `register/unregister` it in my `Activity`. I only have an `AppWidgetProvider` class that is used to inflate a widget on user's home screen, this class is registered in the `Manifest` file as `...`, that's all. – blueware Sep 30 '18 at 13:48
0

I think this post (When trying turn off camera led, app crash) is helpful.

In short, f you try to disable flashlight again (even if flashlight is already disabled), then app is crashed.

sso.techie
  • 136
  • 7
  • I already had commented on that post but unfortunately the onwer could not help me as he forgot how the code was – blueware Sep 28 '18 at 06:39