[MUSIC PLAYING]
DONOVAN MCMURRAY: Hi.
Donovan here.
And in this video, we're going to look at the easiest way
to get up and running with CameraX, the CameraController
class.
This video is part of the CameraX foundation series.
So if you aren't familiar with the basics of CameraX,
go back and watch the CameraX concepts video.
Also, we're finishing the app that we started in the CameraX
setup and permissions video.
So make sure you've watched that video as well.
In CameraX, a CameraController provides
most of the CameraX core functionality
in a single class.
It requires little setup code.
And it automatically handles camera initialization, use case
management, target rotation, tap-to-focus, pinch-to-zoom,
and more.
If you need more control, you can still
use CameraX with its CameraProvider class.
And that video link can be found in this video's description.
Before we jump into code, let's take a look
at how CameraController works with CameraX's four use cases.
The Preview use case is required and is always enabled.
Additionally, a CameraX Preview view is required.
The combination of a CameraController and Preview
view is what makes CameraX able to provide
so much functionality out of the box with CameraController.
But if you don't need a preview or if you want more control,
then you might be more interested in using
a CameraProvider instead.
Back to the other use cases, ImageCapture and ImageAnalysis
are enabled by default. VideoCapture is disabled
by default. You can enable or disable
these three use cases with the Set Enabled Use Cases method.
But keep in mind that not all use
cases are compatible with each other on all devices.
See the concurrent Use Cases Documentation link
in the video description for details.
Also, it's important to note that disabling or enabling
use cases after the previewView is showing
will freeze the preview for a brief moment.
Now let's take a look at where we left off in our camera app.
As a reminder, we're building an app that shows a preview
and allows a user to take a photo.
We'll start with implementing the startCamera method.
The code here is pretty simple.
First, we get a reference to our previewView, which we called
viewFinder in our views layout.
Next, we must initialize a CameraController.
The concrete class name that inherits from CameraController
is LifecycleCameraController.
So create a LifecycleCameraController,
passing in the activity's context.
CameraController is lifecycle-aware.
So we need to call bindToLifecycle,
passing in the activity.
If you need a guide on Android lifecycles,
there's a link in the video description.
Also, set the cameraSelector to pick the DEFAULT_FRONT_CAMERA
for a great selfie shot.
If we were to remove this line, the CameraController
would select the DEFAULT_BACK_CAMERA.
Finally, connect everything by setting the previewView's
controller to the LifecycleCameraController
we just created.
There are more configuration options for CameraController.
But for our app's requirements, everything just
works out of the box.
The CameraController Reference link
is in the video description.
And it shows everything that CameraController can do.
So let's run this app on our trusty test device
to see the app in action.
The first thing we see is the permission
prompt to get access to the camera.
I'll select While Using this App so that any time we
open the app in the future, the camera permissions will already
be granted.
And now you can see the front camera is activated
and the preview is being shown.
CameraController also sets up tap-to-focus and pinch-to-zoom.
On tap-to-focus, you'll notice there's no focus point
visualization.
But the focus action is still occurring.
And you can add your own visualization
on the location of the tap if you'd like.
You'll also see, though, the Take Photo button
isn't doing anything currently.
But that's because we haven't set it up yet.
So let's do that now.
In the on create method, get the Image Capture button and call
setOnClickListener on it, invoking the takePhoto function
in the callback.
Now we need to define the takePhoto function.
When the user wants to take a photo,
first define a name to use for the photo file.
Then set up the content values, which
will contain the file configuration for MediaStore
to save the photo.
Next, use the CameraX ImageCapture.OutputFileOptions
builder, passing in the contentResolver
from main activities context, MediaStore's external content
location, and the MediaStore configuration
we set up in content values.
Then call takePicture on the CameraController
to have CameraX handle the image capture, passing in the output
options and executor in which the callback methods will
be run and an onImageSaved callback object for handling
the error and success states.
Let's run this app again to see the new functionality.
So now when we press the Take Photo button,
we see a toast message that the photo was successfully saved.
If we go over to our photo app, we can see the photo there.
Looks great if you ask me.
Congratulations.
You now know how to create a simple camera app using
CameraX's CameraController.
We have a lot of resources that go
even further with the concepts we've
covered in this video series.
So check those out in the video description.
Happy coding.