How does CameraX library can turn ON/OFF the torch?
Asked Answered
U

10

40

I am developing a feature with the possibility of switching the torch into ON/OFF states. Some days ago, we saw a new library from Google in io2019. I came up with an idea, why not use it.

After some time, I don't see any possibilities to use the only torch from the library.

Even in the official documentation, I wasn't able to find any good pieces of information for me, what's more, the sample app from their also don't have to handle my case.

Do you have something in mind what is easy to implement or perhaps you know how to do it with CameraX?

I am worried about using camera or camera2 because the amount of code to be paste is terrible.

Links:

[1] https://developer.android.com/training/camerax

[2] https://proandroiddev.com/android-camerax-preview-analyze-capture-1b3f403a9395

[3] https://github.com/android/camera/tree/master/CameraXBasic

[4] https://github.com/android/camera/tree/master/CameraXBasic

CameraX is an Android Jetpack library that was built with the intent to make camera development easier.

Umont answered 18/5, 2019 at 12:3 Comment(0)
G
32
androidx.camera:camera-core:1.0.0-alpha10

You can check is torch available or not with this:

val camera = cameraProvider.bindToLifecycle(lifecycleOwner, cameraSelector, preview, imageAnalyzer)

camera.cameraInfo.hasFlashUnit()

And you can enable torch with:

camera.cameraControl.enableTorch(true)
Gailgaile answered 21/2, 2020 at 12:32 Comment(1)
thank you so much! I put in the latest syntax in an answer.Minica
M
19

2021 syntax.

Turn on torch on Android, using Java.

Your typical camera preview code (such as from the google example) generally ends like this:

cameraProvider.bindToLifecycle((LifecycleOwner)this,
                 cameraSelector, imageAnalysis, preview);

to turn on/off the torch...

Camera cam = cameraProvider.bindToLifecycle((LifecycleOwner)this,
                 cameraSelector, imageAnalysis, preview);

if ( cam.getCameraInfo().hasFlashUnit() ) {
    cam.getCameraControl().enableTorch(true); // or false
}

and that's it!

Minica answered 11/3, 2021 at 15:6 Comment(4)
editors - cheers, don't remove phrases which are there for the benefit of search enginesMinica
For anyone who just wants to turn flash on, you still need the camera permission to make it work and also at least 1 use case to bind to cameraProvider.Langlauf
@Minica How can we implement auto flash on/off using CameraX?Briney
Got it, ImageCapture.FLASH_MODE_AUTOBriney
S
15

2022 Syntax

imageCapture = ImageCapture.Builder()
                .setFlashMode(ImageCapture.FLASH_MODE_ON)
                    .build()


val camera = cameraProvider.bindToLifecycle(
             this, cameraSelector, preview, imageCapture, imageAnalyzer)
                
if (camera.cameraInfo.hasFlashUnit()) {
     camera.cameraControl.enableTorch(true)
}

Supplemental answered 6/1, 2021 at 8:29 Comment(1)
Make sure you're using at least version '1.2.0-alpha04' in your gradle.build file and this should lead you to success, young Padawan.Epp
C
13

This is one way you can do it (Kotlin). If there is a better way please let me know. Following code assumes you have already established the availability of flash on the device.

Declare a flashMode var

private var flashMode: Int = ImageCapture.FLASH_MODE_OFF

In updateCameraUI set a listener

controls.findViewById<ImageButton>(R.id.flash_button).setOnClickListener {
    when (flashMode) {
        ImageCapture.FLASH_MODE_OFF ->
            flashMode = ImageCapture.FLASH_MODE_ON
        ImageCapture.FLASH_MODE_ON ->
            flashMode = ImageCapture.FLASH_MODE_AUTO
        ImageCapture.FLASH_MODE_AUTO ->
            flashMode = ImageCapture.FLASH_MODE_OFF
    }
    // Re-bind use cases to include changes
    bindCameraUseCases()
}

In bindCameraUseCases set the flash mode

            imageCapture = ImageCapture.Builder()
                .setCaptureMode(ImageCapture.CAPTURE_MODE_MAXIMIZE_QUALITY)
                .setTargetAspectRatio(screenAspectRatio)
                .setTargetResolution(screenSize)
                .setTargetRotation(rotation)
                .setFlashMode(flashMode)
                .build()
Cannoneer answered 26/3, 2020 at 11:45 Comment(1)
No need to bindCameraUseCase again after changing the flashMode from clicklistenerBriney
D
10
// CameraX
def cameraXVersion = "1.0.0-beta07"
implementation "androidx.camera:camera-camera2:$cameraXVersion"
implementation "androidx.camera:camera-lifecycle:$cameraXVersion"
implementation "androidx.camera:camera-view:1.0.0-alpha14"

    private fun initializeFlashButton() = with(binding) {
        camera?.apply {
            if (cameraInfo.hasFlashUnit()) {
                flashButton.setOnClickListener {
                    flashButton.visibility = View.VISIBLE
                    cameraControl.enableTorch(cameraInfo.torchState.value == TorchState.OFF)
                }
            } else {
                flashButton.visibility = View.GONE
            }

            cameraInfo.torchState.observe(viewLifecycleOwner) { torchState ->
                if (torchState == TorchState.OFF) {
                    flashButton.setImageResource(R.drawable.ic_flash)
                } else {
                    flashButton.setImageResource(R.drawable.ic_flash_active)
                }
            }
        }
    }

