1

Method for deleting file with document uri

private void getDocumentUri(Uri mediaUri){
        try {
            if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O && getActivity() != null) {
                Uri documentUri = MediaStore.getDocumentUri(getActivity(), mediaUri);
                if (documentUri != null) {
                    Log.d(TAG,"getDocumentUri: "+documentUri);
                    DocumentFile documentFile = DocumentFile.fromSingleUri(getActivity(), documentUri);
                    if (documentFile != null) {
                        Log.d(TAG, "getDocumentUri documentFile not null: " + documentFile);
                        if (documentFile.delete()) {
                            Log.i(TAG, "getDocumentUri Delete successful");
                        } else {
                            Log.i(TAG, "getDocumentUri Delete unsuccessful");
                        }
                    }
                }
            }
        }catch(Exception e){
            Log.e(TAG,"getDocumentUri error: " + e);
        }
}

Logcat error

SecurityException: The app is not given any access to the document under path /storage/emulated/0/test/song.mp3 with permissions granted in [UriPermission {uri=content://com.android.externalstorage.documents/tree/primary%3AMusic, modeFlags=3, persistedTime=1601203263354}]

Weird thing is that for some files this works and for some it gives this error and all audio files are in the same place on the internal storage.

EDIT

mediaUri's value is obtained with ContentUris.withAppendedId(MediaStore.Audio.Media.EXTERNAL_CONTENT_URI,cursor.getLong(cursor.getColumnIndexOrThrow(MediaStore.Audio.Media._ID)));

Also the files i'm trying to delete are not created by my app

Vince VD
  • 1,506
  • 17
  • 38
  • 1
    Yes this is due to the newly introduced Scope Storage in android Q. You can add this line in your manifest `android:requestLegacyExternalStorage="true"` and it should work. but remember this is temporary solution and you need to eventually work with scope storage as this newly added line will be ignored after android sdk version 30 – WhiteSpidy. Sep 27 '20 at 10:49
  • @AppDev. Yeah i already know about that flag but isn't there a way to do this without using this temporary solution? – Vince VD Sep 27 '20 at 10:52
  • @AppDev. Im also confused by why it works for some files and some return this error. – Vince VD Sep 27 '20 at 10:56
  • Even I found this permission error for camera and my gallery URI's and I also faced this issues only on some of the times like for some devices I was getting proper image data in `onActivity result` while in some other devices i was getting this Security Exception. Although I got something to workaround with my issue but here's a different case. Not sure about "Why it works for some files". – WhiteSpidy. Sep 27 '20 at 11:01
  • `getDocumentUri(Uri mediaUri)` Please start your post with the exact value of mediaUri. And tell how your app obtained it. Also tell if it is from a file which your app created. Put all in your post. Start your post with it. – blackapps Sep 27 '20 at 11:05
  • Also tell, if you have a media store uri, why you would first convert it to a document uri. – blackapps Sep 27 '20 at 11:08
  • @blackapps I added the value for mediaUri in my post, "why you would first convert it to a document uri?", so i can delete the file with DocumentFile from the storage. – Vince VD Sep 27 '20 at 13:42
  • Why dont you just delete using the media store if it is a media store uri? I asked that before. – blackapps Sep 27 '20 at 16:49
  • @blackapps do you mean with ContentResolver? That doesn't work, it deletes the entry in the MediaStore and not the file itself. – Vince VD Sep 28 '20 at 16:25
  • In Android Q the file is also deleted. Below Q you have to do it yourself yet. – blackapps Sep 28 '20 at 18:06
  • @blackapps Can you post an example then? Because i'm pretty sure thats not true `getContentResolver().delete(mediaUri, null, null);` doesn't delete the physical file. It only deletes the database entry and will reappear after rebooting device. – Vince VD Oct 12 '20 at 18:18
  • You did not tell which uri you tried to delete and i asked you before. – blackapps Oct 13 '20 at 08:10
  • @blackapps I already told you what it was, look at the 7th comment. The Uri i'm trying to delete is a content Uri obtained with `ContentUris.withAppendedId();` – Vince VD Oct 15 '20 at 20:15
  • If SAF has never given you permission for that file or its directory you cannot do much. Further you did not ppst reproducable code. – blackapps Oct 15 '20 at 20:25

1 Answers1

1

Try this method. You need to take the persistable uri permission using SAF of the parent folder, then pass the uri & name of the file to delete. (I have a model class to handle both.)

public void deleteAPI29(ArrayList<Media> mediaList) {
        Uri persistedUri = getContentResolver().getPersistedUriPermissions().get(0).getUri();
        DocumentFile documentFile = DocumentFile.fromTreeUri(this, persistedUri);
        for (int i = 0; i < mediaList.size(); i++) {
            File file = new File(mediaList.get(i).getPath());
            DocumentFile nextDocument = documentFile.findFile(file.getName());
            try {
                DocumentsContract.deleteDocument(getContentResolver(), nextDocument.getUri());
            } catch (FileNotFoundException e) {
                e.printStackTrace();
            }
        }
    }
Dev4Life
  • 2,328
  • 8
  • 22