27

我正在开发一项功能,可以将手电筒切换到开/关状态。几天前,我们在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 库,旨在简化相机开发。

4

10 回答 10

21
androidx.camera:camera-core:1.0.0-alpha10

您可以通过以下方式检查手电筒是否可用:

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

camera.cameraInfo.hasFlashUnit()

您可以通过以下方式启用火炬:

camera.cameraControl.enableTorch(true)
于 2020-02-21T12:32:23.133 回答
12

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
}

就是这样!

于 2021-03-11T15:06:33.643 回答
12

这是您可以做到的一种方式(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()
于 2020-03-26T11:45:45.707 回答
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。

于 2019-08-13T20:19:11.560 回答
8
// 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)
                }
            }
        }
    }

您需要在初始化camera对象后执行此方法

于 2020-07-29T19:43:32.887 回答
7

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

于 2021-01-06T08:29:13.967 回答
3
androidx.camera:camera-core:1.0.0-alpha06

CameraX 新版本提供了这些功能。CameraInfo 添加了检查 Flash 可用和传感器旋转 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);
}
于 2019-10-18T06:51:39.273 回答
3

用作全局变量和布尔值用于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))
    }
于 2021-10-11T12:36:54.943 回答
3
val previewConfig = PreviewConfig.Builder().apply {
            setLensFacing(lensFacing)
            // Any setup
            setTargetRotation(viewFinder.display.rotation)
}.build()

val preview = Preview(previewConfig)

preview.enableTorch(true)
于 2019-05-21T13:23:46.117 回答