I am trying to get all audio contained in a folder that the user picks.
The user is asked to pick a folder like this
getUri = registerForActivityResult(
ActivityResultContracts.OpenDocumentTree(),
activityResultCallback
)
getUri.launch(null)
I am trying to query the folder like this
var selection = MediaStore.Audio.Media.DISPLAY_NAME " != ?"
val selectionArgs = arrayListOf("")
if (data != null){
selection = " AND "
selection = if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.R) {
MediaStore.MediaColumns.RELATIVE_PATH " LIKE ? "
} else {
MediaStore.Audio.Media.DATA " LIKE ? "
}
selectionArgs.add("%$data%")
}
I have tried the following for data
uri.path.toString()
uri.encodedPath.toString()
uri.pathSegments.last().toString()
uri.pathSegments.joinToString ("/")
None of that is working. The query is empty when there should be three files. These files are in the MediaStore, as a query of all audio files in the MediaStore contains them. The docs are not very helpful (as usual). The stack overflow posts I found leave out how to get a path.
Perhaps I should ask how to get the user to pick a folder and get all the music from the folder they chose? The docs lead me to both code snippets above, so I would be floored if there was no way to connect them (except this is Android I am dealing with, so nothing surprises me anymore).
CodePudding user response:
OpenDocumentTree
gives you access to only the Uri
you receive and its children. It does not give you access to any path at all, much less one you could use with the MediaStore
APIs (nor would you want it to, given that the MediaStore
APIs are terrible to begin with).
Instead, the easiest way to deal with the Uri returned by OpenDocumentTree
is to pass it to DocumentFile.fromTreeUri()
, which gives a DocumentFile
object that you can call listFiles()
on and use getType()
to search for mime types starting with audio/
:
// Assuming you have your uri returned by OpenDocumentTree
val rootDirectoryFile = DocumentFile.fromTreeUri(uri)
val directories = ArrayDeque(rootDirectoryFile)
val audioFileUris = mutableListOf<Uri>()
// Loop through all of the subdirectories, starting with the root
while (directories.isNotEmpty()) {
val currentDirectory = directories.removeFirst()
// List all of the files in the current directory
val files = currentDirectory.listFiles()
for (file in files) {
if (file.isDirectory) {
// Add subdirectories to the list to search through
directories.add(file)
} else if (file.type?.startsWith("audio/")) {
// Add Uri of the audio file to the list
audioFileUris = file.uri
}
}
}
// Now audioFileUris has the Uris of all audio files