I'm currently using SAF to access directories, saving (taking) the open tree permission and then in turn save sub directory URIs as strings.
DocumentFile.listFiles().foreach{
// example uri string
// content://com.android.externalstorage.documents/tree/primary%3Aappfiles%2Fsubdir1/document/primary%3Aappfiles%2Fsubdir1%2Fmyfiles1
it.uri.toString() // save these paths to access sub dirs and files
}
Afterwards I'm trying to convert those Uri strings back which returns the correct name for sub directory "myfiles1", but I end up with a security exception when I attempt to call listFiles()
like so:
DocumentFile.fromSingleUri(ctx,Uri.parse(savedSubdirUriString))
On the other hand if I use DocumentFile.fromTreeUri
it only returns the top level dir "subdir1" instead of "myfiles1" which means I have to traverse my way to it.
Is there a way to use the saved DocumentFile.Uri
string to reach "myfiles1" directly, so that in turn I can traverse through deeper sub directories and files?
Searching around I came across this post but I can't find any detailed examples of how to use the code so I tried:
val uri = Uri.parse(savedSubdirUriString)
val newUri = DocumentsContract.buildChildDocumentsUriUsingTree(uri, DocumentsContract.getDocumentId(uri));
val newUriString = newUri.toString()
// content://com.android.externalstorage.documents/tree/primary%3Aappfiles%2Fsubdir1/document/primary%3Aappfiles%2Fsubdir1%2Fmyfiles1/children
val df = DocumentFile.fromTreeUri(newUri)
// still returns top level subdir1 instead of myfiles1
// trying to access myfiles1 as a dir from saved uri that can be traversed
It only seems to append "/children" to the end of the Uri string so I'm not sure how it's of use.
Hope someone can help shed some light on this.
Update 1:
So I spent some more time looking into this issue about accessing and listing the content of sub directories, multi-levels deep inside the permitted parent directory (saved via ContentResolver.takePersistableUriPermission
).
I found an article showing how to use DocumentsContract to traverse a directory's contents but again, it only seems to allow the permitted top level directory. If you pass the Uri of a sub directory into DocumentsContract.buildChildDocumentsUriUsingTree
as above, you still end up with the top level parent directory.
If I attempt to "hack" the Uri to access "myfiles1" directly so that it's:
content://com.android.externalstorage.documents/tree/primary%3Aappfiles%2Fsubdir1%2Fmyfiles1/document/primary%3Aappfiles%2Fsubdir1%2Fmyfiles1
Instead of the original...
content://com.android.externalstorage.documents/tree/primary%3Aappfiles%2Fsubdir1/document/primary%3Aappfiles%2Fsubdir1%2Fmyfiles1
It just results in a security exception again, just like if you used DocumentFile.fromSingleUri
unfortunately.
Fair enough considering why file permissions have been tightened in the OS. Just odd you can't use a direct path to deeper sub-directories, when you can take the parent directory then use DocumentFile.listfiles()
to traverse your way down...