Check Out Mobile Application Proposal

Jetpack Camerax Example Applicaiton | CameraX | Databinding | Video Capture. | video recordings

 


Jetpack Camerax Example Applicaiton | CameraX | Databinding | Video Capture. 

To get started with the cameraX in android studio with java. CameraX is a jetpack library it helps the camera application to built very easy with all the necessary functions developers needed. for more refer here

First you need to implement the cameraX dependencies in your app.build.gradle file update the camerax_version with the current version.

// CameraX core library using camera2 implementation
def camerax_version = "1.0.0"
implementation "androidx.camera:camera-core:${camerax_version}"
implementation "androidx.camera:camera-camera2:${camerax_version}"
implementation "androidx.camera:camera-lifecycle:${camerax_version}"
// CameraX View class
implementation 'androidx.camera:camera-view:1.0.0-alpha28'


Ask for the permission in the AndroidManifest file 

<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE"/>
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.CAMERA"/>
<uses-permission android:name="android.permission.MANAGE_EXTERNAL_STORAGE"
tools:ignore="ScopedStorage"/>

<uses-feature android:name="android.hardware.camera.any"
android:required="true"/>
<uses-permission android:name="android.permission.RECORD_AUDIO"/>
<uses-feature android:name="android.hardware.camera.flash" />

 

if you need audio or flash function just add those permission in the manifest file.

Let's starts building the Image capture Camera . In this example i use the data-binding  method . you can use normal method too.

For enabling data-binding add the below line in your app.build.gradle file inside android tag.

buildFeatures {
dataBinding = true
}

In Xml first add the PriviewView to view the camera image in the screen in this example i added the priview and some images to capture and after capture to show the image . everithing is in there in this xml file . camera_activity.xml

<androidx.camera.view.PreviewView
android:id="@+id/viewFinder"
android:layout_width="match_parent"
android:layout_height="match_parent"/> 

Add this PreviewView component in your camera_activity.xml file. Then add one button for capture the  image from the camera

Initialise the executor and the provider in your oncreate method.  First get the required permission in the starting otherwise you can't see any image or preview in the application.

ExecutorService camaraExecutor = Executors.newSingleThreadExecutor(); 
ListenableFuture<ProcessCameraProvider> cameraProviderFuture = ProcessCameraProvider.getInstance(activity);

 

@RequiresApi(api = Build.VERSION_CODES.M)
@Override
public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {

if(requestCode == REQUEST_CODE_PERMISSIONS){
if (allPermissionsGranted(permissions,activity)) {
startCamera();
} else{
activity.requestPermissions(permissions,1);
Toast.makeText(activity, "Permissions not granted by the user.", Toast.LENGTH_SHORT).show();
}
}

}

Inside the permission granted. going to start the camera . lets Initialise the cameraProvider in there

private void startCamera() {
cameraProviderFuture.addListener(new Runnable() {
@Override
public void run() {
try {
cameraProvider = cameraProviderFuture.get();
initPreview(cameraProvider,CameraSelector.LENS_FACING_BACK);

} catch (ExecutionException | InterruptedException e) {
// No errors need to be handled for this Future.
// This should never be reached.
e.printStackTrace();
}
}
}, ContextCompat.getMainExecutor(activity));
}


cameraselector we can provide the basic camera properties you want to change like fron cam or back came which cam you need to access like the 

 // camera selector use case
cameraSelector = new CameraSelector.Builder()
.requireLensFacing(CameraSelector.LENS_FACING_BACK)
.build();

 ImageAnalysis you can you that for analysis the image like automation . using opencv to dedect somthing like that 

ImageAnalysis imageAnalysis = new ImageAnalysis.Builder()
.setBackpressureStrategy(ImageAnalysis.STRATEGY_KEEP_ONLY_LATEST)
.build();

 ImageCapture is class where you can provise the frame radius image quality , camera rotation, like that all the image properties

