简体   繁体   中英

Can't write to SD Card with permissions

I've been struggling to write on the sd card for quite some time and I've finally come to realize that there's a new kind of "permissions" for this job exclusively. First of all, this is the code which I use, hoping to get the permission and not need it later:

Intent intent = new Intent(Intent.ACTION_OPEN_DOCUMENT_TREE);
startActivityForResult(intent, RCODE);

@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
    super.onActivityResult(requestCode, resultCode, data);
    if (requestCode == RCODE && resultCode == Activity.RESULT_OK){
        Uri treeUri = data.getData();
        DocumentFile pickedDir = DocumentFile.fromTreeUri(this, treeUri);
        grantUriPermission(getPackageName(), treeUri, Intent.FLAG_GRANT_READ_URI_PERMISSION | Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
        getContentResolver().takePersistableUriPermission(treeUri, Intent.FLAG_GRANT_READ_URI_PERMISSION | Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
        App.editor.putBoolean("writable",true).apply();App.editor.commit();
    }
}

and here's the code I use to delete the files:

public static boolean deleteFile(Context context, File f){
    if (isOnInternal(f)){
        return f.delete();
    }else{
        String path = "/document/";
        String tp = f.getAbsolutePath().replace(getsdpath(),"").substring(1);
        path += getsdpath().replace("/storage/","")+":"+tp;
        Uri uri = new Uri.Builder()
                .scheme("content")
                .authority("com.android.externalstorage.documents")
                .path(path)
                .build();
        Log.e("path1",uri.getPath());
        return DocumentFile.fromSingleUri(context,uri).delete();
    }
}

Here's the LogCat message when I want to delete a file:

W/Documents: Failed to delete document
java.lang.SecurityException: Permission Denial: writing com.android.externalstorage.ExternalStorageProvider uri content://com.android.externalstorage.documents/document/1CE2-0E0E%3Aimg.jpg from pid=3000, uid=10060 requires android.permission.MANAGE_DOCUMENTS, or grantUriPermission()
    at android.os.Parcel.readException(Parcel.java:1599)
    at android.database.DatabaseUtils.readExceptionFromParcel(DatabaseUtils.java:183)
    at android.database.DatabaseUtils.readExceptionFromParcel(DatabaseUtils.java:135)
    at android.content.ContentProviderProxy.call(ContentProviderNative.java:646)
    at android.content.ContentProviderClient.call(ContentProviderClient.java:437)
    at android.provider.DocumentsContract.deleteDocument(DocumentsContract.java:1015)
    at android.provider.DocumentsContract.deleteDocument(DocumentsContract.java:999)
    at android.support.v4.provider.SingleDocumentFile.delete(SingleDocumentFile.java:98)
    at ir.coders.nahan.Utils.FileUtils.deleteFile(FileUtils.java:41)
    at ir.coders.nahan.App.deleteFile(App.java:314)
    at ir.coders.nahan.Activities.HidePics.lambda$onActivityResult$7(HidePics.java:230)
    at ir.coders.nahan.Activities.-$$Lambda$HidePics$Vwwkfk8tS-KV0NE8pJgYHtkKXnI.run(lambda)
    at android.os.Handler.handleCallback(Handler.java:739)
    at android.os.Handler.dispatchMessage(Handler.java:95)
    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)

Here are both paths taken by the below method:

uri.getPath();
the tree which I grant the permission from: /tree/1CE2-0E0E:
the file : /document/1CE2-0E0E:img.jpg

The code I use to delete the file is an attempt to duplicate the original URI made by android itslef when user chooses the file but it doesn't seem to work as planned.

I'd appreciate any help!

Add MANAGE_DOCUMENTS to your permissions either in manifest or through code. Your other permissions don't seem to cover this specific permission.

the tree which I grant the permission from: /tree/1CE2-0E0E:

the file : /document/1CE2-0E0E:img.jpg

The URI's roots are not the same. Inspect those two URIs as their do not look alike. I suspect that's the issue.

Somehow you should re-use the URI you sent grantUriPermission()

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM