You are on page 1of 29

Intro to Android CameraX with Java

Dmytro Zubov, PhD


dmytro.zubov@ucentralasia.org
Naryn, Kyrgyzstan, 4:19pm, November 25, 2022
Lessons learnt last time

• Java arrays: jagged array & array index operator

• Java strings

• Java Android Authentication App Using Firebase


What we gonna discuss today?

• What is Android CameraX?

• CameraX structure

• App that detects the camera’s orientation with


CameraX

• Android Jetpack: Understand the CameraX camera-


support library (Google I/O'19)
What is Android CameraX?

• CameraX is a Jetpack support library, built to help


developers make camera app development easier. It
provides a consistent and easy-to-use API surface that
works across most Android devices, with backward-
compatibility to Android 5.0 (API level 21). CameraX
leverages the capabilities of Camera2 APIs.
 Jetpack is a suite of libraries to help developers follow best
practices, reduce boilerplate code, and write code that works
consistently across Android versions and devices so that
developers can focus on the code they care about
https://developer.android.com/training/camerax
https://developer.android.com/jetpack
CameraX structure

• Developers use CameraX to interface with a device’s camera


through an abstraction called a use case. The following use
cases are currently available:
 Preview: accepts a surface for displaying a preview, such as a PreviewView
 Image analysis: provides CPU-accessible buffers for analysis, such as for
machine learning
 Image capture: captures and saves a photo
• Use cases can be combined and active concurrently. For
example, an app can let the user view the image that the
camera sees using a preview use case, have an image analysis
use case that determines whether the people in the photo
are smiling, and include an image capture use case to take a
picture once they are.
App that detects the camera’s orientation with CameraX
To move the camera in AVD, push
Alt and move the mouse…
• In this exercise, we will develop an app that detects the
camera’s orientation with CameraX:
App that detects the camera’s orientation with
CameraX (cont.)

• Create a New Project in Android Studio and choose the


Empty Activity when prompted:

The project was


developed in
Android Studio
4.0. Can we do
that in the
Android Studio
Dolphin 2021.3.1?

https://medium.com/swlh/introduction-to-androids-camerax-with-java-ca384c522c5
App that detects the camera’s orientation with
CameraX (cont.)

• Configure the project in accord with your preferences:


App that detects the camera’s orientation with
CameraX (cont.)

• Find the build.gradle(Module:app) file under the


Gradle Scripts directory
• Scroll to the bottom of the file and find the dependencies
block. Add the following CameraX dependencies:
def camerax_version = "1.0.0-beta07"
implementation "androidx.camera:camera-camera2:$camerax_version"
implementation "androidx.camera:camera-lifecycle:$camerax_version"
implementation "androidx.camera:camera-view:1.0.0-alpha14"
App that detects the camera’s orientation with
CameraX (cont.)

• In the same file build.gradle(Module:app), find the


android block and add the following to the bottom
before the closing bracket
compileOptions {
sourceCompatibility JavaVersion.VERSION_1_8
targetCompatibility JavaVersion.VERSION_1_8
}
App that detects the camera’s orientation with
CameraX (cont.)

• Add the camera permissions - open the


AndroidManifest.xml under the Manifests directory
and add the following lines:
<uses-feature android:name="android.hardware.camera.any" />
<uses-permission android:name="android.permission.CAMERA" />
• Sync Gradle settings by pressing on the toolbar icon
App that detects the camera’s orientation with
CameraX (cont.)

• Prompt the user for camera permission


 Check if the permission has been granted. If yes, enable
camera; otherwise, ask for permission
 In the MainActivity.java file, add the following code block in
the onCreate method:
Button enableCamera = findViewById(R.id.enableCamera);
enableCamera.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
if (hasCameraPermission()) {
enableCamera();
} else {
requestPermission();
}
}
});
App that detects the camera’s orientation with
CameraX (cont.)

• Method hasCameraPermission() returns True/False


depending on whether the user has given camera
permission to the app:
private boolean hasCameraPermission() {
return ContextCompat.checkSelfPermission(
this,
Manifest.permission.CAMERA
) == PackageManager.PERMISSION_GRANTED;
}
App that detects the camera’s orientation with
CameraX (cont.)

• Method requestPermission() requests permission


from the user so that the app can access the device’s
camera and perform the image analysis:
private void requestPermission() {
ActivityCompat.requestPermissions(
this,
CAMERA_PERMISSION,
CAMERA_REQUEST_CODE
);
}
App that detects the camera’s orientation with
CameraX (cont.)

• Method enableCamera() creates a new Intent object