// imagecapture user case
ImageCapture.Builder builder = new ImageCapture.Builder();
imageCapture = builder
.setCaptureMode(ImageCapture.CAPTURE_MODE_MAXIMIZE_QUALITY)
.setTargetRotation(activity.getWindowManager().getDefaultDisplay().getRotation())
.setTargetAspectRatio(AspectRatio.RATIO_4_3)
.build();

// video capture use case
videoCapture = new VideoCapture.Builder()
.setTargetRotation(activity.getWindowManager().getDefaultDisplay().getRotation())
.setCameraSelector(cameraSelector)
// .setVideoFrameRate(30)
.setTargetAspectRatio(AspectRatio.RATIO_4_3)
.build();

In the initPreview going to bind all the camera properties and the preview components going to initialise.

@SuppressLint("RestrictedApi")

    void initPreview(@NonNull ProcessCameraProvider cameraProvider, int lensFacingBack) {
cameraProvider.unbindAll();

try {

// preview user case
Preview preview = new Preview.Builder()
.build();

preview.setSurfaceProvider(cameraActivityBinding.viewFinder.getSurfaceProvider());

// camera selector use case
cameraSelector = new CameraSelector.Builder()
.requireLensFacing(lensFacingBack)
.build();

ImageAnalysis imageAnalysis = new ImageAnalysis.Builder()
.setBackpressureStrategy(ImageAnalysis.STRATEGY_KEEP_ONLY_LATEST)
.build();

// imagecapture user case
ImageCapture.Builder builder = new ImageCapture.Builder();
imageCapture = builder
.setCaptureMode(ImageCapture.CAPTURE_MODE_MAXIMIZE_QUALITY)
.setTargetRotation(activity.getWindowManager().getDefaultDisplay().getRotation())
.setTargetAspectRatio(AspectRatio.RATIO_4_3)
.build();

// video capture use case
videoCapture = new VideoCapture.Builder()
.setTargetRotation(activity.getWindowManager().getDefaultDisplay().getRotation())
.setCameraSelector(cameraSelector)
// .setVideoFrameRate(30)
.setTargetAspectRatio(AspectRatio.RATIO_4_3)
.build();


preview.setSurfaceProvider(cameraActivityBinding.viewFinder.getSurfaceProvider());
camera = cameraProvider.bindToLifecycle((LifecycleOwner) this, cameraSelector, preview, imageCapture,videoCapture);


}catch (Exception e){
e.printStackTrace();
Log.d(TAG, "bindPreview: Exception" + e.getMessage());
}
}

Don't forget to close the image.close in side there.

you can save directly the captured image in your cache or internal storage for them mostly you need the ManagedInternal storeage Permission you needed .

File myPath = getInternalStorageDir(internalStorageDir, videoFormat, Environment.DIRECTORY_MOVIES);
VideoCapture.OutputFileOptions outputFileOptions = new VideoCapture.OutputFileOptions.Builder(myPath).build();
Log.d(TAG, "takeVideo: long press");
startCount();
videoCapture.startRecording(outputFileOptions, camaraExecutor, new VideoCapture.OnVideoSavedCallback() {
@Override
public void onVideoSaved(@NonNull VideoCapture.OutputFileResults outputFileResults) {
Log.d(TAG, "onVideoSaved: success");

activity.runOnUiThread(() -> {
try {
cameraActivityBinding.submitImg.setVisibility(View.VISIBLE);
cameraActivityBinding.previewImage.setVisibility(View.GONE);
cameraActivityBinding.cameraLayout.setVisibility(View.GONE);
cameraActivityBinding.previewLayout.setVisibility(View.VISIBLE);
cameraActivityBinding.previewVideo.setVisibility(View.VISIBLE);

MediaController mediaController = new MediaController(activity);
mediaController.setAnchorView(cameraActivityBinding.previewVideo);
// Setting MediaController and URI, then starting the videoView
cameraActivityBinding.previewVideo.setMediaController(mediaController);
cameraActivityBinding.previewVideo.setVideoURI(outputFileResults.getSavedUri());
cameraActivityBinding.previewVideo.requestFocus();
cameraActivityBinding.previewVideo.setZOrderOnTop(true);
cameraActivityBinding.previewVideo.start();

cameraActivityBinding.previewVideo.setVideoURI(outputFileResults.getSavedUri());

imagePath = outputFileResults.getSavedUri().getPath();
Log.d(TAG, "onVideoSaved: " + outputFileResults.getSavedUri());

} catch (Exception e) {
Log.d(TAG, "onVideoSaved error: " + e.getMessage());
}
});

}

@Override
public void onError(int videoCaptureError, @NonNull String message, @Nullable Throwable cause) {
Log.d(TAG, "onError: " + message);
stopRecording();
}
});

