带有从存储访问框架 (SAF) 收到的 Uri 的 Android contentResolver.query

问题描述

以前我有逻辑,我在外部存储上找到所需的文件夹(使用我自己的文件选择器将文件返回到所选文件夹),然后查询其中的所有媒体文件,使用路径作为前缀,有一个逻辑:

fun loadAudio(path: String): List<Audio> {

        val contentResolver = context.contentResolver
        val uri = MediaStore.Audio.Media.EXTERNAL_CONTENT_URI

        val projection = arrayOf(
                MediaStore.Audio.Media.DATA,MediaStore.Audio.Media.TITLE,MediaStore.Audio.Media.ALBUM,MediaStore.Audio.Media.ARTIST,MediaStore.Audio.Media.DURATION,MediaStore.Audio.Albums.ALBUM_ID
        )

        val selection = "${MediaStore.Audio.Media.IS_MUSIC} != 0 AND ${MediaStore.Audio.Media.DATA} LIKE '${path}%'"
        val sortOrder = MediaStore.Audio.Media.TITLE + " ASC"
        val cursor = contentResolver.query(uri,projection,selection,null,sortOrder)

        val tempAudioList = arraylistof<Audio>()

        if (cursor != null && cursor.count > 0) {
            while (cursor.movetoNext()) {
                val data = cursor.getString(cursor.getColumnIndex(MediaStore.Audio.Media.DATA))
                val fileName = data.split(File.separator).let { it[it.size - 1] }
                val title = cursor.getString(cursor.getColumnIndex(MediaStore.Audio.Media.TITLE))
                val album = cursor.getString(cursor.getColumnIndex(MediaStore.Audio.Media.ALBUM))
                val artist = cursor.getString(cursor.getColumnIndex(MediaStore.Audio.Media.ARTIST))
                val duration = cursor.getLong(cursor.getColumnIndex(MediaStore.Audio.Media.DURATION))
                val albumId = cursor.getLong(cursor.getColumnIndex(MediaStore.Audio.Albums.ALBUM_ID))

                // Save to audioList
                tempAudioList.add(Audio(data,fileName,title,album,artist,duration,albumId))
            }
        }

        cursor!!.close()
        return tempAudioList
    }

现在android弃用了使用文件的直接访问,我们被迫使用存储访问框架(SAF)。 于是我开始使用:

val intent = Intent(Intent.ACTION_OPEN_DOCUMENT_TREE)
        intent.putExtra("android.content.extra.SHOW_ADVANCED",true);
        startActivityForResult(intent,42)

这将 Uri 返回到文件夹。 问题是:我不再拥有该文件夹的直接文件系统路径,因此当我尝试使用 contentResolver.query 查询媒体文件时,我不再能够编写如下选择:

val selection = "${MediaStore.Audio.Media.IS_MUSIC} != 0 AND ${MediaStore.Audio.Media.DATA} LIKE '${path}%'"

因为我没有路了。 我改用了 DocumentFile,但是当我尝试在该 sql 选择子句中使用该 Uri 时,它不起作用...... 我有 1 个解决方法,例如:从 DocumentFile 获取文件名,然后尝试在查询中使用它并按 ${MediaStore.Audio.Media.disPLAY_NAME} LIKE ${name} 过滤,但文件系统可能有多个同名文件。 有人可以建议我应该遵循的方式来选择文件夹(就像我现在使用 SAF 所做的那样,然后能够使用 contentResolver.query 查询文件夹中的所有音频以获取它们的媒体标签

此外,如果我使用文件夹的 Uri 或其任何子文件

contentResolver.query(uri,sortOrder)

in 不返回任何媒体标签

解决方法

暂无找到可以解决该程序问题的有效方法,小编努力寻找整理中!

如果你已经找到好的解决方法,欢迎将解决方案带上本链接一起发送给小编。

小编邮箱:dio#foxmail.com (将#修改为@)