Turning on/off flash with Android camera2 API not working

20,235

Solution 1

Create these variables:

    public static final String CAMERA_FRONT = "1";
    public static final String CAMERA_BACK = "0";

    private String cameraId = CAMERA_BACK;
    private boolean isFlashSupported;
    private boolean isTorchOn;

then add these methods:

public void switchFlash() {
    try {
        if (cameraId.equals(CAMERA_BACK)) {
            if (isFlashSupported) {
                if (isTorchOn) {
                    mPreviewBuilder.set(CaptureRequest.FLASH_MODE, CaptureRequest.FLASH_MODE_OFF);
                    mPreviewSession.setRepeatingRequest(mPreviewBuilder.build(), null, null);
                    flashButton.setImageResource(R.drawable.ic_flash_off);
                    isTorchOn = false;
                } else {
                    mPreviewBuilder.set(CaptureRequest.FLASH_MODE, CaptureRequest.FLASH_MODE_TORCH);
                    mPreviewSession.setRepeatingRequest(mPreviewBuilder.build(), null, null);
                    flashButton.setImageResource(R.drawable.ic_flash_on);
                    isTorchOn = true;
                }
            }
        }
    } catch (CameraAccessException e) {
        e.printStackTrace();
    }
}

public void setupFlashButton() {
    if (cameraId.equals(CAMERA_BACK) && isFlashSupported) {
        flashButton.setVisibility(View.VISIBLE);

        if (isTorchOn) {
            flashButton.setImageResource(R.drawable.ic_flash_off);
        } else {
            flashButton.setImageResource(R.drawable.ic_flash_on);
        }

    } else {
        flashButton.setVisibility(View.GONE);
    }
}

after this line add this code:

Boolean available = characteristics.get(CameraCharacteristics.FLASH_INFO_AVAILABLE);
isFlashSupported = available == null ? false : available;

setupFlashButton();

at the end call switchFlash() in your desired click listener.

et voilà!

PS. This might be helpful - front/back camera switcher

Solution 2

I see for cameraX, ImageCapture.flashMode only has effect during we build with initial configuration, ImageCapture.Builder() etc. But if you want to enable/disable flash dynamically, you will have to use the following.

camera?.cameraControl?.enableTorch(enableFlash)

If you are wondering what camera is? Captured it from documentation.

// A variable number of use-cases can be passed here -
// camera provides access to CameraControl & CameraInfo
camera = cameraProvider.bindToLifecycle(
this, cameraSelector, preview, imageCapture
)

Solution 3

The answer by @MrOnyszko is correct, but it needs to be updated to

isTorchAvailable = camChars.get(CameraCharacteristics.FLASH_INFO_AVAILABLE).booleanValue();
CameraManager camManager = (CameraManager).context.getSystemService(Context.CAMERA_SERVICE);
          
try {
    String cameraId cameraId = camManager.getCameraIdList()[0];
    CameraCharacteristics camChars = camManager.getCameraCharacteristics(cameraId);

    boolean isTorchAvailable = camChars.get(CameraCharacteristics.FLASH_INFO_AVAILABLE).booleanValue();
    if(isTorchAvailable) {
        camManager.setTorchMode(cameraId, true);   //Turn ON
        camManager.setTorchMode(cameraId, false);
    }
} catch (CameraAccessException e) {
    e.printStackTrace();
}
Share:
20,235
J.M.
Author by

J.M.

Updated on July 09, 2022

Comments

  • J.M.
    J.M. almost 2 years

    I'm creating an Android app with a custom camera and I'm switching to the new camera2 API. I have a button allowing to turn ON and OFF the flash when the back camera is on (without stopping the camera, like any classic camera app).

    When I tap the flash icon, nothing happens and this is what the logcat returns:

    D/ViewRootImpl: ViewPostImeInputStage processPointer 0
    D/ViewRootImpl: ViewPostImeInputStage processPointer 1
    

    I don't know why it's not working. Here is the code:

    I have a RecordVideoActivity using a RecordVideoFragment. Here is the fragment's XML part that contains the flash button code:

    <ImageButton
        android:id="@+id/button_flash"
        android:src="@drawable/ic_flash_off"
        android:layout_alignParentLeft="true"
        style="@style/actions_icons_camera"
        android:onClick="actionFlash"/>
    

    And the Java code:

    ImageButton flashButton;
    private boolean hasFlash;
    private boolean isFlashOn = false;
    

    With in the onViewCreated:

    @Override
    public void onViewCreated(final View view, Bundle savedInstanceState) {
        ...
        [some code]
        ...
        // Flash on/off button
        flashButton = (ImageButton) view.findViewById(R.id.button_flash);
        // Listener for Flash on/off button
        flashButton.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                actionFlash();
            }
        });
    

    And here is the actionFlash() function definition:

    private void  actionFlash() {
    
        /* First check if device is supporting flashlight or not */
        hasFlash = getActivity().getApplicationContext().getPackageManager()
                .hasSystemFeature(PackageManager.FEATURE_CAMERA_FLASH);
    
        if (!hasFlash) {
            // device doesn't support flash
            // Show alert message and close the application
            AlertDialog alert = new AlertDialog.Builder(this.getActivity())
                    .create();
            alert.setMessage("Sorry, your device doesn't support flash light!");
            alert.setButton(DialogInterface.BUTTON_POSITIVE, "OK", new DialogInterface.OnClickListener() {
                public void onClick(DialogInterface dialog, int which) {
                    dialog.dismiss();
                }
            });
            alert.show();
            return;
        }
        else {  // the device support flash
            CameraManager mCameraManager = (CameraManager) getActivity().getSystemService(Context.CAMERA_SERVICE);
            try {
                String mCameraId = mCameraManager.getCameraIdList()[0];
                if (mCameraId.equals("1")) {    // currently on back camera
                    if (!isFlashOn) {  // if flash light was OFF
                        // Turn ON flash light
                        try {
                            if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
                                mCameraManager.setTorchMode(mCameraId, true);
                            }
                        } catch (Exception e) {
                            e.printStackTrace();
                        }
                        // Change isFlashOn boolean value
                        isFlashOn = true;
                        // Change button icon
                        flashButton.setImageResource(R.drawable.ic_flash_off);
    
                    } else { // if flash light was ON
                        // Turn OFF flash light
                        try {
                            if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
                                mCameraManager.setTorchMode(mCameraId, false);
                            }
                        } catch (Exception e) {
                            e.printStackTrace();
                        }
                        // Change isFlashOn boolean value
                        isFlashOn = false;
                        // Change button icon
                        flashButton.setImageResource(R.drawable.ic_flash_on);
                    }
                }
            } catch (CameraAccessException e) {
                Toast.makeText(getActivity(), "Cannot access the camera.", Toast.LENGTH_SHORT).show();
                getActivity().finish();
            }
        }
    }
    

    Any idea what could be wrong?

    (I already looked at this question but it doesn't address my problem)

    Thank you very much for your help. This is driving me crazy.

  • rakesh kejriwal
    rakesh kejriwal about 5 years
    Hi @MrOnyszko this code is working fine in case of image capture, but i am facing a problem while recording video , flash goes on but upon stoping video recording flash doesn't off, please suggest something.
  • Mudlabs
    Mudlabs about 5 years
    CaptureRequest.FLASH_MODE_OFF (or torch) don't exist developer.android.com/reference/android/hardware/camera2/…
  • Yog Guru
    Yog Guru almost 5 years
    Thanks.. This became very helpful. Working Answer.
  • Pooja
    Pooja over 2 years
    Save my day! This is perfect answer for Android Camera2 Api also.