VideoCapture.OutputFileOptions have the file path to store the video location


the final XML code , <layout> tag is used for data binding . if your using the data binding you kept like that otherwise just remove that . the listener i'm using to communicate with the activity. for images use the appropriate needed images i leave that with blank white. camera_activity.xml

<?xml version="1.0" encoding="utf-8"?>
<layout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto">

<data>
<import type="android.view.View"/>
<variable
name="cameraListener"
type="com.image.imagecapture.CameraListener" />
</data>

<androidx.constraintlayout.widget.ConstraintLayout
android:layout_width="match_parent"
android:layout_height="match_parent">

<RelativeLayout
android:id="@+id/camera_layout"
android:layout_width="match_parent"
android:layout_height="match_parent"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent"
>

<androidx.camera.view.PreviewView
android:id="@+id/viewFinder"
android:layout_width="match_parent"
android:layout_height="match_parent"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintTop_toTopOf="parent"
/>

<ImageView
android:id="@+id/cambackPress"
android:layout_width="30dp"
android:layout_height="30dp"
android:layout_marginStart="@dimen/five_dp"
android:layout_marginTop="@dimen/five_dp"
android:layout_marginEnd="@dimen/five_dp"
android:layout_marginBottom="@dimen/five_dp"
android:backgroundTint="@color/white"
app:tint="@color/white"
android:layout_alignParentEnd="true"
/>

<LinearLayout
android:id="@+id/count_down_lay"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:padding="5dp"
android:orientation="horizontal"
android:layout_centerHorizontal="true"
android:layout_marginTop="5dp"
android:visibility="gone"
>
<TextView
android:id="@+id/seconds_rec"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="00"
android:textColor="@color/white"
/>
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text=" : "
android:textColor="@color/white"
/>
<TextView
android:id="@+id/mili_seconds_rec"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="00"
android:textColor="@color/white"
/>
</LinearLayout>

<RelativeLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_alignParentBottom="true"
android:padding="@dimen/ten_dp"
>
<androidx.cardview.widget.CardView
android:layout_width="50dp"
android:layout_height="50dp"
android:layout_centerVertical="true"
android:layout_marginEnd="@dimen/twty_dp"
app:cardCornerRadius="30dp"
app:contentPadding="@dimen/ten_dp"
app:cardElevation="0dp"
android:onClick='@{(view) -> cameraListener.flashOnOff(view,flashLight)}'
>

<ImageView
android:id="@+id/flashLight"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:backgroundTint="@color/white"
app:tint="@color/white"
/>
</androidx.cardview.widget.CardView>


<Button
android:id="@+id/camera_capture_button"
android:layout_width="60dp"
android:layout_height="60dp"
android:layout_centerInParent="true"
android:elevation="2dp"
android:onClick='@{(view) -> cameraListener.takePicture(view)}'
android:scaleType="fitCenter" />

