CameraX: Make photography easier on Android!

Goodbye complicated Camera2 API, and hello CameraX. Explore the new features that makes CameraX easier to implement.

Bapusaheb Patil
4 min readSep 7, 2019

--

This post was originally published on Codementor.

A throwback to Google I/O 2019…

One of the most exciting changes that Google announced this year at Google I/O 2019 is CameraX. It is an API that will bring a slew of new features and, supposedly, makes implementing camera features easier on Android.

But how is this better than the current Camera2 API? Does CameraX really have a lot to offer or is it just a gimmick?

Let’s find out in this article. But first, let’s take a peek at how the Camera2 API is being implemented in apps these days.

Note: The Camera2 API, which replaced the legacy Camera API, gives you more control over your device’s camera. But also keep in mind that the Camera2 API supports Lollipop 5.0 and above, so if you want to support devices lower than that, you’d have to stick to the legacy Camera API.

The (now-outdated?) Camera2 API

We will be focusing on capturing photos with a custom camera UI in Android in this article. We will be leaving out videos since a video implementation in Android requires a separate article of its own.

Let’s take a look at a basic implementation for capturing photos with the Camera2 API.

First, we’d have to set up a TextureView and Button in our layout to capture the image:

<RelativeLayout 
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent">
<TextureView
android:id="@+id/texture_view"
android:layout_width="match_parent"
android:layout_height="match_parent"
… />
<Button
android:id="@+id/btn_capture"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
… />
</RelativeLayout>

Then, we’d have to setup a camera preview, like so:

try {
val texture = texture_view.getSurfaceTexture()
texture.setDefaultBufferSize(imageDimension.getWidth(), imageDimension.getHeight())
val surface = Surface(texture)
captureRequestBuilder = cameraDevice.createCaptureRequest(CameraDevice.TEMPLATE_PREVIEW)
captureRequestBuilder.addTarget(surface)
cameraDevice.createCaptureSession(Arrays.asList(surface), object:CameraCaptureSession.StateCallback() {
fun onConfigured(@NonNull cameraCaptureSession:CameraCaptureSession) {
if (null == cameraDevice)
{
return
}
cameraCaptureSessions = cameraCaptureSession
updatePreview()
}
fun onConfigureFailed(@NonNull cameraCaptureSession:CameraCaptureSession) {
Toast.makeText(this@AndroidCameraApi, "Configuration changed!", Toast.LENGTH_SHORT).show()
}
}, null)
} catch (e:CameraAccessException) {
e.printStackTrace()
}

We still need to:

  • Get an instance of the CameraManager
  • Get the CameraCharacteristics and StreamConfigurationMap
  • Setup a CameraDevice.StateCallback and CameraCaptureSession.CaptureCallback for the image preview and image capture respectively
  • Setup the TextureView.SurfaceTextureListener for the preview on the TextureView
  • Open the camera
  • Write code for taking the picture
  • Write code for updating the preview
  • Close the camera when it isn’t in use

Phew! That sounds like a lot of work! I wouldn’t want to spend the rest of this article going on about how to implement the Camera2 API. So let’s cut it short here and talk about why Camera2 API is a real pain to implement in an Android app:

  • It requires a ton of code, as you can infer from above. This is a huge drawback if you’re new to implementing camera in Android.
  • It’s just too complex. A lot of the code in the API could be simplified, but because the API was designed to provide more control over the camera, it has become too difficult to comprehend for developers who are new to implementing camera in their app.
  • It requires you to implement a lot of states, and you’ll be required to execute a bunch of specific methods to handle when these states change. You can take a look at the exhausting list of states here.
  • It also introduces some bugs in the flashlight part of your camera. There’s a lot of confusion regarding the differences between a “torch” mode and a “flash” mode in Camera2.
  • If this isn’t already enough to drive new developers from Camera2, there are a lot of bugs that are vendor-specific that require fixing and hence, more code. These are also known as device compatibility issues, which require the developers to write device-specific code to manage a work-around to the solution.

While the legacy Camera API is easier to use and supports lower Android OS devices, it doesn’t provide a lot of control over the camera. It isn’t short of its own bugs and vendor-specific issues either. It shares a lot of the same unpredictable issues as the Camera2 API and hence, isn’t a good idea to implement in your custom camera.

With these hurdles in mind, Google introduced the new CameraX API to solve these issues.

To read the rest of the article, click on the following link:

--

--

Bapusaheb Patil

Award-Winning Designer • Design Book Author • Video Course Creator