[Переписать, основываясь на комментариях]
Упрощенный пример:
rootUri
получается с помощью ACTION_OPEN_DOCUMENT_TREE
. Затем я создаю папку (или несколько вложенных папок):
val rootTree = DocumentFile.fromTreeUri(context, rootUri) // rootTree.name == "treeRoot"
val childTree = rootTree.createDirectory("ChildDir1") // childTree.name == "ChildDir1"
val childUriStr = childTree.uri.toString()
Я сохраняю childUriStr
в локальной базе данных, чтобы впоследствии я мог воссоздать childTree
. childUriStr
содержит все необходимые элементы: authority
, rootTree
documentId и childTree
documentId. Таким образом, childTree
может быть воссоздан с помощью:
val childUri = Uri.parse(childUriStr)
val childTreeCopy = TreeDocumentFile(
DocumentFile.fromTreeUri(context, childTree), // equals rootTree
context,
childUri
)
Но конструктор TreeDocumentFile()
является частным для пакета и используется только для внутреннего использования и DocumentFile.fromTreeUri()
.
Обходной путь 1 ( медленно):
var childTree = DocumentFile.fromTreeUri(context, childUri)!! // rootTree
// get subfolders
val subfolders = DocumentsContract.getDocumentId(childUri)
.substringAfter(
// root documentId
DocumentsContract.getDocumentId(childTree.uri))
).trim('/').split('/')
// move down the folder structure
subfolders.forEach { childTree = childTree.findFile(it)!! }
// result
childTree
Обходной путь 2 (информация о rootTree потеряна):
val childAsRootUri = DocumentsContract.buildTreeDocumentUri(
childUri.authority,
DocumentsContract.getDocumentId(childUri)
)
var childAsRootTree = DocumentFile.fromTreeUri(context, childAsRootUri)!!
Здесь дерево посажено в подпапку, поэтому я не может использовать childAsRootTree.parent
, не может разрешить имя childAsRootTree.name == null
и, возможно, некоторые другие всплывающие подсказки - определенно не рекомендуется. DocumentFile.fromSingleUri()
также теряет слишком много функциональности по сравнению с TreeDocumentFile
.
Обходной путь 3 (дополнительный код для поддержки):
Написание собственной оболочки на основе TreeDocumentFile
Вариант использования (читать не нужно)
Обратите внимание, что то, что описано выше, является упрощенным примером. Возможный вариант использования, похожий на мой: пользователь выбирает один файл или папку с несколькими файлами через проводник в приложении (шаг 1). Файл root из проводника в приложении получен ACTION_OPEN_DOCUMENT_TREE
. Пользователь может обрабатывать файлы, а затем обработанные файлы сохраняются в том же каталоге, если пользователь выбрал папку на шаге 1, или рядом с выбранным файлом в новой папке, если пользователь выбрал файл на шаге 1 (для этого требуется доступ к родительской папке выбранный файл). Позже пользователь может выбрать другое расположение сохраненных файлов.