【问题标题】:How does CameraX library can turn ON/OFF the torch?CameraX 库如何打开/关闭手电筒?
【发布时间】:2019-10-05 12:20:33
【问题描述】:

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

【问题讨论】:

    标签: android camera android-camera flashlight android-camerax


    【解决方案1】:
    androidx.camera:camera-core:1.0.0-alpha10
    

    你可以用这个检查手电筒是否可用:

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

    您可以通过以下方式启用手电筒:

    camera.cameraControl.enableTorch(true)
    

    【讨论】:

    • 非常感谢!我在答案中输入了最新的语法。
    【解决方案2】:

    这是您可以做到的一种方式(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()
    

    【讨论】:

    • 有帮助...谢谢
    【解决方案3】:

    2021 语法。

    使用 Java 在 Android 上打开 Torch。

    您的典型相机预览代码(例如来自 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 个用例才能绑定到 cameraProvider。
    【解决方案4】:

    我无法发表评论,所以我正在回答以扩展 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】:
      // 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对象后需要执行该方法

      【讨论】:

      • 出色的答案。感谢您利用观察火炬状态。不过可以使用更多的解释。仍然是一个很好的答案。
      【解决方案6】:

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

      【讨论】:

        【解决方案7】:
        val previewConfig = PreviewConfig.Builder().apply {
                    setLensFacing(lensFacing)
                    // Any setup
                    setTargetRotation(viewFinder.display.rotation)
        }.build()
        
        val preview = Preview(previewConfig)
        
        preview.enableTorch(true)
        

        【讨论】:

        • 抱歉,enableTorch 似乎无法在我使用 Android 8.0 的华为 P10 Lite 上运行。预览工作正常,但似乎它并不关心 enableTorch(true)。 ¯_(ツ)_/¯ 有什么想法吗?
        • enableTorch 不再是Preview 类的方法;见developer.android.com/reference/androidx/camera/core/…
        【解决方案8】:
        androidx.camera:camera-core:1.0.0-alpha06
        

        CameraX 新版本提供了这些功能。 CameraInfo 添加了检查 Flash Available 和 Sensor Rotation APIs,参考这个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);
        }
        

        【讨论】:

        • 你正在使用的CameraX这个类在哪里?我认为 CameraX 是一个库而不是一个类,我找不到任何静态方法 CameraX.getCameraInfo 就像你在这里所说的那样。另外,这段代码 sn-p 只会检查 flash 状态并根据 flash 状态设置切换的可见性,它实际上不会设置 flash 状态
        • 这是cameraX处于alpha阶段的例子,在最新版本中可能会移除这个类。
        【解决方案9】:

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

        【讨论】:

        • 什么是绑定?
        • 那是viewBinding,你可以在这里调用你的cameraView。
        【解决方案10】:
        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2015-01-28
        • 2015-12-20
        • 1970-01-01
        • 1970-01-01
        • 2019-03-18
        • 2020-06-04
        • 1970-01-01
        相关资源
        最近更新 更多