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);
}
};
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.
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.
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.
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.
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
When the device is at least LEVEL_LIMITED:
These values are possible, but there is no guarantee that they all work:
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.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With