How to set viewfinder using CameraX in Java?
I have been working on an app which needed to use CameraX for it's preview stream but it also needs a viewfinder. I have successfully implemented the preview but for the viewfinder part most of the codes that I can find online is in Kotlin and I being a newbie can't seem to effectively convert it to my java based code. Any help would be really appreciated.
My XML preview code:
<androidx.camera.view.PreviewView
android:id="@+id/previewView"
android:layout_width="match_parent"
android:layout_height="675dp"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@+id/toolbar">
My CameraX preview code:
PreviewView mCameraView;
Camera camera;
void startCamera() {
mCameraView = findViewById(R.id.previewView);
cameraProviderFuture = ProcessCameraProvider.getInstance(this);
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));
}
void bindPreview(@NonNull ProcessCameraProvider cameraProvider) {
Preview preview = new Preview.Builder().
setTargetResolution(BestSize())
.build();
CameraSelector cameraSelector = new CameraSelector.Builder()
.requireLensFacing(CameraSelector.LENS_FACING_BACK)
.build();
preview.setSurfaceProvider(mCameraView.createSurfaceProvider());
camera = cameraProvider.bindToLifecycle(this, cameraSelector, preview);
}
private int degreesToFirebaseRotation(int degrees) {
switch (degrees) {
case 0:
return FirebaseVisionImageMetadata.ROTATION_0;
case 90:
return FirebaseVisionImageMetadata.ROTATION_90;
case 180:
return FirebaseVisionImageMetadata.ROTATION_180;
case 270:
return FirebaseVisionImageMetadata.ROTATION_270;
default:
throw new IllegalArgumentException(
"Rotation must be 0, 90, 180, or 270.");
}
}
Sorry for the weird indentation and if the question is stupid. Thanks in advance.
You also need to bind the preview use case to a lifecycle owner.
preview.setSurfaceProvider(mCameraView.createSurfaceProvider());
cameraProvider.unbindAll();
Camera camera = cameraProvider.bindToLifecycle(this, cameraSelector, preview);
// Do stuff with camera
Although this issue may be long gone, I hope it gives a clue to those who follow up.
First I believe you should have seen this sample code from Google: https://developer.android.com/codelabs/camerax-getting-started
where the so-called viewFinder
is actually the id of a component in the xml
layout file, i.e. your R.id.previewView
.
Since the Google example uses the kotlin-android-extensions
plugin, you can use the component's id directly in kotlin code.
It's not unusual that you won't find it in the native kotlin code. Here is the xml file for the Google example.
<?xml version="1.0" encoding="utf-8"? >
<androidx.constraintlayout.widget.ConstraintLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".MainActivity">
<Button
android:id="@+id/camera_capture_button"
android:layout_width="100dp"
android:layout_height="100dp"
android:layout_marginBottom="50dp"
android:scaleType="fitCenter"
android:text="Take Photo"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintBottom_toBottomOf="parent"
android:elevation="2dp" />
<androidx.camera.view.PreviewView
android:id="@+id/viewFinder"
android:layout_width="match_parent"
android:layout_height="match_parent" />
</androidx.constraintlayout.widget.ConstraintLayout>