CameraX库如何打开/关闭手电筒?

39

我正在开发一个功能,可以将手电筒切换到开/关状态。几天前,我们在 io2019 上看到了 Google 的一个新库。我想到了一个主意,为什么不使用它呢。

经过一段时间,我没有看到任何使用该库中唯一的手电筒的可能性。

即使在官方文档中,我也找不到对我有用的好信息,更重要的是,他们的示例应用程序也无法处理我的情况。

你是否有想法可以轻松实施,或者您知道如何使用 CameraX 进行操作?

我担心使用相机或相机2,因为要粘贴的代码量太多了。

链接:

[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 是一个 Android Jetpack 库,旨在使相机开发更加简便。

10个回答

31
androidx.camera:camera-core:1.0.0-alpha10
您可以使用以下代码检查是否可用torch:

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

camera.cameraInfo.hasFlashUnit()

你可以使用以下方式启用手电筒:

camera.cameraControl.enableTorch(true)

非常感谢!我在答案中使用了最新的语法。 - Fattie

19

2021语法。

使用Java在Android上打开手电筒。

通常的相机预览代码(例如来自Google示例的代码)通常以这样结束:

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

打开/关闭手电筒...

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

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

就是这样!


1
编辑器 - 干杯,不要删除那些为搜索引擎优化而存在的短语。 - Fattie
对于只想打开闪光灯的人,你仍然需要相机权限才能使其工作,并且至少需要一个用例来绑定到相机提供程序。 - Ranjan
@Fattie 我们如何使用CameraX实现自动闪光灯开关? - Astha Garg
1
明白了,ImageCapture.FLASH_MODE_AUTO。 - Astha Garg

15

2022 语法

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)
}


请确保在您的gradle.build文件中使用至少版本为“1.2.0-alpha04”,这将引导您走向成功,年轻的帕达万。 - Grant

13

这是一种你可以用 Kotlin 实现的方法。如果有更好的方法,请告诉我。以下代码假定您已经确定设备上存在闪光灯。

声明一个 flashMode 变量。

private var flashMode: Int = ImageCapture.FLASH_MODE_OFF
在 updateCameraUI 中设置一个监听器。
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()
}
在bindCameraUseCases中设置闪光灯模式。
            imageCapture = ImageCapture.Builder()
                .setCaptureMode(ImageCapture.CAPTURE_MODE_MAXIMIZE_QUALITY)
                .setTargetAspectRatio(screenAspectRatio)
                .setTargetResolution(screenSize)
                .setTargetRotation(rotation)
                .setFlashMode(flashMode)
                .build()

在从clicklistener更改flashMode后,无需重新绑定相机用例。 - Astha Garg

9
// 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)
                }
            }
        }
    }

在初始化相机对象之后,需要执行此方法。


非常棒的回答。感谢您利用观察火炬状态的优势。不过可能需要更多的解释。仍然是一个很好的答案。 - Sakiboy

9
我无法评论,因此我正在回答以扩展yevhen_69的答案。
在我的情况下,设置enabledTorch(true)也不起作用,但是我发现必须在调用CameraX.bindToLifecycle之后设置enableTorch(true)。
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)

然而需要注意的是,CameraX仍处于Alpha版本,因此建议仍然使用Camera2 API。


5

CameraControl作为全局变量和布尔值使用,用于开启和关闭。

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

通过点击监听器关闭和打开。

flashFlag = !flashFlag
cameraControl.enableTorch(flashFlag)

在这个函数中,我已经开始了相机的预览。
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))
    }

什么是绑定? - Alexandr
这是关于viewBinding的,你可以在这里直接调用你的cameraView。 - ahmad bajwa
自动闪光模式怎么样? - Astha Garg
您可以像这样使用自动闪光模式:imageCapture?.flashMode = ImageCapture.FLASH_MODE_AUTO - ahmad bajwa

3
androidx.camera:camera-core:1.0.0-alpha06

CameraX新发布提供了以下功能。添加了CameraInfo API,其中包括Flash是否可用以及Sensor Rotation(传感器旋转)API,请参阅此链接

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);
}

你使用的 CameraX 类在哪里?我认为 CameraX 是一个库而不是一个类,我找不到任何静态方法 CameraX.getCameraInfo,就像你在这里调用的那样。此外,这段代码片段只会检查闪光灯状态并根据闪光灯状态设置切换按钮的可见性,它实际上不会设置闪光灯状态。 - Adam Burley
这是当CameraX处于alpha版本时的示例,在最新版本中可能已经删除了这个类。 - Akshay Raiyani

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

val preview = Preview(previewConfig)

preview.enableTorch(true)

抱歉,但在我的华为P10 Lite上使用Android 8.0时,enableTorch似乎无法正常工作。预览功能正常,但它似乎并不关心enableTorch(true)。¯_(ツ)_/¯有什么想法吗? - Pluto1010
enableTorch 不再是 Preview 类的一个方法;请参阅 https://developer.android.com/reference/androidx/camera/core/Preview.html。 - Adam Burley

2

似乎enableTorch方法已从API中删除。 - Adam Burley

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接