0

App is working fine without any error and crashes but it cant save any photo. This activity has one previewview and one imagebutton to capture image. Whenever I try to take picture onError() gets executed which means photo is not saved but I dont know why. Please tell me what is wrong going here...

xml:

<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context=".BaseCamera">


    <FrameLayout
        android:id="@+id/frameLayout"
        android:layout_width="match_parent"
        android:layout_height="685dp"
        tools:layout_editor_absoluteX="1dp"
        tools:layout_editor_absoluteY="1dp">

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

    </FrameLayout>

    <ImageButton
        android:id="@+id/capture"
        android:layout_width="74dp"
        android:layout_height="65dp"
        android:onClick="onClick"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintHorizontal_bias="0.498"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toTopOf="parent"
        app:layout_constraintVertical_bias="0.99"
        app:srcCompat="@android:drawable/ic_menu_camera" />
</androidx.constraintlayout.widget.ConstraintLayout>

Java:

package com.example.camerax;

import androidx.annotation.NonNull;
import androidx.annotation.Size;
import androidx.appcompat.app.AppCompatActivity;
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.lifecycle.ProcessCameraProvider;
import androidx.camera.view.PreviewView;
import androidx.core.content.ContextCompat;
import androidx.lifecycle.LifecycleOwner;

import android.graphics.Camera;
import android.os.Bundle;
import android.view.View;
import android.widget.ImageButton;
import android.widget.Toast;

import com.google.common.util.concurrent.ListenableFuture;

import java.io.File;
import java.util.Date;
import java.util.concurrent.ExecutionException;


public class BaseCamera extends AppCompatActivity{

    Preview previewView = new Preview.Builder().build();
    private ListenableFuture<ProcessCameraProvider> cameraProviderFuture;
    PreviewView prw;
    public ImageButton capture;
    public ImageCapture imageCapture;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_base_camera);

        prw = 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));

        capture = findViewById(R.id.capture);

        capture.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                capture_image();
            }
        });

    }

    void bindPreview (@NonNull ProcessCameraProvider cameraProvider)
    {
        Preview preview = new Preview.Builder()
                .build();

        CameraSelector cameraSelector =
                new CameraSelector.Builder()
                .requireLensFacing(CameraSelector.LENS_FACING_BACK)
                .build();

        imageCapture =
                new ImageCapture.Builder()
                        .setTargetRotation(prw.getDisplay().getRotation())
                        .setCaptureMode(ImageCapture.CAPTURE_MODE_MAXIMIZE_QUALITY)
                        .build();

        preview.setSurfaceProvider(prw.getSurfaceProvider());

        cameraProvider.bindToLifecycle((LifecycleOwner)this, cameraSelector, imageCapture, preview );

    }


    public void capture_image()
    {
        File ex = new File("storage/emulated/0/JayurCam");

        if(!ex.exists())
            ex.mkdirs();

        Date date = new Date();
        String dte = String.valueOf(date.getTime());
        String FileName = ex.getAbsolutePath()+dte+".jpg";
        File path = new File(FileName);

        ImageCapture.OutputFileOptions outputFileOptions =
                new ImageCapture.OutputFileOptions.Builder(path).build();

        imageCapture.takePicture(outputFileOptions, ContextCompat.getMainExecutor(this),
                new ImageCapture.OnImageSavedCallback() {
                    @Override
                    public void onImageSaved(@NonNull ImageCapture.OutputFileResults outputFileResults) {
                        Toast.makeText(BaseCamera.this, "Photo Saved.", Toast.LENGTH_SHORT).show();
                    }

                    @Override
                    public void onError(@NonNull ImageCaptureException exception) {
                        Toast.makeText(BaseCamera.this, "Failed", Toast.LENGTH_SHORT).show();
                    }
                }
        );
    }
}

1 Answers1

0

In android you need to have permission to access internal or external memory. Add this to your AndroidManifest.xml

<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
Abishek Stephen
  • 386
  • 1
  • 3
  • 15
  • I already added those permissions. I added read, write and manage external strorage permissions, but it still not working. – Jayur Pithava Sep 12 '21 at 14:30
  • Did you request user for those permissions? You have to prompt user for accessing memory. Does your app show a dialog when saving the file? – Abishek Stephen Sep 12 '21 at 14:33
  • I requsted user for those permission and i checked for those permissions in my phone, and allowed all permissions. My app does not show any dialog when saving file. I added mkdir() but it dont even create that directory. – Jayur Pithava Sep 12 '21 at 15:03
  • What is your base and target API level – Abishek Stephen Sep 12 '21 at 17:07