1
votes

I'm using the new camera2 api on Android 6.1, sdk 23.

I have two requests: a preview and a still image capture request. I'd like to make it so that the flash goes off on every still image request, but without any pre-flash. Right now, my request looks like this:

CaptureRequest.Builder requester = mCameraDevice.createCaptureRequest(mCameraDevice.TEMPLATE_STILL_CAPTURE);
        requester.set(CaptureRequest.CONTROL_AE_MODE, CaptureRequest.CONTROL_AE_MODE_ON_ALWAYS_FLASH);
        requester.set(CaptureRequest.CONTROL_CAPTURE_INTENT, CaptureRequest.CONTROL_CAPTURE_INTENT_STILL_CAPTURE);
        requester.set(CaptureRequest.CONTROL_AE_EXPOSURE_COMPENSATION, CaptureRequest.CONTROL_AE_STATE_FLASH_REQUIRED);
        requester.set(CaptureRequest.CONTROL_AE_PRECAPTURE_TRIGGER, CaptureRequest.CONTROL_AE_PRECAPTURE_TRIGGER_CANCEL);
        requester.addTarget(mCaptureBuffer.getSurface());

mCaptureSession.capture(requester.build(), null, null);

It seems to work on one phone (a Motorola Moto G) but not on another (a Nexus 5 -- the flash doesn't turn on at all). I know the Nexus' flash works because I can trigger it with other camera apps, so I'm guessing there are some defaults that I'm not setting.

Is there another way I can do this / more flags I can set?

Thanks!

Edit:


It turns out that a lot of the trouble I was having stemmed from working with devices that had only LIMITED support for camera2. Just because you can access the camera using camera 2 doesn't mean you can control all the features. Check out this answer for more
2
maybe you have piece of example? or just tell me where exactlly i should to incdlude this lines of code? on stillCapture() or onConfigurate() or unlockFocus() medhod? because i can't find anythink that can make my code worked...Aleksey Timoshchenko

2 Answers

3
votes

Flash_Mode and CONTROL_AE_MODE sometimes have some problems when they are active at the same time, so I recommend you to separate them, keeping off FLASH_MODE to off and control the Flash with CONTROL_AE_MODE . So to set the different flash modes, use something like this:

int flashMode = yourDesireFlashModeKey;
        if (flashMode == CameraMetadata.FLASH_MODE_OFF) {
            builder.set(CaptureRequest.CONTROL_AE_MODE, CameraMetadata.CONTROL_AE_MODE_ON);
            builder.set(CaptureRequest.FLASH_MODE, CameraMetadata.FLASH_MODE_OFF);

        } else if (flashMode == CameraMetadata.CONTROL_AE_MODE_ON_AUTO_FLASH) {
            builder.set(CaptureRequest.CONTROL_AE_MODE, CameraMetadata.CONTROL_AE_MODE_ON_AUTO_FLASH);
            builder.set(CaptureRequest.FLASH_MODE, CameraMetadata.FLASH_MODE_OFF);

        } else if (flashMode == CameraMetadata.CONTROL_AE_MODE_ON_ALWAYS_FLASH) {
            builder.set(CaptureRequest.CONTROL_AE_MODE, CameraMetadata.CONTROL_AE_MODE_ON_ALWAYS_FLASH);
            builder.set(CaptureRequest.FLASH_MODE, CameraMetadata.FLASH_MODE_OFF);

        } else if (flashMode == CameraMetadata.CONTROL_AE_MODE_ON_AUTO_FLASH_REDEYE) {
            builder.set(CaptureRequest.CONTROL_AE_MODE, CameraMetadata.CONTROL_AE_MODE_ON_AUTO_FLASH_REDEYE);
            builder.set(CaptureRequest.FLASH_MODE, CameraMetadata.FLASH_MODE_OFF);
        }
        else if (flashMode == CameraMetadata.FLASH_MODE_OFF || flashMode == CameraMetadata.CONTROL_AE_MODE_ON_AUTO_FLASH) {

            builder.set(CaptureRequest.FLASH_MODE, CameraMetadata.FLASH_MODE_OFF);
        }
        else if (flashMode == CameraMetadata.CONTROL_AE_MODE_ON_ALWAYS_FLASH) {

            builder.set(CaptureRequest.FLASH_MODE, CameraMetadata.FLASH_MODE_SINGLE);
        }

Keep FLASH_MODE in SINGLE for ALWAYS_FLASH, and OFF when you are using the AE_MODE_FLASH Modes.

You can read more about it in this documentation.

0
votes

Manual flashMode update can be done with this

I see 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
)