<androidx.cardview.widget.CardView
android:layout_width="50dp"
android:layout_height="50dp"
android:layout_alignParentEnd="true"
android:layout_centerVertical="true"
android:layout_marginEnd="@dimen/twty_dp"
android:onClick='@{(view) -> cameraListener.changeCamera(view)}'
app:cardCornerRadius="30dp"
app:contentPadding="@dimen/ten_dp"
app:cardElevation="0dp"
>
<ImageView
android:id="@+id/switchCamera"
android:layout_width="match_parent"
android:layout_height="match_parent"
app:srcCompat="@android:drawable/ic_popup_sync"
app:tint="@color/white" />
</androidx.cardview.widget.CardView>

</RelativeLayout>
</RelativeLayout>

<RelativeLayout
android:id="@+id/previewLayout"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="@color/black"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent"
android:visibility="gone"
>
<ImageView
android:id="@+id/previewImage"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="@color/black"
android:scaleType="fitCenter"
/>

<VideoView
android:id="@+id/previewVideo"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="@color/black"
/>

<RelativeLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_alignParentBottom="true"
android:padding="@dimen/ten_dp"
>
<androidx.cardview.widget.CardView
android:layout_width="60dp"
android:layout_height="60dp"
android:layout_alignParentStart="true"
android:layout_centerVertical="true"
android:layout_marginEnd="@dimen/twty_dp"
android:onClick='@{(view) -> cameraListener.closeBackToCam(view)}'
app:cardBackgroundColor="@color/white"
app:cardCornerRadius="30dp"
app:contentPadding="@dimen/ten_dp">

<ImageView
android:id="@+id/deleteImage"
android:layout_width="match_parent"
android:layout_height="match_parent"
app:tint="@color/white" />
</androidx.cardview.widget.CardView>
<androidx.cardview.widget.CardView
android:id="@+id/submitImg"
android:layout_width="60dp"
android:layout_height="60dp"
android:layout_alignParentEnd="true"
android:layout_centerVertical="true"
android:layout_marginEnd="@dimen/twty_dp"
android:onClick='@{(view) -> cameraListener.submitClick(view)}'
app:cardBackgroundColor="@color/white"
app:cardCornerRadius="30dp"
app:contentPadding="@dimen/ten_dp"
android:visibility="gone"
>

<ImageView
android:id="@+id/next_btn"
android:layout_width="match_parent"
android:layout_height="match_parent"
app:tint="@color/white" />
</androidx.cardview.widget.CardView>
</RelativeLayout>

</RelativeLayout>

</androidx.constraintlayout.widget.ConstraintLayout>
</layout>

Finally the camera is a fragment so that you can use that in all the activity easily.CameraFragment.java

package com.image.imagecapture;/**
* Created by Charles Raj I on 06/09/21.
*
* @author Charles Raj I
*/

import android.Manifest;
import android.annotation.SuppressLint;
import android.app.Activity;
import android.content.Context;
import android.content.pm.PackageManager;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.os.Build;
import android.os.Bundle;
import android.os.Environment;
import android.os.Handler;
import android.text.TextUtils;
import android.util.Log;
import android.view.KeyEvent;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ImageView;
import android.widget.MediaController;
import android.widget.Toast;

import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.annotation.RequiresApi;
import androidx.camera.core.AspectRatio;
import androidx.camera.core.Camera;
import androidx.camera.core.CameraSelector;
import androidx.camera.core.ImageAnalysis;
import androidx.camera.core.ImageCapture;
import androidx.camera.core.ImageCaptureException;
import androidx.camera.core.ImageProxy;
import androidx.camera.core.Preview;
import androidx.camera.core.VideoCapture;
import androidx.camera.lifecycle.ProcessCameraProvider;
import androidx.core.content.ContextCompat;
import androidx.databinding.DataBindingUtil;
import androidx.fragment.app.Fragment;
import androidx.lifecycle.LifecycleOwner;

import com.bumptech.glide.Glide;
import com.bumptech.glide.request.target.BitmapImageViewTarget;
import com.google.common.util.concurrent.ListenableFuture;
import com.image.imagecapture.databinding.CameraActivityBinding;

import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.nio.ByteBuffer;
import java.util.Date;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;

