16

I am trying to delete a file located at the path

/storage/714D-160A/Xender/image/Screenshot_commando.png

What I've done so far:

  try{
        String d_path = "/storage/714D-160A/Xender/image/Screenshot_commando.png";
        File file = new File(d_path);
        file.delete();

     }catch(Exception e){

        e.printStackTrace();
     }

and the file is still at its place(Not deleted :( )

Also I've given permission in Manifest file.

<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.WRITE_INTERNAL_STORAGE" />
<uses-permission android:name="android.permission.STORAGE" />
user207421
  • 305,947
  • 44
  • 307
  • 483
Secret
  • 611
  • 1
  • 10
  • 29

4 Answers4

14
public static boolean delete(final Context context, final File file) {
    final String where = MediaStore.MediaColumns.DATA + "=?";
    final String[] selectionArgs = new String[] {
            file.getAbsolutePath()
    };
    final ContentResolver contentResolver = context.getContentResolver();
    final Uri filesUri = MediaStore.Files.getContentUri("external");

    contentResolver.delete(filesUri, where, selectionArgs);

    if (file.exists()) {

        contentResolver.delete(filesUri, where, selectionArgs);
    }
    return !file.exists();
}
Secret
  • 611
  • 1
  • 10
  • 29
  • Will this method work with Android devices running on Android 5.0 and above? – Rahulrr2602 Jul 30 '17 at 18:43
  • 2
    No, it doesn't work on Android 5.0 and will cause many problems. In fact, editing files on the `sd-card` is not that easy but it is doable. See my answer. – Eftekhari Jul 31 '17 at 08:48
  • 2
    hii @Secret one suggestion A good answer will always have an explanation of what was done and why it was done in such a manner, not only for the OP but for future visitors to SO. so if possible please edit and explain in few words :) – Rucha Bhatt Joshi Aug 10 '17 at 11:27
  • what is "external" in getContentUri("external") ? - @Secret – Yesha Shah Dec 07 '20 at 13:05
12

Using ContentResolver to delete media files is wrong and provides many problems for the user.
You can not delete a file on the sd-card simply by deleting its information from the ContentResolver on Android versions greater than Jelly Bean(4.3).
It works only on Android versions prior to KitKat(4.4).
That's why the Android team provided DocumentProvider.

Why contentResolver.delete(...) is wrong?
1. Fills up the sd-card
When you try to delete a media file on the sd-card by the ContentResolver on Android versions greater than 4.3, the actual media file will remain untouched because the contentResolver.delete(...) approach only removes the information (name, date, path ...) of the media and you will end up having unregistered media files on your sd-card which ContentResolver has no idea about their existence anymore and that's why you couldn't see them in your gallery and you think they've been deleted with this approach while they're still there and fill up the sd-card each time the user tries to delete a media file on the sd-card.

2. Media files (Images, videos, gifs ...) will come back to the gallery
There are many apps out there especially gallery and file manager ones that will find these unregistered media files and will add them to the ContentResolver again as of their normal behavior while the user assumes his/her unwanted media files are gone. Sure no user wants his/her assuming deleted images or videos show up in the middle of a demonstration.

So, what's the correct approach to remove media files on the sd-card?
Well, this has already been answered here with the use of DocumentProvider.

Eftekhari
  • 1,001
  • 1
  • 19
  • 37
  • The original question never even mentioned ContentResolver. Why does your answer focus on it? OH. I see. the accepted answer uses contentresolver. – Neo42 Feb 07 '18 at 15:49
  • `The original question never even mentioned ContentResolver. Why does your answer focus on it? OH. I see. the accepted answer uses contentresolver.` @Neo42 No. Your assumption is wrong and illogical. I've already answered the question to explain how to use `ContentResolver` in the correct way, almost one year before the accepted answer appears and talks about `ContentResolver` which is wrong and irresponsible. Here is the link also provided in my answer >> https://stackoverflow.com/a/39104124/2123400 – Eftekhari Jun 23 '19 at 12:55
5

From Android 4.4 onwards, you can't write to SD card files (except in the App directory) using the normal way. You'll have to use the Storage Access Framework using DocumentFile for that.

The following code works for me:

