androidsaf

Storage Access Framework: keep file permissions after revoke tree permissions


In the app the user picks a directory via SAF using ACTION_OPEN_DOCUMENT_TREE intent and the user can create various files inside. The problem is when the user change the working dir (always using SAF), the access on these files are lost. How keep the access like ACTION_CREATE_DOCUMENT or ACTION_OPEN_DOCUMENT?

here my code

private void showDirectoryPicker() {
        Intent i = new Intent(Intent.ACTION_OPEN_DOCUMENT_TREE)
               i.addFlags(Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION);
               i.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION | Intent.FLAG_GRANT_WRITE_URI_PERMISSION);

        startActivityForResult(i, 12345);
}
public void onActivityResult(int requestCode, int resultCode, Intent data) {
        if (resultCode != Activity.RESULT_OK) return;
        mDir = data.getData();

        grantUriPermission(getPackageName(), mDir, Intent.FLAG_GRANT_READ_URI_PERMISSION | Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
        getContentResolver().takePersistableUriPermission(mDir, Intent.FLAG_GRANT_READ_URI_PERMISSION | Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
}
 mFile = DocumentFile.fromTreeUri(getContext(), mDir).createFile("text/plain", "some file.txt").getUri();
getContentResolver().releasePersistableUriPermission(mDir, Intent.FLAG_GRANT_READ_URI_PERMISSION | Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
revokeUriPermission(mDir, Intent.FLAG_GRANT_READ_URI_PERMISSION | Intent.FLAG_GRANT_WRITE_URI_PERMISSION);

mDir = null;

// ask for another dir
showDirectoryPicker();

Once I restart the application and try to open a file created in the old directory, i get: java.lang.SecurityException: No persistable permission grants found for UID <<<uid>>> and Uri 0 @ <<<file uri>>>

example:

DocumentFile file = DocumentFile.fromSingleUri(getContext(), mFile);

if (file.getName() == null) {
     // permissions lost
} else {
     // do something
}

how handle this? or just keep the directory permissions until the application is uninstalled???


Solution

  • The simple solution is to not release the permission grant until you are done with all content in that tree. The user changing which tree they will use for future actions does not change your need to work with the tree they had wanted for past actions, at least for those pieces of content that you still hold Uri values for.

    You could try requesting individual Uri grants to the individual pieces of content in the old tree, then releasing the permission grant on the old tree. I have never tried this, so I don't know if it will work. This is the most elegant solution permission-wise that I can think of, in that you have no more rights than you actually need.