public class CameraFragment extends Fragment implements CameraListener {

private static final String TAG = "CameraActivity";
public static final String internalStorageDir = "/images";
public static final String videoFormat = ".mp4";
public static final String imageFormat = ".jpg";
public static final String[] CAMERA_PERMISSIONS = new String[]{Manifest.permission.READ_EXTERNAL_STORAGE,Manifest.permission.CAMERA,Manifest.permission.WRITE_EXTERNAL_STORAGE,Manifest.permission.RECORD_AUDIO};
CameraActivityBinding cameraActivityBinding;
Activity activity;
ExecutorService camaraExecutor;
CameraSelector cameraSelector;
ImageCapture imageCapture;
ProcessCameraProvider cameraProvider;
ListenableFuture<ProcessCameraProvider> cameraProviderFuture;


private int REQUEST_CODE_PERMISSIONS = 1001;
VideoCapture videoCapture;
String imagePath= "";
CameraFragmentToActivity cameraFragmentToActivity;
int lenceFacing;

Boolean videoStatus= false;
Camera camera;
int miliSec = 0;
int sec = 0;
boolean isFlashOn = false;

private boolean started = false;
private Handler handler = new Handler();

@RequiresApi(api = Build.VERSION_CODES.M)
@Nullable
@Override
public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
activity = getActivity();
cameraActivityBinding = DataBindingUtil.inflate(LayoutInflater.from(activity), R.layout.camera_activity,container,false);
cameraActivityBinding.setCameraListener(this);
camaraExecutor = Executors.newSingleThreadExecutor();
cameraProviderFuture = ProcessCameraProvider.getInstance(activity);
cameraActivityBinding.flashLight.setEnabled(false);

if (allPermissionsGranted(CAMERA_PERMISSIONS,activity)) {
startCamera();
}else {
activity.requestPermissions(CAMERA_PERMISSIONS,1);
}

cameraActivityBinding.getRoot().setFocusableInTouchMode(true);
cameraActivityBinding.getRoot().requestFocus();
cameraActivityBinding.getRoot().setOnKeyListener((v, keyCode, event) -> {
if( keyCode == KeyEvent.KEYCODE_BACK )
{
cameraFragmentToActivity.fragmentBackPress();
return true;
}
return false;
});

cameraActivityBinding.cambackPress.setOnClickListener(v -> {
cameraFragmentToActivity.fragmentBackPress();
});
return cameraActivityBinding.getRoot();
}

@Override
public void onAttach(@NonNull Context context) {
super.onAttach(context);
cameraFragmentToActivity = (CameraFragmentToActivity) context;
}

@RequiresApi(api = Build.VERSION_CODES.M)
@Override
public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {

if(requestCode == REQUEST_CODE_PERMISSIONS){
if (allPermissionsGranted(permissions,activity)) {
startCamera();
} else{
activity.requestPermissions(permissions,1);
Toast.makeText(activity, "Permissions not granted by the user.", Toast.LENGTH_SHORT).show();
}
}
}

private static boolean allPermissionsGranted(String[] permissions, Activity activity){

for(String permission : permissions){
if(ContextCompat.checkSelfPermission(activity, permission) != PackageManager.PERMISSION_GRANTED){
return false;
}
}
return true;
}

private void startCamera() {
cameraProviderFuture.addListener(new Runnable() {
@Override
public void run() {
try {
cameraProvider = cameraProviderFuture.get();
lenceFacing = CameraSelector.LENS_FACING_BACK;
initPreview(cameraProvider,lenceFacing);

} catch (ExecutionException | InterruptedException e) {
// No errors need to be handled for this Future.
// This should never be reached.
e.printStackTrace();
}
}
}, ContextCompat.getMainExecutor(activity));
}

