Search code examples
androidimagefilecamera

Images deleted from my application folder are still in the camera gallery


I am trying to delete images taken through the Camera api and, in principle it does delete them from my application folder but the images are still in the DCIM/camera folder.

I am using an ITOS device with Android version 9.

Here is the code I am using.

manifest.xml

    <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
    <uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />

    <uses-feature
        android:name="android.hardware.camera"
        android:required="false" />
------
<provider
            android:name="androidx.core.content.FileProvider"
            android:authorities="com.example.cameratest.fileprovider"
            android:exported="false"
            android:grantUriPermissions="true">
            <meta-data
                android:name="android.support.FILE_PROVIDER_PATHS"
                android:resource="@xml/file_paths" />
        </provider>

@xml/file_paths
<?xml version="1.0" encoding="utf-8"?>
<paths xmlns:android="http://schemas.android.com/apk/res/android">
    <external-path
        name="external"
        path="." />
    <external-files-path
        name="external_files"
        path="." />
    <cache-path
        name="cache"
        path="." />
    <external-cache-path
        name="external_cache"
        path="." />
    <files-path
        name="files"
        path="." />
</paths>

And this is how I capture the image:

private void checkPermissions(View view) {
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
            if (checkSelfPermission(Manifest.permission.CAMERA) != PackageManager.PERMISSION_GRANTED) {
                requestPermissions(new String[]{Manifest.permission.CAMERA}, MY_CAMERA_PERMISSION_CODE);
            } else {
                captureImage();
            }
        } else {
            captureImage();
        }
    }

private void captureImage() {
        Intent cameraIntent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
        if (cameraIntent.resolveActivity(getPackageManager()) != null) {
            File imageFile = null;
            try {
                imageFile = getImageFile();
            } catch (IOException e) {
                Log.d("TAG", "captureImage ERROR: " + e.getMessage());
                e.printStackTrace();
            }

            if (imageFile != null) {
                Uri imageUri = FileProvider.getUriForFile(this, Constants.FILE_AUTHORITY_PROVIDER, imageFile);
                cameraIntent.putExtra(MediaStore.EXTRA_OUTPUT, imageUri);
                startActivityForResult(cameraIntent, CAMERA_REQUEST);
            }
        }

private File getImageFile() throws IOException {
        String timeStamp = new SimpleDateFormat("yyyyMMdd_HHmmss").format(new Date());
        String imageFileName = "IMG_" + timeStamp;
        File storageDir =  new File(this.getExternalFilesDir(Environment.DIRECTORY_PICTURES),"MisFotos");

        if (! storageDir.exists()){
            if (! storageDir.mkdirs()){
                Log.d("MyCameraApp", "failed to create directory");
                return null;
            }
        }

        File image = new File(storageDir.getPath() + File.separator + imageFileName + ".jpg");

        // Save a file: path for use with ACTION_VIEW intents
        currentPhotoPath = image.getAbsolutePath();
        Log.d("PHOTO_TAG", "getImageFile: " + currentPhotoPath);
        return image;
    }

@Override
    public void onActivityResult(int requestCode, int resultCode, @Nullable Intent data) {
        super.onActivityResult(requestCode, resultCode, data);
        if (requestCode == CAMERA_REQUEST && resultCode == Activity.RESULT_OK) {
            setPictureToDataBase();
        }
    }

UPDATED I save the image path in a database and then retrieve it to delete the file.

And here is the code I use to delete the image in my Picture Adapter

public void deletePicture(Picture picture) {
        try {

            myDatabase.deletePicture(picture.getUid());
            String path = picture.getImage();//storageDir.getPath() + File.separator + imageFileName + ".jpg"
            pictures.remove(picture);
            notifyDataSetChanged();
            if (pictures != null && pictures.size()>0){
                listener.onDeleteClick( pictures.size());
            }else {
                listener.onDeleteClick( 0);
            }

            File target = new File(path);

            if (target.exists()) {
                target.delete();
            }
            else {
                Log.d("TAG_DELETE_PICTURE", "ERROR: FILE NOT EXITS");
            }
        } catch (Exception e) {
            Log.d("deletePicture", "ERROR: " + e.getMessage());
        }
    }

And when I open the device file explorer it is in "MyPhotos" and in DCIM/camera. same image, two places

It works correctly when deleting the image from the application folder, but when looking in DCIM/camera the images are still there and occupy memory.

Am I doing something wrong, is there a way to delete the image saved in DCIM/camera?

I want to take the photo, save it only in the folder of the application, and not save it anywhere else. Is there any other way to do this?


Solution

  • Am I doing something wrong

    You are launching a camera app via ACTION_IMAGE_CAPTURE. There are tens of thousands of Android device models. There will be dozens of different pre-installed camera apps across those device models, and users can install other camera apps from the Play Store and elsewhere.

    What those camera apps do is up to their developers.

    In your case, the camera app that you happen to be using is both saving the photo in its normal place and making a copy in the location identified by EXTRA_OUTPUT. Few camera apps will do this, but it is perfectly legitimate for a camera app to behave that way.

    I want to take the photo, save it only in the folder of the application, and not save it anywhere else. Is there any other way to do this?

    Do not use ACTION_IMAGE_CAPTURE. Instead, use the camera APIs directly or via a wrapper library (Google's CameraX, FotoApparat, CameraKit-Android, etc.).