In the latest alpha (alpha08
) I can't seem to figure out how to correctly configure everything so that the my Analyzer
runs normally. I can see it work once, then it never runs again.
For various reasons I need to use a TextureView
so I cannot swap to CameraView
, etc.
I'm almost positive it's due to something related to the Futures, but I can't seem to nail it down.
I'm fresh out of ideas. Any thoughts/help appreciated.
I've configured my Application
class with the following:
override fun getCameraXConfig(): CameraXConfig {
return Camera2Config.defaultConfig()
}
And then the following is my MainActivity
code (layout is just a single TextureView
inside a ConstraintLayout
):
import androidx.appcompat.app.AppCompatActivity
import android.os.Bundle
import android.util.Log
import android.util.Size
import android.view.Surface
import android.view.TextureView
import androidx.camera.core.*
import androidx.camera.lifecycle.ProcessCameraProvider
import androidx.concurrent.futures.CallbackToFutureAdapter
import androidx.core.content.ContextCompat
import androidx.lifecycle.LifecycleOwner
import com.google.common.util.concurrent.ListenableFuture
import java.util.concurrent.Executors
class MainActivity : AppCompatActivity() {
private lateinit var viewFinder: TextureView
private lateinit var cameraProviderFuture : ListenableFuture<ProcessCameraProvider>
private val executor = Executors.newSingleThreadExecutor()
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
cameraProviderFuture = ProcessCameraProvider.getInstance(this)
viewFinder = findViewById(R.id.view_finder) // TextureView
startCamera()
}
private fun startCamera() {
val preview = Preview.Builder().apply {
setTargetResolution(Size(640, 480))
}.build()
preview.setPreviewSurfaceProvider { resolution, surfaceReleaseFuture ->
viewFinder.surfaceTexture.setDefaultBufferSize(resolution.width, resolution.height)
val surface = Surface(viewFinder.surfaceTexture)
surfaceReleaseFuture.addListener(
Runnable {
surface.release()
viewFinder.surfaceTexture.release()
},
ContextCompat.getMainExecutor(this)
)
CallbackToFutureAdapter.getFuture<Surface> { completer -> completer.set(surface) }
}
val analyzer = ImageAnalysis.Builder().build()
val analyzerUseCase = analyzer.apply {
setAnalyzer(executor, MyTestAnalyzer())
}
val cameraSelector = CameraSelector.Builder().requireLensFacing(CameraSelector.LENS_FACING_BACK).build()
cameraProviderFuture.addListener(Runnable {
val cameraProvider = cameraProviderFuture.get()
cameraProvider.bindToLifecycle(this as LifecycleOwner, cameraSelector, analyzerUseCase, preview)
}, ContextCompat.getMainExecutor(this))
}
}
private class MyTestAnalyzer : ImageAnalysis.Analyzer {
override fun analyze(image: ImageProxy) {
Log.d("Sandbox", "### Would analyze the image here ...")
}
}