@SuppressLint("RestrictedApi")
void initPreview(@NonNull ProcessCameraProvider cameraProvider, int lensFacingBack) {
cameraProvider.unbindAll();

try {

// preview user case
Preview preview = new Preview.Builder()
.build();

preview.setSurfaceProvider(cameraActivityBinding.viewFinder.getSurfaceProvider());

// camera selector use case
cameraSelector = new CameraSelector.Builder()
.requireLensFacing(lensFacingBack)
.build();

ImageAnalysis imageAnalysis = new ImageAnalysis.Builder()
.setBackpressureStrategy(ImageAnalysis.STRATEGY_KEEP_ONLY_LATEST)
.build();

// imagecapture user case
ImageCapture.Builder builder = new ImageCapture.Builder();
imageCapture = builder
.setCaptureMode(ImageCapture.CAPTURE_MODE_MAXIMIZE_QUALITY)
.setTargetRotation(activity.getWindowManager().getDefaultDisplay().getRotation())
.setTargetAspectRatio(AspectRatio.RATIO_4_3)
.build();

// video capture use case
videoCapture = new VideoCapture.Builder()
.setTargetRotation(activity.getWindowManager().getDefaultDisplay().getRotation())
.setCameraSelector(cameraSelector)
// .setVideoFrameRate(30)
.setTargetAspectRatio(AspectRatio.RATIO_4_3)
.build();


preview.setSurfaceProvider(cameraActivityBinding.viewFinder.getSurfaceProvider());
camera = cameraProvider.bindToLifecycle((LifecycleOwner) this, cameraSelector, preview, imageCapture,videoCapture);

cameraActivityBinding.cameraCaptureButton.setOnLongClickListener(new View.OnLongClickListener() {
@Override
public boolean onLongClick(View v) {
if (ContextCompat.checkSelfPermission(activity, Manifest.permission.CAMERA) == PackageManager.PERMISSION_GRANTED
&& ContextCompat.checkSelfPermission(activity, Manifest.permission.WRITE_EXTERNAL_STORAGE) == PackageManager.PERMISSION_GRANTED) {

try {
if (!videoStatus) {
videoStatus = true;
cameraActivityBinding.cameraCaptureButton.setActivated(true);
// Store the files in the internal memory
File myPath = getInternalStorageDir(internalStorageDir, videoFormat, Environment.DIRECTORY_MOVIES);
VideoCapture.OutputFileOptions outputFileOptions = new VideoCapture.OutputFileOptions.Builder(myPath).build();
Log.d(TAG, "takeVideo: long press");
startCount();
videoCapture.startRecording(outputFileOptions, camaraExecutor, new VideoCapture.OnVideoSavedCallback() {
@Override
public void onVideoSaved(@NonNull VideoCapture.OutputFileResults outputFileResults) {
Log.d(TAG, "onVideoSaved: success");

activity.runOnUiThread(() -> {
try {
cameraActivityBinding.submitImg.setVisibility(View.VISIBLE);
cameraActivityBinding.previewImage.setVisibility(View.GONE);
cameraActivityBinding.cameraLayout.setVisibility(View.GONE);
cameraActivityBinding.previewLayout.setVisibility(View.VISIBLE);
cameraActivityBinding.previewVideo.setVisibility(View.VISIBLE);

MediaController mediaController = new MediaController(activity);
mediaController.setAnchorView(cameraActivityBinding.previewVideo);
// Setting MediaController and URI, then starting the videoView
cameraActivityBinding.previewVideo.setMediaController(mediaController);
cameraActivityBinding.previewVideo.setVideoURI(outputFileResults.getSavedUri());
cameraActivityBinding.previewVideo.requestFocus();
cameraActivityBinding.previewVideo.setZOrderOnTop(true);
cameraActivityBinding.previewVideo.start();

cameraActivityBinding.previewVideo.setVideoURI(outputFileResults.getSavedUri());

imagePath = outputFileResults.getSavedUri().getPath();
Log.d(TAG, "onVideoSaved: " + outputFileResults.getSavedUri());

} catch (Exception e) {
Log.d(TAG, "onVideoSaved error: " + e.getMessage());
}
});

}

@Override
public void onError(int videoCaptureError, @NonNull String message, @Nullable Throwable cause) {
Log.d(TAG, "onError: " + message);
stopRecording();
}
});
} else {
stopRecording();
}
} catch (Exception e) {
Log.d(TAG, "onLlong click catch error: " + e.getMessage());
}
}
return true;
}
});

}catch (Exception e){
e.printStackTrace();
Log.d(TAG, "bindPreview: Exception" + e.getMessage());
}
}


