如何从DocumentFile获取用于EXTRA_INITIAL_URI的目录URI?
我的应用让用户选择一个公共目录(使用 Intent.ACTION_OPEN_DOCUMENT_TREE)来创建一个用于保存文件的目录,稍后可以从设备中提取。我还想把创建的目录的路径持久化,以便在应用中更容易访问。
为此我尝试使用 File.mkdir() 和 Files.createDirectory(),但都没能创建出目录,因此我决定如下所示使用 DocumentFile:
fun saveFileDirectory(uri: Uri) {
val chosenDirectory = DocumentFile.fromTreeUri(applicationContext, uri)
if (chosenDirectory != null) {
val newDirectory = chosenDirectory.createDirectory("newDirectory")
newDirectory?.createDirectory("dir1")
newDirectory?.createDirectory("dir2")
val newUri = newDirectory?.uri
//persisting the path
viewModelScope.launch {
applicationContext.dataStore.updateData { data ->
data.copy(saveFileDirectory = newUri!!)
}
}
}
这段代码能够成功创建目录并将创建目录的Uri保存下来,但当我把该持久化的Uri作为文件选择器的初始Uri使用时,用户所选的目录(它是创建目录的父目录)会被打开。
例如,用户选择了 “/save” 目录,因此输入Uri为
content://com.android.externalstorage.documents/tree/primary:save
函数 saveFileDirectory 将保存以下路径:
content://com.android.externalstorage.documents/tree/primary:save/document/primary:save/newDirectory
随后,该Uri会被读入一个名为 localSaveFileDirectory 的变量,并像下面这样用作文件选择器的初始Uri:
val intent = Intent(Intent.ACTION_OPEN_DOCUMENT).apply {
addCategory(Intent.CATEGORY_OPENABLE)
putExtra(Intent.EXTRA_TITLE, "test.csv")
putExtra(DocumentsContract.EXTRA_INITIAL_URI, Uri.withAppendedPath(localSaveFileDirectory, "dir1"))
type = "*/*"
}
launcherRead.launch(intent)
然而,当用户尝试选择文件时,会打开 “/save” 目录。
我希望它打开 “/save/newDirectory”。
解决方案
我最终为所有必需的目录分别持久化 Uri 的值
fun saveFileDirectory(uri: Uri) {
val chosenDirectory = DocumentFile.fromTreeUri(applicationContext, uri)
if (chosenDirectory != null) {
val newDirectory = chosenDirectory.createDirectory("newDirectory")
val dir1Directory = newDirectory?.createDirectory("dir1")
val dir2Directory = newDirectory?.createDirectory("dir2")
val dir1Uri = dir1Directory?.uri
val dir2Uri = dir2Directory?.uri
saveFileDirectory1 = dir1Uri!!
saveFileDirectory2 = dir2Uri!!
viewModelScope.launch {
applicationContext.dataStore.updateData { data ->
data.copy(
saveFileDirectory1 = dir1Uri!!,
saveFileDirectory2 = dir2Uri!!
)
}
}
}
}
然后为需要它们的每个函数获取这些 Uri,如下例所示。
getSaveFileDirectory1() 输出 saveFileDirectory1 变量的值。
val intent = Intent(Intent.ACTION_OPEN_DOCUMENT).apply {
addCategory(Intent.CATEGORY_OPENABLE)
putExtra(Intent.EXTRA_TITLE, "test.csv")
putExtra(DocumentsContract.EXTRA_INITIAL_URI, getSaveFileDirectory1())
type = "*/*"
}
launcherRead.launch(intent)
站内所有文章版权归属LeftHeroAI导航站,无授权禁止任何主体转载、抄袭、复制内容,亦不得私自架设镜像站点。一经侵权,本站将通过法律途径追责。