Storage Access Framework: сохранить права доступа к файлам после отзыва дерева разрешений - PullRequest
1 голос
/ 13 апреля 2019

В приложении пользователь выбирает каталог через 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 Ответ

1 голос
/ 14 апреля 2019

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

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

...