0

I worked barcode scanner with zxing library in my app. I added flash on/off function to barcode scanner Activity. Unfortunately, when I flash turn ON, app gets crashed.

public void requestAutoFocus(Handler handler, int message) {
   if (camera != null && previewing) {
     autoFocusCallback.setHandler(handler, message);
     // Log.d(TAG, "Requesting auto-focus callback");
     camera.autoFocus(autoFocusCallback);  // <<<<<<< dead here
   }
}

********* Error Log ******************************************

java.lang.RuntimeException: autoFocus failed
at android.hardware.Camera.native_autoFocus(Native Method)                            
at android.hardware.Camera.autoFocus(Camera.java:1297)
at com.google.zxing.client.android.camera.CameraManager.requestAutoFocus(CameraManager.java:222)                                                                        
at com.google.zxing.client.android.CaptureActivityHandler.handleMessage(CaptureActivityHandler.java:75)                                                     
at android.os.Handler.dispatchMessage(Handler.java:102)                                              
at android.os.Looper.loop(Looper.java:154)
at android.app.ActivityThread.main(ActivityThread.java:6646)                                                                        
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:1468)                                                                        
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1358)

I prevent focus code if it is flash turn on, like below,

 public void requestAutoFocus(Handler handler, int message) {
   if (isFlashOn) return;  // <<<<<<< prevent here

   if (camera != null && previewing) {
     autoFocusCallback.setHandler(handler, message);
     //Log.d(TAG, "Requesting auto-focus callback");
     camera.autoFocus(autoFocusCallback);  
   }
 }

then, it is not crashed, but camera preview was freezing.

logcat logs like below.

I/Choreographer: Skipped 38 frames!  The application may be doing too much work on its main thread.
E/Camera: Error 2

flash turn on/off code like below.

private void setFlash(boolean turnOn) {
    Camera camera;
    if (turnOn) {

      camera = CameraManager.get().getCamera().open();
      Camera.Parameters p = camera.getParameters();
      p.setFlashMode(Camera.Parameters.FLASH_MODE_TORCH);
      camera.setParameters(p);
      camera.startPreview();
    } else {

      camera = CameraManager.get().getCamera().open();
      Camera.Parameters p = camera.getParameters();
      p.setFlashMode(Camera.Parameters.FLASH_MODE_OFF);
      camera.setParameters(p);
      camera.stopPreview();
    }
  }

please help me....

weew
  • 363
  • 3
  • 12
  • The second problem clearly has to do with the fact that your camera callbacks are using the UI thread. See how you can [push these callback to a background trhead](https://stackoverflow.com/questions/18149964/best-use-of-handlerthread-over-other-similar-classes/19154438#19154438). – Alex Cohn Feb 01 '18 at 15:47

3 Answers3

0

Add below code to your AndroidManifest.xml file to make use of camera

 <uses-feature
        android:name="android.hardware.camera"
        android:required="false" />
Satendra
  • 6,755
  • 4
  • 26
  • 46
Abhinav Gupta
  • 2,225
  • 1
  • 14
  • 30
0

Let's address the first problem: you call autoFocus() and it fails. OK, this can happen. Even if you do everything right, now and then your calls to camera will inevitably throw a RuntimeException. You can wrap all these calls in try … catch and gracefully continue whatever you've been doing even if the call failed.

Alex Cohn
  • 56,089
  • 9
  • 113
  • 307
0

I hope you are using below library

implementation 'com.google.zxing:core:3.4.0'
implementation 'com.journeyapps:zxing-android-embedded:4.0.0'

If you are and using DecoratedBarcodeView then you can implement flash option as below

<com.journeyapps.barcodescanner.DecoratedBarcodeView
                android:id="@+id/barcodeView"
                android:layout_width="match_parent"
                android:layout_height="match_parent" />

Create a member variable inside activity or fragment to keep track of flash status

private var isFlashOn = false

Initialise the barcode view and set torch listener

barcodeView = rootView.findViewById(R.id.barcodeView)
barcodeView.setStatusText("")

barcodeView.setTorchListener(this)

iv_flash_toggle.setOnClickListener{
    toggleFlash(!isFlashOn)
}

Make sure your activity or fragment implements below two methods. Update the member variable to keep track if flash is on or off

override fun onTorchOff() {
    isFlashOn = false
}

override fun onTorchOn() {
    isFlashOn = true
}

Hope this helps, Happy Coding :)

Sumit Sahoo
  • 2,949
  • 1
  • 25
  • 37