2

Based on CameraX Basics and Introduction to CAmeraX tutorials, I successfully created an activity that opens Camera inside that activity. I want to switch the camera between front and back on a button click. I use the following code to do that:

@Override
protected void onCreate(Bundle savedInstanceState)
{
     ...

     cameraOrientation = CameraX.LensFacing.BACK;
     StartCamera();

     switchCamera.setOnClickListener(new View.OnClickListener()
     {
         @SuppressLint("RestrictedApi")
         @Override
         public void onClick(View view)
         {
             CameraX.unbindAll();

             cameraOrientation = (cameraOrientation == CameraX.LensFacing.BACK ? CameraX.LensFacing.FRONT : CameraX.LensFacing.BACK);
             try {
                 StartCamera();
             } catch (Exception e) {
                 Toast.makeText(context, "Error", Toast.LENGTH_SHORT).show(); }
         }
     });
 }

private void StartCamera()
{
    previewConfig = new PreviewConfig.Builder()
            .setLensFacing(cameraOrientation)
            .build();
    preview = new Preview(previewConfig);
    preview.setOnPreviewOutputUpdateListener(
            new Preview.OnPreviewOutputUpdateListener()
            {
                @Override
                public void onUpdated(Preview.PreviewOutput previewOutput)
                {
                    textureView.setSurfaceTexture(previewOutput.getSurfaceTexture());
                }
            });

    imageCaptureConfig = new ImageCaptureConfig.Builder()
            .setLensFacing(cameraOrientation)
            .setFlashMode(flashMode)
            .build();
    imageCapture = new ImageCapture(imageCaptureConfig);

    CameraX.bindToLifecycle(SampleCameraActivity.this, imageCapture, preview);
}

But, when I click on the button, the app becomes stuck (but it doesn't crash) and this error keeps repeatedly showing on the log:

E/GLConsumer: [SurfaceTexture-0–6996–1] updateAndRelease: GLConsumer is not attached to an OpenGL ES context

I also switch flash mode and take picture using this api and all those works fine. I also have tested in multiple devices. Same error in all those devices.

frogatto
  • 28,539
  • 11
  • 83
  • 129
Jayesh Babu
  • 1,389
  • 2
  • 20
  • 34

2 Answers2

1

I had the same problem a few days ago, a similar issue existed, but the proposed solution didn't work for me. What worked was slightly modifying the method bindCameraUseCases() from the official sample (which was linked to in the similar issue). Call startCamera() from onCreate().

private fun startCamera() {
    texture.post { bindCameraUseCases() }
    //btn_take_picture.setOnClickListener { takePhoto() } 
    btn_swap_camera.setOnClickListener {swapCamera()}
}

@SuppressLint("RestrictedApi")
private fun swapCamera() {
    lensFacing = when (lensFacing) {
        CameraX.LensFacing.BACK -> CameraX.LensFacing.FRONT
        CameraX.LensFacing.FRONT -> CameraX.LensFacing.BACK
        else -> CameraX.LensFacing.BACK
    }
    CameraX.getCameraWithLensFacing(lensFacing)
    bindCameraUseCases()
}

// Slightly modified code from the sample
private fun bindCameraUseCases() {
    CameraX.unbindAll()

    val metrics = DisplayMetrics().also { texture.display.getRealMetrics(it) }
    val screenAspectRatio = Rational(metrics.widthPixels, metrics.heightPixels)

    val viewFinderConfig = PreviewConfig.Builder().apply {
        setLensFacing(lensFacing)
        setTargetAspectRatio(screenAspectRatio)
        setTargetRotation(texture.display.rotation)
    }.build()

    preview = AutoFitPreviewBuilder.build(viewFinderConfig, texture) // See note below

    val imageCaptureConfig = ImageCaptureConfig.Builder().apply {
        setLensFacing(lensFacing)
        setCaptureMode(ImageCapture.CaptureMode.MIN_LATENCY)
        setTargetAspectRatio(screenAspectRatio)
        setTargetRotation(texture.display.rotation)
    }.build()

    imageCapture = ImageCapture(imageCaptureConfig)

    CameraX.bindToLifecycle(this, preview, imageCapture)
}

Note the class AutoFitPreviewBuilder is from the sample and can be found here (The samples is Apache 2.0 lisenced by Google so the usage should be fair)

Tor-Martin Holen
  • 1,359
  • 1
  • 13
  • 19
  • Thank u for ur answer. I just want to know that u used `AutoFitPreviewBuilder` instead of `Preview`. Is that the only main difference from ur code to my code? – Jayesh Babu Sep 20 '19 at 12:34
  • That do seems to be the main difference. Given that the error you receive is linked to the `TextureView`'s `SurfaceTexture` used in the `Preview` I can't think of anything else that may be the cause of the problem. – Tor-Martin Holen Sep 20 '19 at 13:02
  • I have looked at that class. But I didn't use it because that class is in Kotlin. I am using Java. – Jayesh Babu Sep 20 '19 at 13:57
0

Just look for the imageCapture object and add .setFlashMode(FlashMode.ON) to it's functions eg

private fun createCaptureUseCase(): ImageCapture {
    val imageCaptureConfig = ImageCaptureConfig.Builder()
            //when capturaing turn on flash
        .setFlashMode(FlashMode.ON)
            //set LensFacing and rotation
        .apply {
            setLensFacing(lensFacing)
            setTargetRotation(previewView.display.rotation)
            setCaptureMode(ImageCapture.CaptureMode.MAX_QUALITY)
        }
FEELIX
  • 407
  • 4
  • 8