@Override @SuppressLint("RestrictedApi")
public void takePicture(View view) {
if (ContextCompat.checkSelfPermission(activity, Manifest.permission.CAMERA) == PackageManager.PERMISSION_GRANTED
&& ContextCompat.checkSelfPermission(activity, Manifest.permission.WRITE_EXTERNAL_STORAGE) == PackageManager.PERMISSION_GRANTED) {
if (!videoStatus) {
Log.d(TAG, "takePicture: click ");
imagePath = "";
try {
imageCapture.takePicture(camaraExecutor, new ImageCapture.OnImageCapturedCallback() {
@Override
public void onCaptureSuccess(@NonNull ImageProxy image) {
Log.d("somthing", "onCaptureSuccess: success ---");

showImage(activity, imageProxyToBitmap(image), cameraActivityBinding.previewImage);
activity.runOnUiThread(() -> {
cameraActivityBinding.cameraLayout.setVisibility(View.GONE);
cameraActivityBinding.previewLayout.setVisibility(View.VISIBLE);
cameraActivityBinding.previewImage.setVisibility(View.VISIBLE);
cameraActivityBinding.previewVideo.setVisibility(View.GONE);
});
Log.d(TAG, "Image saved path: " + imagePath);
imagePath = saveTOInternamMemory(activity, imageProxyToBitmap(image));
activity.runOnUiThread(() -> {
cameraActivityBinding.submitImg.setVisibility(View.VISIBLE);
});
image.close();
}

@Override
public void onError(@NonNull ImageCaptureException exception) {
exception.printStackTrace();
Toast.makeText(activity, exception.getMessage(), Toast.LENGTH_SHORT).show();
Log.d("somthing", "onCaptureSuccess: " + exception.getMessage());
}
});
} catch (Exception e) {
e.printStackTrace();
Toast.makeText(activity, e.getMessage(), Toast.LENGTH_SHORT).show();
Log.d("somthing", "try catch: " + e.getMessage());
}

}else {
stopRecording();
}
}
}


public void showImage(Activity activity, Bitmap value, ImageView imageView){
activity.runOnUiThread(new Runnable() {
@Override
public void run() {

Glide.with(activity)
.asBitmap()
.load(value)
.into(new BitmapImageViewTarget(imageView) {
@Override
protected void setResource(Bitmap resource) {
//Play with bitmap
super.setResource(resource);
}
});

}
});
}

// output of the image capture image proxy to bitmap
public Bitmap imageProxyToBitmap(ImageProxy image) {
ByteBuffer buffer = image.getPlanes()[0].getBuffer();
buffer.rewind();
byte[] bytes = new byte[buffer.capacity()];
buffer.get(bytes);
byte[] clonedBytes = bytes.clone();
return BitmapFactory.decodeByteArray(clonedBytes, 0, clonedBytes.length);
}

// used for save the files internal storage , can view in the gallery or internal storage
public String saveTOInternamMemory(Activity activity, Bitmap bitmapImage){

File myPath = getInternalStorageDir(internalStorageDir,imageFormat,Environment.DIRECTORY_PICTURES);

Log.d(TAG, "directory: " + myPath.getAbsolutePath());

FileOutputStream fos = null;
try {
fos = new FileOutputStream(myPath);
// Use the compress method on the BitMap object to write image to the OutputStream
bitmapImage.compress(Bitmap.CompressFormat.PNG, 100, fos);
Log.d(TAG, "bit exception: Success" );
} catch (Exception e) {
Log.d(TAG, "bit exception: " + e.getMessage());
e.printStackTrace();
} finally {
try {
fos.close();
} catch (IOException e) {
e.printStackTrace();
Log.d(TAG, "io exce: " + e.getMessage());
}
}
Log.d(TAG, "absolute path " + myPath.getAbsolutePath());
return myPath.getAbsolutePath();
}

