Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Android: how to detect if camera flashed

I'm using Android's Camera2 API and I currently want the camera to perform a certain action whenever it prepares to flash.

When building the CaptureRequest, the following line:

captureRequest.set(CaptureRequest.CONTROL_AE_MODE,CaptureRequest.CONTROL_AE_MODE_ON_AUTO_FLASH);

allows the camera to flash under low-lighting conditions. However, I am at a loss as to how I can detect whether the camera is prepped to flash or not. It seems like the literature online about this particular action is pretty sparse.

I have tried checking if FLASH_STATE is in FLASH_STATE_READY while processing a partialresult in the camera's CaptureCallback, but it seems like the key wasn't available - it kept returning null. Perhaps I'm not checking in the right place?

The camera's CaptureCallback, shown below (based off Google's Camera2Basic code sample):

private CameraCaptureSession.CaptureCallback mCaptureCallback
        = new CameraCaptureSession.CaptureCallback()    {
    private void process(CaptureResult result)  {
        switch(mState)  {
            case STATE_PREVIEW: break;
            case STATE_WAITING_LOCK:
                // checking if result.get(CaptureResult.FLASH_STATE) == 
                // CaptureResult.FLASH_READY over here didn't work because
                // null was returned
                int afState = result.get(CaptureResult.CONTROL_AF_STATE);
                if (CaptureResult.CONTROL_AF_STATE_FOCUSED_LOCKED == afState ||
                        CaptureResult.CONTROL_AF_STATE_NOT_FOCUSED_LOCKED == afState) {
                    Integer aeState = result.get(CaptureResult.CONTROL_AE_STATE);
                    if (aeState == null ||
                            aeState == CaptureResult.CONTROL_AE_STATE_CONVERGED) {
                        mState = STATE_WAITING_NON_PRECAPTURE;
                        captureStillPicture();
                    } else {
                        runPrecaptureSequence();
                    }
                }
                break;
            case STATE_WAITING_PRECAPTURE:
                Integer aeState = result.get(CaptureResult.CONTROL_AE_STATE);
                if (aeState == null ||
                        aeState == CaptureResult.CONTROL_AE_STATE_PRECAPTURE ||
                        aeState == CaptureRequest.CONTROL_AE_STATE_FLASH_REQUIRED) {
                    mState = STATE_WAITING_NON_PRECAPTURE;
                }
                break;
            case STATE_WAITING_NON_PRECAPTURE:
                Integer aeState1 = result.get(CaptureResult.CONTROL_AE_STATE);
                if (aeState1 == null || aeState1 != CaptureResult.CONTROL_AE_STATE_PRECAPTURE) {
                    mState = STATE_PICTURE_TAKEN;
                    captureStillPicture();
                }
                break;
        }
    }

    @Override
    public void onCaptureProgressed(CameraCaptureSession session,
                                    CaptureRequest request, CaptureResult partialResult) {
        super.onCaptureProgressed(session, request, partialResult);
        process(partialResult);
    }

    @Override
    public void onCaptureCompleted(CameraCaptureSession session,
                                   CaptureRequest request, TotalCaptureResult result) {
        super.onCaptureCompleted(session, request, result);
        process(result);
    }
};
like image 957
rfblue2 Avatar asked Aug 05 '15 04:08

rfblue2


People also ask

How do I test my front camera flash?

1 Tap on Camera icon from the Home screen. 2 Tap on the Switch camera icon to switch to the front camera as shown below. 3 Tap on the Flashlight icon to turn on the front flash.

Why does my Android phone camera flash randomly?

Some phones have the ability to flash the LED to alert you to some new condition on the phone, like an incoming call or new mail notification. This is useful for people with poor hearing who might not hear the ringer or beep. It's also potentially useful in circumstances where you don't want the phone to make a noise.

What is flash test on Android phone?

Android Flash Tool allows you to flash an Android build to your device for development and testing. To get started, you need a development machine and an Android device.

How do you check which apps are using camera Android?

1 In the Settings menu, tap on the "Privacy" option. 2 In the Privacy menu, tap on “Permission Manager” option. 3 In the Permission Manager menu, you can review which apps have permission to use the camera, microphone, or both.


2 Answers

In the documentation you can read the following statement for the FLASH_STATE key:

Optional - This value may be null on some devices.

Basically even if you are using a Lollipop device you can't be sure all functions of the Camera2 APi are supported. Devices with limited functions are called "limited devices".

For more informations take a look at this page. This describes it pretty well.

EDIT: To answer the comment which is basically wrong: The documentations say:

When the camera device doesn't have flash unit (i.e. android.flash.info.available == false), this state will always be UNAVAILABLE. Other states indicate the current flash status.

So if there is no flash on the device the FLASH_STATE is also present and will return UNAVAILABLE.

The documentation say pretty much everything you have to know. The most importand fact is, that it depends on the hardware-level/hardware mode.


Lets summarize it

For LEGACY devices

It will return the following

  • FIRED if the AE mode is set to ON_ALWAYS_FLASH
  • FIRED if the flash mode is set to TORCH
  • UNAVAILABLE if the camera has no flash.

When the device is at least LEVEL_LIMITED:

These values are possible, but there is no guarantee that they all work:

  • UNAVAILABLE
  • CHARGING
  • READY
  • FIRED
  • PARTIAL
like image 169
foxy Avatar answered Sep 19 '22 21:09

foxy


There is no current way to know for sure if the flash will fire - the decision is made by the camera device at the last moment before the full-resolution capture. Once the final capture result for the full-resolution capture is available, its flash state should be FIRED if the flash did fire, but you'll get this after the fact. Make sure you wait for the total capture result from onCaptureCompleted to check for this field, not a partial from onCaptureProgressed; the partial results may be missing various fields.

That said, if the AE state field before starting the precapture sequence is FLASH_REQUIRED, it's quite likely that the flash will be fired if the AE mode allows for flash (AE_MODE_ON_AUTO_FLASH / ALWAYS_FLASH / AUTO_FLASH_REDEYE). It's not a 100% guarantee, since the scene may change in the few frames between the start of the precapture sequence (which will execute a precapture flash to estimate necessary flash power) and the actual final picture capture. But I suspect 95% of the time it'll be the final outcome.

like image 45
Eddy Talvala Avatar answered Sep 22 '22 21:09

Eddy Talvala