Search code examples
androidfileandroid-intentandroid-bitmapmediastore

How to delete a file using the path


I'm building an app that allows the user to save the bitmap or share it without saving it. The 2nd functionality doesn't quite work. I understand that the app needs to save the file to the device before sharing it on a social media app so my idea was, immediately after the file was successfully shared, to automatically delete the file from the device. I've build a delete method trying 2 different approaches and neither have worked:

First approach:

public void deleteFile(String path){
        File file = new File(path);
        try {
            file.getCanonicalFile().delete();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

Second approach:

public void deleteFile(String path){
    File file = new File(path);
    boolean deleted = file.delete();
}

And I'm calling deleteFile(String) from the sharing method:

public void shareMeme(Bitmap bitmap) {
    String path = MediaStore.Images.Media.insertImage(Objects.requireNonNull(getContext()).getContentResolver(), bitmap, "Meme", null);
    Uri uri = Uri.parse(path);

    Intent share = new Intent(Intent.ACTION_SEND);
    share.setType("image/*");
    share.putExtra(Intent.EXTRA_STREAM, uri);
    share.putExtra(Intent.EXTRA_TEXT, "This is my Meme");
    getContext().startActivity(Intent.createChooser(share, "Share Your Meme!"));

    deleteFile(path);
}

Solution

  • With respect to your stated problem, insertImage() returns a string representation of a Uri. That Uri is not a file. Calling getPath() on it is pointless, and you cannot delete anything based on that path.

    More broadly, if your intention is to delete the content right away:

    • Do not put it in the MediaStore
    • Do not share it, as you will be deleting it before the other app has a chance to do anything with it

    If you want to share it, but then delete it:

    • Do not put it in the MediaStore
    • Delete it the next day, or in a few hours, or something, as you have no good way of knowing when the other app is done with the content

    To share an image with another app without using the MediaStore:

    • Save the image to a file in getCacheDir() (call that on a Context, such as an Activity or Service)
    • Use FileProvider to make that file available to other apps

    Beyond that:

    • Do not use wildcard MIME types in ACTION_SEND. You are the one who is supplying the content to send. You know the actual MIME type. Use it.

    • Note that there is no requirement for an ACTION_SEND activity to honor both EXTRA_TEXT and EXTRA_STREAM. Most seem to do so, but that behavior is outside of the ACTION_SEND specification.

    • Note that insertImage() is deprecated on Android Q.