I've implemented a new sample, here is a link which describes new CameraX api from Google codelabs, but TextureView doesn't show anything and throw next exception:
OpenGLRenderer: [SurfaceTexture-0-7609-1] dequeueImage: SurfaceTexture is not attached to a View
Another camera samples as a Camera2 and native camera app work fine I used emulator with api level Q beta 3
class CameraXFragment : Fragment(), TextureView.SurfaceTextureListener { companion object { fun newInstance(): Fragment = CameraXFragment() } private val REQUEST_CODE_PERMISSIONS = 10 private val REQUIRED_PERMISSIONS = arrayOf(Manifest.permission.CAMERA, Manifest.permission.WRITE_EXTERNAL_STORAGE) override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View? = inflater.inflate(R.layout.fragment_camera, container, false) override fun onViewCreated(view: View, savedInstanceState: Bundle?) { super.onViewCreated(view, savedInstanceState) viewFinder.surfaceTextureListener = this } private fun startCamera() { CameraX.unbindAll() val previewConfig = PreviewConfig.Builder().apply { setTargetAspectRatio(Rational(1, 1)) setTargetResolution(Size(320, 320)) }.build() val preview = Preview(previewConfig) preview.setOnPreviewOutputUpdateListener { viewFinder.surfaceTexture = it.surfaceTexture updateTransform() } val imageCaptureConfig = ImageCaptureConfig.Builder() .apply { setTargetAspectRatio(Rational(1, 1)) setCaptureMode(ImageCapture.CaptureMode.MIN_LATENCY) }.build() val imageCapture = ImageCapture(imageCaptureConfig) captureButton.setOnClickListener { val file = File(Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_DCIM), "${System.currentTimeMillis()}.jpg") imageCapture.takePicture(file, object : ImageCapture.OnImageSavedListener { override fun onError(error: ImageCapture.UseCaseError, message: String, t: Throwable?) { t?.printStackTrace() } override fun onImageSaved(file: File) { val msg = "Photo capture succeeded: ${file.absolutePath}" Toast.makeText(requireContext(), msg, Toast.LENGTH_SHORT).show() } }) } CameraX.bindToLifecycle(this, preview, imageCapture) } private fun updateTransform() { val matrix = Matrix() val centerX = viewFinder.width / 2f val centerY = viewFinder.height / 2f val rotationDegrees = when (viewFinder.display.rotation) { Surface.ROTATION_0 -> 0 Surface.ROTATION_90 -> 90 Surface.ROTATION_180 -> 180 Surface.ROTATION_270 -> 270 else -> return } matrix.postRotate(-rotationDegrees.toFloat(), centerX, centerY) viewFinder.setTransform(matrix) } override fun onSurfaceTextureSizeChanged(surface: SurfaceTexture, width: Int, height: Int) { } override fun onSurfaceTextureUpdated(surface: SurfaceTexture) { } override fun onSurfaceTextureDestroyed(surface: SurfaceTexture): Boolean { return true } override fun onSurfaceTextureAvailable(surface: SurfaceTexture?, width: Int, height: Int) { if (allPermissionsGranted()) { viewFinder.post { startCamera() } } else { requestPermissions(REQUIRED_PERMISSIONS, REQUEST_CODE_PERMISSIONS) } viewFinder.addOnLayoutChangeListener { _, _, _, _, _, _, _, _, _ -> updateTransform() } } override fun onRequestPermissionsResult(requestCode: Int, permissions: Array, grantResults: IntArray) { if (requestCode == REQUEST_CODE_PERMISSIONS) { if (allPermissionsGranted()) { viewFinder.post { startCamera() } } else { Toast.makeText(requireContext(), "Permissions are not granted", Toast.LENGTH_SHORT).show() } } } private fun allPermissionsGranted(): Boolean { for (permission in REQUIRED_PERMISSIONS) { if (ContextCompat.checkSelfPermission(requireContext(), permission) != PackageManager.PERMISSION_GRANTED) { return false } } return true } }