камера X отменена другим начальным фокусом и измерением

#java #android #kotlin #android-camera #android-camerax

#java #Android #kotlin #android-камера #android-camerax

Вопрос:

Я реализую пользовательскую камеру, используя библиотеку CameraX. Я работаю над фокусировкой, и я сделал следующие вещи

 viewFinder.setOnTouchListener { v, event ->
            return@setOnTouchListener when (event.action) {
                MotionEvent.ACTION_DOWN -> {
                    true
                }
                MotionEvent.ACTION_UP -> {
                   // The below code is for focusing 

                    val factory = SurfaceOrientedMeteringPointFactory(
                        viewFinder.width.toFloat(),
                        viewFinder.height.toFloat()
                    )
                    val point = factory.createPoint(event.x, event.y)
                    try {
                        val action = FocusMeteringAction.Builder(point, FocusMeteringAction.FLAG_AF)
                            .apply {
                                disableAutoCancel() //focus only when the user tap the preview
                            }.build()

                        val future = cameraControl?.startFocusAndMetering(action)
                        future?.addListener(Runnable {
--->line 66                 val result = future?.get()
                            println("log result ---> $result")
                        }, cameraExecutor)

                    } catch (e: CameraInfoUnavailableException) {
                        println("log error ---> $e")
                    }
                    true
                }
                else -> false // Unhandled event.
            }
        }
  

Теперь это то, что фокусирует точку, к которой я прикоснулся, и это не слишком точно, но все в порядке. И при фокусировке после 5-6 раз приложение зависало и закрывалось.

 FATAL EXCEPTION: pool-2-thread-1
...
...
java.lang.Error: java.util.concurrent.ExecutionException: androidx.camera.core.CameraControl$OperationCanceledException: Cancelled by another startFocusAndMetering()
...
...
...MainActivity$onCreate$2$1.run(MainActivity.kt:66)
  

Я не понимаю, почему он падает, и он не часто падает. Иногда это приведет к сбою, а иногда нет.

Редактировать 1 :-

Я узнал, что когда я нажимаю фокус несколько раз, это происходит. Итак, перед началом фокусировки мне нужно очистить предыдущий фокус, если он выполняется. Но, как очистить предыдущий фокус, я не понимаю.

Редактировать 2 :-

Я попробовал это cameraControl?.cancelFocusAndMetering() , я просто поместил это в первую строку блока try. но проблема все еще существует.

Ответ №1:

Прошу прощения за java-код здесь. Но, по моему опыту, future?.get() должен быть заключен в try, catch

 future.addListener(() -> {

    try
        {
            FocusMeteringResult result = (FocusMeteringResult) future.get();
            if(result.isFocusSuccessful())
            {
                // Focus has succeeded
            }
            else
            {
                // Focus has failed
            }
        }
        catch (ExecutionException e) // Thrown exceptions
        {
            e.printStackTrace();
        }
        catch (InterruptedException e) // Thrown exceptions
        {
            e.printStackTrace();
        }
}
  

Ответ №2:

Я только что удалил этот блок

 future?.addListener(Runnable {
          val result = future?.get()
          println("log result ---> $result")
       }, cameraExecutor)

  

и все работает нормально. Но я не знаю, правильно это или неправильно.

Если кто-нибудь знает? пожалуйста, ответьте. в настоящее время я отмечаю это как ответ, поскольку он работал.

Комментарии:

1. При вызове CameraControl.startFocusAndMetering() , если предыдущее действие замера все еще выполняется, оно отменяется. Будущее отменяется и завершается ошибкой с исключением, которое вы видите в logcat. Вы не должны беспокоиться об этом. Вызов CameraControl.cancelFocusAndMetering() делает то же самое, он отменяет любые текущие действия по измерению, но с немного другим сообщением об ошибке, которое вы, возможно, заметили.

2. @HusaynHakeem Спасибо, но когда я вставил future?.addListener приложение, оно зависало и закрывалось, даже когда я вставил это в try catch. Можете ли вы показать мне какой-нибудь код о том, как с этим справиться.

3. Сбой приложения из-за фрагмента в вашем ответе ( future?.addListener(...) )? Для примера кода взгляните на этот пример .

4. @HusaynHakeem Да, когда приложение разбилось, оно всегда указывает на строку val result = future?.get() .

5. Я тоже испытывал это — хотел бы я знать, был ли фокус успешным или нет!