You need execute this method after initialize camera object

Dedans answered 29/7, 2020 at 19:43 Comment(1)
Brilliant answer. Thanks for taking advantage of observing the torch state. Could use a little more explanation though. Still a great answer.Wellheeled
C
9

I can't comment so I'm answering to expand on yevhen_69's answer.

Setting enabledTorch(true) didn't work for me either, however I found I had to set enableTorch(true) after the call to CameraX.bindToLifecycle

val previewConfig = PreviewConfig.Builder().apply {
        setLensFacing(lensFacing)
        // Any setup
        setTargetRotation(viewFinder.display.rotation)
}.build()

val preview = Preview(previewConfig)

CameraX.bindToLifecycle(this, preview)
preview.enableTorch(true)

However on a side note, CameraX is still in Alpha so its advisable still to use Camera2 API.

Cineaste answered 13/8, 2019 at 20:19 Comment(0)
D
5

Use CameraControl as global variable and boolean for turn off and on.

 lateinit var cameraControl: CameraControl
 private var flashFlag: Boolean = true

Turn off and on by click listener.

flashFlag = !flashFlag
cameraControl.enableTorch(flashFlag)

In this function I have started the camera preview.

private fun startCamera() {
        val cameraProviderFuture = ProcessCameraProvider.getInstance(this)

        cameraProviderFuture.addListener({
            // Used to bind the lifecycle of cameras to the lifecycle owner
            val cameraProvider: ProcessCameraProvider = cameraProviderFuture.get()

            // Preview
            val preview = Preview.Builder()
                .build()
                .also {
                    it.setSurfaceProvider(binding.cameraView.surfaceProvider)
                }

            // Select back camera as a default
            val cameraSelector = CameraSelector.DEFAULT_BACK_CAMERA

            try {
                // Unbind use cases before rebinding
                cameraProvider.unbindAll()

                // Bind use cases to camera
                val camera = cameraProvider.bindToLifecycle(
                    this, cameraSelector, preview
                )
                cameraControl = camera.cameraControl
                cameraControl.enableTorch(flashFlag)

            } catch (exc: Exception) {
                Log.e(TAG, "Use case binding failed", exc)
            }

        }, ContextCompat.getMainExecutor(this))
    }
Drucill answered 11/10, 2021 at 12:36 Comment(4)
What is the binding?Burgin
that's for viewBinding, You can just call your cameraView here.Drucill
what about auto flash mode?Briney
you can use auto flash mode like this imageCapture?.flashMode = ImageCapture.FLASH_MODE_AUTODrucill
D
3
val previewConfig = PreviewConfig.Builder().apply {
            setLensFacing(lensFacing)
            // Any setup
            setTargetRotation(viewFinder.display.rotation)
}.build()

val preview = Preview(previewConfig)

preview.enableTorch(true)
Dilan answered 21/5, 2019 at 13:23 Comment(2)
Sorry but enableTorch does not seem to work on my Huawei P10 Lite using Android 8.0. Preview is working fine but it seems that it just does not care about enableTorch(true). ¯_(ツ)_/¯ Any ideas?Wink
enableTorch is no longer a method of the class Preview; see developer.android.com/reference/androidx/camera/core/…Moralist
R
3
androidx.camera:camera-core:1.0.0-alpha06

CameraX new release provide these features. CameraInfo added with check Flash Available and Sensor Rotation APIs, refer this link

try {
    CameraInfo cameraInfo = CameraX.getCameraInfo(currentCameraLensFacing);
    LiveData<Boolean> isFlashAvailable = cameraInfo.isFlashAvailable();
    flashToggle.setVisibility(isFlashAvailable.getValue() ? View.VISIBLE : View.INVISIBLE);
} catch (CameraInfoUnavailableException e) {
    Log.w(TAG, "Cannot get flash available information", e);
    flashToggle.setVisibility(View.VISIBLE);
}
Rhythmical answered 18/10, 2019 at 6:51 Comment(2)
Where is this class CameraX you are using? I think CameraX is a library not a class, I cannot find any static method CameraX.getCameraInfo like what you have called here. also, this code snippet will only check the flash state and set the visibility of a toggle based on the flash state, it won't actually set the flash stateMoralist
This is the example when cameraX is in alpha, in latest version may be this class removed.Rhythmical
A
2

You can enable the torch on the Preview object. https://developer.android.com/reference/androidx/camera/core/Preview.html#enableTorch(boolean)

And you can set the flash mode (on/off/auto) on the ImageCapture object or on the config builder associated. https://developer.android.com/reference/androidx/camera/core/ImageCapture.html#setFlashMode(androidx.camera.core.FlashMode) https://developer.android.com/reference/androidx/camera/core/ImageCaptureConfig.Builder.html#setFlashMode(androidx.camera.core.FlashMode)

Avent answered 20/5, 2019 at 12:33 Comment(1)
Looks like that method enableTorch has now since removed from the APIMoralist

© 2022 - 2024 — McMap. All rights reserved.