我的问题与this question非常相似。 我使用ACTION_OPEN_DOCUMENT_TREE获取了目录的内容Uri。 得到这样的东西
content://com.android.externalstorage.documents/tree/primary%3ASHAREit%2Fpictures
选择目录时的结果。 现在,我的问题是我如何访问目录中的所有文件(最好是子目录)。
答案 0 :(得分:3)
使用DocumentFile.fromTreeUri()
为您的树创建a DocumentFile
。然后,use listFiles()
获取该树内的文档和子树的列表。对于isDirectory()
返回true
的人,您可以进一步遍历树。对于其余部分,请使用getUri()
获取文档的Uri
,如果需要,可以在openInputStream()
上使用ContentResolver
来获取内容。
答案 1 :(得分:0)
以下是与@CommonsWare answer相关的代码段。
使用Intent.ACTION_OPEN_DOCUMENT_TREE
启动文件选择器
startActivityForResult(
Intent.createChooser(Intent(Intent.ACTION_OPEN_DOCUMENT_TREE), "Choose directory"),
IMPORT_FILE_REQUEST
)
从文件选择器接收所选目录的Uri
override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) {
when (requestCode) {
IMPORT_FILE_REQUEST -> {
if (resultCode != Activity.RESULT_OK) return
val uri = data?.data ?: return
// get children uri from the tree uri
val childrenUri =
DocumentsContract.buildChildDocumentsUriUsingTree(
uri,
DocumentsContract.getTreeDocumentId(uri)
)
// get document file from children uri
val tree = DocumentFile.fromTreeUri(this, childrenUri)
// get the list of the documents
tree?.listFiles()?.forEach { doc ->
// get the input stream of a single document
val iss = contentResolver.openInputStream(doc.uri)
// prepare the output stream
val oss = FileOutputStream(File(filesDir, doc.name))
// copy the file
CopyFile { result ->
println("file copied? $result")
}.execute(iss, oss)
}
}
}
}
使用AsyncTask
复制文件(随时使用线程,协程。)
class CopyFile(val callback: (Boolean) -> Unit) :
AsyncTask<Closeable, Int, Boolean>() {
override fun doInBackground(vararg closeables: Closeable): Boolean {
if (closeables.size != 2) throw IllegalArgumentException("two arguments required: input stream and output stream")
try {
(closeables[0] as InputStream).use { iss ->
(closeables[1] as OutputStream).use { oss ->
iss.copyTo(oss)
return true
}
}
} catch (e: Exception) {
e.printStackTrace()
}
return false
}
override fun onPostExecute(result: Boolean) {
callback.invoke(result)
}
}
答案 2 :(得分:0)
我对Android开发非常陌生,并且长期以来一直在理解CommonsWare的答案(以及其他资源)。这个resource也很有帮助。
您需要DocumentFile AndroidX library,因此将其添加到您的build.gradle
获得包含tree
的内容URI后,就可以使用DocumentFile.fromTreeUri
val filenamesToDocumentFile = mutableMapOf<String, DocumentFile>()
val documentsTree = DocumentFile.fromTreeUri(context, treeUri) ?: return
val childDocuments = documentsTree.listFiles()
for (childDocument in childDocuments) {
childDocuments[0].name?.let {
filenamesToDocumentFile[it] = childDocument
}
}
现在我要弄清楚如何使用此DocumentFile ...(提示:val inputStream = contentResolver.openInputStream(childDocument.uri)
)