Storage Access Framework: сохранить права доступа к файлам после отзыва дерева разрешений

В приложении пользователь выбирает каталог через SAF, используя ACTION_OPEN_DOCUMENT_TREE намерение и пользователь может создавать различные файлы внутри. Проблема в том, что когда пользователь меняет рабочий каталог (всегда используя SAF), доступ к этим файлам теряется. Как сохранить доступ как ACTION_CREATE_DOCUMENT или же ACTION_OPEN_DOCUMENT?

вот мой код

  • выбирая реж
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();

Как только я перезапускаю приложение и пытаюсь открыть файл, созданный в старом каталоге, я получаю:java.lang.SecurityException: No persistable permission grants found for UID <<<uid>>> and Uri 0 @ <<<file uri>>>

пример:

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

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

как справиться с этим? или просто сохранить права доступа к каталогу, пока приложение не будет удалено???

1 ответ

Решение

Простое решение - не выпускать разрешение, пока не закончите со всем содержимым в этом дереве. Пользователь, изменяющий, какое дерево он будет использовать для будущих действий, не меняет вашу потребность работать с деревом, которое он хотел для прошлых действий, по крайней мере для тех фрагментов контента, которые вы все еще держите Uri значения для.

Вы можете попробовать запросить Uri предоставляет отдельным частям содержимого в старом дереве, а затем освобождает разрешение на старом дереве. Я никогда не пробовал это, поэтому я не знаю, сработает ли это. Это самое элегантное решение с точки зрения разрешений, которое я могу себе представить, поскольку у вас нет прав больше, чем вам действительно нужно.

Другие вопросы по тегам