public File getInternalStorageDir(String internalStorageDir, String fileType, String dirType){
Date date = new Date();
String milisec = String.valueOf(date.getTime());
File photosDir = new File(Environment.getExternalStoragePublicDirectory(dirType) + internalStorageDir);
// Create imageDir
if (!photosDir.exists()) photosDir.mkdir();
return new File(photosDir, milisec + fileType);
}
@Override
public void takeVideo(View view) {

}

@Override
public void submitClick(View view) {
if (!TextUtils.isEmpty(imagePath))
cameraFragmentToActivity.sendUrl(imagePath);
}

@Override
public void changeCamera(View view) {
cameraProvider.unbindAll();
if(lenceFacing == CameraSelector.LENS_FACING_FRONT) {
initPreview(cameraProvider, CameraSelector.LENS_FACING_BACK);
lenceFacing = CameraSelector.LENS_FACING_BACK;
}else {
initPreview(cameraProvider, CameraSelector.LENS_FACING_FRONT);
lenceFacing = CameraSelector.LENS_FACING_FRONT;
}
}

@Override
public void closeBackToCam(View view) {
activity.runOnUiThread(() -> {
imagePath ="";
cameraActivityBinding.cameraLayout.setVisibility(View.VISIBLE);
cameraActivityBinding.previewLayout.setVisibility(View.GONE);
cameraActivityBinding.previewVideo.stopPlayback();

cameraActivityBinding.miliSecondsRec.setText(String.valueOf(0));
cameraActivityBinding.secondsRec.setText(String.valueOf(0));
cameraActivityBinding.countDownLay.setVisibility(View.GONE);
});

cameraProvider.unbindAll();
initPreview(cameraProvider, CameraSelector.LENS_FACING_BACK);
lenceFacing = CameraSelector.LENS_FACING_BACK;
}

@Override
public void flashOnOff(View view, ImageView imageView) {
try {
if (isFlashOn){
camera.getCameraControl().enableTorch(false);
isFlashOn = false;
imageView.setEnabled(false);
}else {
camera.getCameraControl().enableTorch(true);
isFlashOn = true;
imageView.setEnabled(true);
}
} catch (Exception e) {
e.printStackTrace();
Log.d(TAG, "onCreateView: set tourch error" + e.getMessage());
}

}

@SuppressLint("RestrictedApi")
public void stopRecording(){
videoCapture.stopRecording();
videoStatus = false;
cameraActivityBinding.cameraCaptureButton.setActivated(false);
stopCount();
}


private Runnable runnable = new Runnable() {
@Override
public void run() {
miliSec++;
Log.d(TAG, "recordingCount: " + miliSec);
cameraActivityBinding.miliSecondsRec.setText(String.valueOf(miliSec));
if (miliSec == 60) {
sec++;
cameraActivityBinding.secondsRec.setText(String.valueOf(sec));
miliSec = 0;
}
if (sec == 2){
stopCount();
}
if(started) {
startCount();
}
}
};

public void stopCount() {
started = false;
miliSec = 0;
sec = 0;
handler.removeCallbacks(runnable);
}

public void startCount() {
cameraActivityBinding.countDownLay.setVisibility(View.VISIBLE);
started = true;
handler.postDelayed(runnable, 1000);
}

}This is the camera fragment i use interface i use to communicate with the UI. and back to activity . 
I'll give the Github url of this project Click here.
I think this is usefull for you . ThankYour . if you  need any clarifications just ask me or commnet . i'll give my information here .
Thank You

Comments