Google is committed to advancing racial equity for Black communities. See how.

Implement a preview

When adding a preview to your app, use PreviewView, which is a View that can be cropped, scaled, and rotated for proper display.

The image preview streams to a surface inside the PreviewView when the camera becomes active.

Use the PreviewView

Implementing a preview for CameraX using PreviewView involves the following steps, which are covered in later sections:

  1. Optionally configure a CameraXConfig.Provider.
  2. Add a PreviewView to your layout.
  3. Request a CameraProvider.
  4. On View creation, check for the CameraProvider.
  5. Select a camera and bind the lifecycle and use cases.

Using PreviewView has some limitations. When using PreviewView, you can't do any of the following things:

  • Create a SurfaceTexture to set on TextureView and PreviewSurfaceProvider.
  • Retrieve the SurfaceTexture from TextureView and set it on PreviewSurfaceProvider.
  • Get the Surface from SurfaceView and set it on PreviewSurfaceProvider.

If any of these happen, then the Preview will stop streaming frames to the PreviewView.

[Optional] Configure a CameraXConfig.Provider

If you want fine control over when CameraX gets initialized, you can implement the CameraXConfig.Provider interface in your Application class. Note that most apps do not require this level of control.

Kotlin

import androidx.camera.camera2.Camera2Config
import androidx.camera.core.CameraXConfig

public class MyCameraXApplication : Application(),  CameraXConfig.Provider {
  override fun getCameraXConfig(): CameraXConfig {
    return Camera2Config.defaultConfig()
  }
}

Java

import androidx.camera.camera2.Camera2Config;
import androidx.camera.core.CameraXConfig;

public class MyCameraXApplication extends Application implements CameraXConfig.Provider {
    @NonNull
    @Override
    public CameraXConfig getCameraXConfig() {
        return Camera2Config.defaultConfig();
    }
}

Add a PreviewView to your layout

The following sample shows a PreviewView in a layout:

<FrameLayout
    android:id="@+id/container">
        <androidx.camera.view.PreviewView
            android:id="@+id/previewView" />
</FrameLayout>

Request a CameraProvider

The following code shows how to request a CameraProvider:

Kotlin

import androidx.camera.lifecycle.ProcessCameraProvider
import com.google.common.util.concurrent.ListenableFuture

class MainActivity : AppCompatActivity() {
    private lateinit var cameraProviderFuture : ListenableFuture<ProcessCameraProvider>
    override fun onCreate(savedInstanceState: Bundle?) {
        cameraProviderFuture = ProcessCameraProvider.getInstance(this)
    }
}

Java

import androidx.camera.lifecycle.ProcessCameraProvider
import com.google.common.util.concurrent.ListenableFuture

public class MainActivity extends AppCompatActivity {
    private ListenableFuture<ProcessCameraProvider> cameraProviderFuture;

    @Override
    protected void onCreate(@Nullable Bundle savedInstanceState) {
        cameraProviderFuture = ProcessCameraProvider.getInstance(this);
    }
}

Check for CameraProvider availability

After requesting a CameraProvider, verify that its initialization succeeded when the view is created. The following code shows how to do this:

Kotlin

cameraProviderFuture.addListener(Runnable {
    val cameraProvider = cameraProviderFuture.get()
    bindPreview(cameraProvider)
}, ContextCompat.getMainExecutor(this))

Java

cameraProviderFuture.addListener(() -> {
    try {
        ProcessCameraProvider cameraProvider = cameraProviderFuture.get();
        bindPreview(cameraProvider);
    } catch (ExecutionException | InterruptedException e) {
        // No errors need to be handled for this Future.
        // This should never be reached.
    }
}, ContextCompat.getMainExecutor(this));

For an example of the bindPreview function used in this sample, see the code provided in Select a camera and bind the lifecycle and use cases.

Select a camera and bind the lifecycle and use cases

Once you have created and confirmed the CameraProvider, do the following:

  1. Create a Preview.
  2. Specify the desired camera LensFacing option.
  3. Bind the selected camera and any use cases to the lifecycle.
  4. Connect the Preview to the PreviewView.

The following code shows an example:

Kotlin

fun bindPreview(cameraProvider : ProcessCameraProvider) {
    var preview : Preview = Preview.Builder()
            .build()

    var cameraSelector : CameraSelector = CameraSelector.Builder()
          .requireLensFacing(CameraSelector.LENS_FACING_BACK)
          .build()

    preview.setSurfaceProvider(previewView.getSurfaceProvider())

    var camera = cameraProvider.bindToLifecycle(this as LifecycleOwner, cameraSelector, preview)
}

Java

void bindPreview(@NonNull ProcessCameraProvider cameraProvider) {
    Preview preview = new Preview.Builder()
            .build();

    CameraSelector cameraSelector = new CameraSelector.Builder()
            .requireLensFacing(CameraSelector.LENS_FACING_BACK)
            .build();

    preview.setSurfaceProvider(previewView.getSurfaceProvider());

    Camera camera = cameraProvider.bindToLifecycle((LifecycleOwner)this, cameraSelector, preview);
}

You are now done implementing the camera preview. Build your app and confirm that your preview appears in your app and functions as you intend it to.

Additional resources

To learn more about CameraX, see the following additional resources.

Codelab

  • Getting Started with CameraX
  • Code sample

  • Official CameraX sample app