to start a CameraActivity (pls see the following slides):
private void enableCamera() {
Intent intent = new Intent(this,
CameraActivity.class);
startActivity(intent);
}
App that detects the camera’s orientation with
CameraX (cont.)

• Create a new empty activity CameraActivity


 This activity is responsible for three main tasks: initialize a camera
provider, bind the image analysis case to the camera provider so
that we can use the camera and analyze images, and keep track of
the device’s camera rotation.
App that detects the camera’s orientation with
CameraX (cont.)

• Define the following instance variables in the


CameraActivity class:
private PreviewView previewView;
private ListenableFuture<ProcessCameraProvider> cameraProviderFuture;
private TextView textView;
App that detects the camera’s orientation with
CameraX (cont.)

• In the onCreate() callback of the CameraActivity


class, initialize the instance variables and bind a camera
provider so that we can bind the image analysis case to
it:
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_camera);
previewView = findViewById(R.id.previewView);
cameraProviderFuture = ProcessCameraProvider.getInstance(this);
textView = findViewById(R.id.orientation);
cameraProviderFuture.addListener(new Runnable() {
@Override
public void run() {
try {
ProcessCameraProvider cameraProvider = cameraProviderFuture.get();
bindImageAnalysis(cameraProvider);
} catch (ExecutionException | InterruptedException e) {
e.printStackTrace();
}
}
}, ContextCompat.getMainExecutor(this));
}
App that detects the camera’s orientation with
CameraX (cont.)

• Method bindImageAnalysis() binds the ImageAnalyzer to


the camera provider created in the onCreate method and
listens for changes in the camera’s rotation:
private void bindImageAnalysis(@NonNull ProcessCameraProvider cameraProvider) {
ImageAnalysis imageAnalysis =
new ImageAnalysis.Builder().setTargetResolution(new Size(1280, 720))
.setBackpressureStrategy(ImageAnalysis.STRATEGY_KEEP_ONLY_LATEST).build();
imageAnalysis.setAnalyzer(ContextCompat.getMainExecutor(this), new ImageAnalysis.Analyzer() {
@Override
public void analyze(@NonNull ImageProxy image) {
image.close();
}
});
OrientationEventListener orientationEventListener = new OrientationEventListener(this) {
@Override
public void onOrientationChanged(int orientation) {
textView.setText(Integer.toString(orientation));
}
};
orientationEventListener.enable();
Preview preview = new Preview.Builder().build();
CameraSelector cameraSelector = new CameraSelector.Builder()
.requireLensFacing(CameraSelector.LENS_FACING_BACK).build();
preview.setSurfaceProvider(previewView.createSurfaceProvider());
cameraProvider.bindToLifecycle((LifecycleOwner)this, cameraSelector,
imageAnalysis, preview);
}
App that detects the camera’s orientation with
CameraX (cont.)

• Defining the user interface


 In the activity_main.xml file, add the following xml code:
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">
<TextView
android:layout_width="match_parent"
android:layout_height="500dp"
android:id="@+id/container"
android:textSize="20sp"
android:layout_gravity="center"
android:text="This is a CameraX test app!"
android:gravity="center">
</TextView>

<Button
android:id="@+id/enableCamera"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:gravity="center"
android:text="Open Camera" />
</LinearLayout>
App that detects the camera’s orientation with
CameraX (cont.)

• Defining the user interface


 In the activity_camera.xml file, add the following xml code:
<FrameLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:id="@+id/container">
<androidx.camera.view.PreviewView
android:id="@+id/previewView"
android:layout_width="match_parent"
android:layout_height="match_parent"/>
</FrameLayout>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent">
<TextView
android:id="@+id/orientation"
android:layout_width="match_parent"
android:layout_height="300dp"
android:layout_gravity="center"
android:gravity="center"
android:textSize="100sp"
android:textColor="#9999ff"/>
</LinearLayout>
App that detects the camera’s orientation with
CameraX (cont.)

• When we start our app for


the first time, it asks the user
for permission to use the
camera:
App that detects the camera’s orientation with
CameraX (cont.)

• Then, the activity_main


layout is shown:
App that detects the camera’s orientation with
CameraX (cont.)

• When we tap the button


“OPEN CAMERA”, the
activity_camera layout is

shown:
App that detects the camera’s orientation with
CameraX (cont.)

• Screenshots of the AVD:


Android Jetpack: Understand the CameraX camera-
support library (Google I/O'19)
https://www.youtube.com/watch?v=kuv8uK-5CLY
Do you have any
questions or
comments?
Thank you
for your attention !
In this presentation:
• Some icons were downloaded from flaticon.com and iconscout.com

You might also like