2 years ago

#48314

test-img

kosmicow

Unable to open captured image: open failed: EACCES (Permission denied)

I am working on this project for an app that can capture an image and then perform Text Recognition on the image using Google ML Toolkit. It is for my personal use only so I don't really care about "respecting the user's choice not to allow permissions", if I could I would ask them all at startup instead of asking when I need them.

Right now I basically request Camera Access at startup (which works fine) and then I show the camera feed to the user in the center of the screen. Then, the user can click on a "capture" button in order to capture the current frame and save it to a certain path. Then, I would like to decode the file in that path into bitmap format, display it to the user and then use the ML Toolkit.

However, I get an error, which I think is a permission error from the READ_EXTERNAL_STORAGE permission. Since the error I get says "Unable to decode stream: java.io.FileNotFoundException: /mnt/sdcard/Pictures/CameraXPhotos/1642088145797.jpg: open failed: EACCES (Permission denied)"

From what I understood I have to manually request permissions. From Android Developers it is stated that: "Any app that declares the WRITE_EXTERNAL_STORAGE permission is implicitly granted this (READ_EXTERNAL_STORAGE) permission." So I theoretically just need to ask for the WRITE_EXTERNAL_STORAGE permission. So I do the following:

onCreate{
     button_capture.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v)
            {
                checkPermission(Manifest.permission.WRITE_EXTERNAL_STORAGE, STORAGE_WRITE_PERMISSION_CODE);
                capturePhoto();
            }
        });
}

public void checkPermission(String permission, int requestCode){
        if (ContextCompat.checkSelfPermission(MainActivity.this, permission) == PackageManager.PERMISSION_DENIED) {

            // Requesting the permission
            ActivityCompat.requestPermissions(MainActivity.this, new String[] { permission }, requestCode);
        }
        else {
            Toast.makeText(MainActivity.this, "Permission already granted", Toast.LENGTH_SHORT).show();
        }
    }

@Override
public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults){
        super.onRequestPermissionsResult(requestCode, permissions, grantResults);

        if (requestCode == CAMERA_PERMISSION_CODE) {
            if (grantResults.length > 0 && grantResults[0] == PackageManager.PERMISSION_GRANTED) {
                Toast.makeText(MainActivity.this, "Camera Permission Granted", Toast.LENGTH_SHORT) .show();
            } else {
                Toast.makeText(MainActivity.this, "Camera Permission Denied", Toast.LENGTH_SHORT) .show();
            }
        }
        else if (requestCode == STORAGE_WRITE_PERMISSION_CODE) {
            if (grantResults.length > 0 && grantResults[0] == PackageManager.PERMISSION_GRANTED) {
                Toast.makeText(MainActivity.this, "Storage Permission Granted", Toast.LENGTH_SHORT).show();
            } else {
                Toast.makeText(MainActivity.this, "Storage Permission Denied", Toast.LENGTH_SHORT).show();
            }
        }
    }

But once I click on the capture button, it doesn't ask for permissions and crashes with the error "open failed: EACCES (Permission denied)" because of the line in my code in the capturePhoto() method where I try to open a file from its absolute path. I don't really understand why, with methods checkPermission() and onRequestPermissionsResult() I am handling permissions correctly right? Is it because the capturePhoto() method runs in parallel of the checkPermissions() method and therefore does not wait for the permissions to be given?

I hope my issue is understanble, this is my first question so if I did anything wrong in my question feel free to point it out to me!

Could it be that it is because in my checkPermission() method I check if the permission was denied but not if it was not granted in the first place?

EDIT: Thank you for your comments @blackapps. The code that lets the user capture a picture is the following:

private void capturePhoto() {
        File photoDir = new File("/mnt/sdcard/Pictures/CameraXPhotos");

        if(!photoDir.exists())
            photoDir.mkdir();

        Date date = new Date();
        String timestamp = String.valueOf(date.getTime());
        String photoFilePath = photoDir.getAbsolutePath() + "/" + timestamp + ".jpg";

        File photoFile = new File(photoFilePath);

        imageCapture.takePicture(
                new ImageCapture.OutputFileOptions.Builder(photoFile).build(),
                getExecutor(),
                new ImageCapture.OnImageSavedCallback() {
                    @Override
                    public void onImageSaved(@NonNull ImageCapture.OutputFileResults outputFileResults) {
                        Toast.makeText(MainActivity.this, "Photo has been taken", Toast.LENGTH_SHORT).show();
                    }

                    @Override
                    public void onError(@NonNull ImageCaptureException exception) {
                        Toast.makeText(MainActivity.this, "Error taking photo: " + exception.getMessage(), Toast.LENGTH_SHORT).show();
                    }
                }
        );

        Bitmap bitmap = BitmapFactory.decodeFile(photoFile.getAbsolutePath());
        getTextFromImage(bitmap);
        image_result.setImageBitmap(bitmap);

//        return photoFilePath;
    }

java

android

android-studio

android-permissions

0 Answers

Your Answer

Accepted video resources