Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Storage Access Framework persist permissions not working

I use Android Storage Access Framework to access some files on SD card. It is important for me to persists this permissions, to be able to edit files after reboot of device.

So according to Storage Access Framework documentation I use Persist permissions that gives the user continued access to the files through your app, even if the device has been restarted.

However, after some time I noticed that for some users permissions were somehow revoked. Because when I am trying to use SAF for writing I get android.system.ErrnoException: open failed: EACCES (Permission denied) after that exception I check what permissions do I have using mContext.getContentResolver().getPersistedUriPermissions() however it return empty list. I am sure that user provide me with the right permissions and that permissions are for the currently installed Sd card, because I track this actions in the database.

Currently, in this case I am showing document picker so user can provide me one more time with new permissions, but asking user to perform same action often is not user friendly.

What can cause the revoke of permissions? And how I can prevent this revoke?

I have tested on all my devices multiple reboots of the phone, changing time, removing inserting sd card, but was not able to lost any of saf permissions.

I have next code for obtaining permissions:

private void openDocumentTree() {
        Intent intent = new Intent(Intent.ACTION_OPEN_DOCUMENT_TREE);
        intent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION | Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
        startActivityForResult(intent, REQUEST_CODE);
    }

public void onActivityResult(int requestCode, int resultCode, Intent data) {
        super.onActivityResult(requestCode, resultCode, data);
        if (resultCode == Activity.RESULT_OK && requestCode == REQUEST_CODE) {
            Uri treeUri = data.getData();
            final int takeFlags = data.getFlags() & ( 
                    Intent.FLAG_GRANT_READ_URI_PERMISSION | Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
            mContext.getContentResolver().takePersistableUriPermission(treeUri,
                    takeFlags);

                    //this is my internal class for saving and restoring tree uri permissions.
                    final Permission permission = Permission.from(treeUri);
                    mPermissionDao.save(permission);
        }
    }
like image 447
Rostyslav Roshak Avatar asked Sep 14 '15 11:09

Rostyslav Roshak


1 Answers

You need additional flags when requesting ACTION_OPEN_DOCUMENT_TREE.

openDocumentTree should look like

private void openDocumentTree() {
    Intent intent = new Intent(Intent.ACTION_OPEN_DOCUMENT_TREE);
    intent.addFlags(
        Intent.FLAG_GRANT_READ_URI_PERMISSION
        | Intent.FLAG_GRANT_WRITE_URI_PERMISSION
        | Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION
        | Intent.FLAG_GRANT_PREFIX_URI_PERMISSION);
    startActivityForResult(intent, REQUEST_CODE);
}

Review docs for FLAG_GRANT_PERSISTABLE_URI_PERMISSION and FLAG_GRANT_PREFIX_URI_PERMISSION

like image 73
Peter Tran Avatar answered Sep 30 '22 07:09

Peter Tran