Léa Massiot
Léa Massiot

Reputation: 2018

Deleting a file given a Storage Access Framework uri and using content resolver fails

I am trying to delete a file using Storage Access Framework. Below are some elements of code:

public class MyActivity extends AppCompatActivity
{
    @Override
    public boolean onOptionsItemSelected(MenuItem menuItem)
    {
    int n_requestCode;

        switch(menuItem.getItemId())
        {
            [...]
            case R.id.delete_file:
                n_requestCode = 108;
                startSAFActionOpenDocumentTree(n_requestCode);
                break;
            [...]
        }
        [...]
    }

    public void startSAFActionOpenDocumentTree(int n_requestCode)
    {
    Intent intent;
    
        intent = new Intent(Intent.ACTION_OPEN_DOCUMENT_TREE);  
        startActivityForResult(intent, n_requestCode);
    }

    private void startSAFActionOpenDocument(int n_requestCode)
    {
    Intent intent = null;

        intent = new Intent(Intent.ACTION_OPEN_DOCUMENT);
        intent.addCategory(Intent.CATEGORY_OPENABLE);
        intent.setType("*/*");
        startActivityForResult(intent, n_requestCode);
    }

    protected void onActivityResult(int n_requestCode, int n_resultCode, Intent data)
    {
    android.net.Uri uri;
    ContentResolver contentResolver;

        if(n_requestCode == 108)
        {
            n_requestCode = 109;
            startSAFActionOpenDocument(n_requestCode);
        }
        else if(n_requestCode == 109)
        {
            uri = data.getData();                      
            contentResolver = getContentResolver();

            try
            {
                contentResolver.delete(uri, null, null);
            }
            catch(Exception exn)
            {
                exn.printStackTrace();
            }
        }
    }
}

Hence, the use case is the following:

The problem is the following:

The contentResolver.delete(uri, null, null); raises the following exception:

W/System.err: java.lang.UnsupportedOperationException: Delete not supported
            at android.database.DatabaseUtils.readExceptionFromParcel(DatabaseUtils.java:167)
            at android.database.DatabaseUtils.readExceptionFromParcel(DatabaseUtils.java:135)
            at android.content.ContentProviderProxy.delete(ContentProviderNative.java:544)
            at android.content.ContentResolver.delete(ContentResolver.java:1330)
            at [...]MyActivity.onActivityResult(MyActivity.java:[...])
            at android.app.Activity.dispatchActivityResult(Activity.java:6490)
            at android.app.ActivityThread.deliverResults(ActivityThread.java:3695)
            at android.app.ActivityThread.handleSendResult(ActivityThread.java:3742)
            at android.app.ActivityThread.access$1400(ActivityThread.java:150)
            at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1393)
W/System.err:   at android.os.Handler.dispatchMessage(Handler.java:102)
                at android.os.Looper.loop(Looper.java:148)
                at android.app.ActivityThread.main(ActivityThread.java:5417)
                at java.lang.reflect.Method.invoke(Native Method)
                at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:726)
                at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:616)

Note that, at another place in the code, I use the delete() method of the java.io.File class with an argument that is a file path (a String), not an android.net.Uri and the deletion works for the very same file.

Can you please help me solve that problem? Thanks.

Upvotes: 0

Views: 823

Answers (3)

Michał Klimczak
Michał Klimczak

Reputation: 13144

Other answers use DocumentFile, which requires an additional library dependency.

Instead, you can simply use:

DocumentsContract.deleteDocument(context.contentResolver, destinationUri)

Upvotes: 0

Léa Massiot
Léa Massiot

Reputation: 2018

I found this solution using the class DocumentFile instead of ContentResolver.

The file is deleted.

public class MyActivity extends AppCompatActivity
{    
    @Override
    public boolean onOptionsItemSelected(MenuItem menuItem)
    {
    int n_requestCode;

        switch(menuItem.getItemId())
        {
            [...]
            case R.id.delete_file:
                n_requestCode = 109;
                startSAFActionOpenDocument(n_requestCode);
                break;
            [...]
        }
        [...]
    }

    private void startSAFActionOpenDocument(int n_requestCode)
    {
    Intent intent = null;

        intent = new Intent(Intent.ACTION_OPEN_DOCUMENT);
        intent.addCategory(Intent.CATEGORY_OPENABLE);
        intent.setType("*/*");
        startActivityForResult(intent, n_requestCode);
    }

    protected void onActivityResult(int n_requestCode, int n_resultCode, Intent data)
    {
    DocumentFile srcDoc;

        if(n_requestCode == 109)
        {
            srcDoc = DocumentFile.fromSingleUri(this, data.getData());
            try
            {
                srcDoc.delete();
            }
            catch(Exception exn)
            {
                exn.printStackTrace();
            }                
        }
    }
}

Upvotes: 2

blackapps
blackapps

Reputation: 9292

The operation is not supported is the message.

Try instead:

DocumentFile srcDoc = DocumentFile.fromSingleUri(context, data.getData());

if ( srcDoc.delete() )
                    {

                    }

Your answer may work but code is too complicated. Also the user does not have to select the directory first.

Upvotes: 6

Related Questions