private void deletefile(Uri uri, String filename) {
    DocumentFile pickedDir = DocumentFile.fromTreeUri(this, uri);

    DocumentFile file = pickedDir.findFile(filename);
    if(file.delete())
        Log.d("Log ID", "Delete successful");
    else
        Log.d("Log ID", "Delete unsuccessful");
}

where filename is the name of the file to be deleted and uri is the URI returned by ACTION_OPEN_DOCUMENT_TREE:

private static final int LOCATION_REQUEST = 1;

private void choosePath() {
    Intent intent = new Intent(Intent.ACTION_OPEN_DOCUMENT_TREE);
    intent.addCategory(Intent.CATEGORY_DEFAULT);
    startActivityForResult(intent, LOCATION_REQUEST);
}

@Override
public void onActivityResult(int requestCode, int resultCode, Intent resultData) {
    if (requestCode == LOCATION_REQUEST && resultCode == Activity.RESULT_OK) {
        if (resultData != null) {
            Uri uri = resultData.getData();
            if (uri != null) {
                /* Got the path uri */
            }
        }
    }
}
Spikatrix
  • 20,225
  • 7
  • 37
  • 83
  • In this "private void deletefile(Uri uri, String filename)" need file name as well, but how can I get file name from uri got in activityresult... – Bhavesh Moradiya Dec 07 '18 at 11:12
  • @BhaveshMoradiya Sorry for the late reply, I was a bit busy. I use the following for getting the path from the URI: `String path = FileUtil.getFullPathFromTreeUri(uri, this);`. The `FileUtil` class can be found here: https://stackoverflow.com/a/36162691/3049655 – Spikatrix Dec 13 '18 at 16:13
  • @BhaveshMoradiya The URI that you get via `ACTION_OPEN_DOCUMENT_TREE` is not a particular file, but rather, a location. You'll need to use `ACTION_OPEN_DOCUMENT` if you want the user to pick a particular file – Spikatrix Dec 13 '18 at 16:15
  • DocumentFile file = pickedDir.findFile(filename); returns npe for some reason? – Vince VD Feb 09 '19 at 03:06
  • Found the reason why, i had to select the folder where the files where located; but how can i automatically open that folder so the users doesn't have to browser to that folder? – Vince VD Feb 09 '19 at 03:09
  • @Vince Try `pickedDir = DocumentFile.fromFile(new File(location)); DocumentFile file = pickedDir.findFile(fileName); if(file == null) { /* File not found */ } else { if(file.delete()) { /* Success! */ } else { /* Failed to delete */ } }` – Spikatrix Feb 09 '19 at 05:09
  • also, won't this open a dialogue? people would like to obtain the uri from the native app interface, e.g. by taping the song name on a music player, is there a way to get the uri in another way? – juztcode Jul 07 '20 at 12:12
  • @juztcode Yes `ACTION_OPEN_DOCUMENT_TREE` will open a dialog for selecting a path. I'm not sure if there is a way to get a tree URI without using that. – Spikatrix Jul 07 '20 at 13:00
3

Use Environment.getExternalStorageDirectory().getAbsolutePath() instead of hard coding storage path

String baseDir = Environment.getExternalStorageDirectory().getAbsolutePath();
File f = new File(baseDir + "/714D-160A/Xender/image/Screenshot_commando.png");
boolean d = f.delete();
SiSa
  • 2,594
  • 1
  • 15
  • 33
  • thank's for your answer but i want to delete external storage(Memory Card) file.and boolean return false,the file is still at its place(Not deleted).. – Secret Jul 24 '17 at 05:56
  • @Secret Did you test `Environment.getExternalStorageDirectory().getAbsolutePath()` instead of `/storage` ? – SiSa Jul 24 '17 at 06:44
  • @Secret I'm pretty sure that the problem is in file address. Test another file which is located in your external storage root – SiSa Jul 24 '17 at 07:39
  • @Secret, Hi I'm also looking for method which able to delete file from External Memory Card(Physically Mounted Memory), Do you get solution ? Please Help me.. – Bhavesh Moradiya Dec 07 '18 at 10:21
  • @BhaveshMoradiya you need `ExternalStoragePermission` and then simply call `File.delete()` for your file – SiSa Dec 08 '18 at 07:41