Android 13 Photo / Video Picker -来自URI的文件名是垃圾

fnatzsnv  于 2023-11-15  发布在  Android
关注(0)|答案(2)|浏览(176)

通过ActivityResultContracts.PickVisualMedia使用Android 13中引入的选取器时,将返回一个Uri(表示所选媒体项):

content://media/picker/0/com.android.providers.media.photopicker/media/1000000198

字符串
如果我使用内容解析器并询问光标,我会得到这样的结果:

duration = 38003
orientation = 0
height = 2336
_display_name = 1000000198.mp4
datetaken = 1681826421000
mime_type = video/mp4
_data = /sdcard/.transforms/synthetic/picker/0/com.android.providers.media.photopicker/media/1000000198.mp4
_size = 9920806
width = 1072


通常用于文件名的列是 OpenableColumns. NAME(_display_name)。然而,正如你所看到的,这里的值只是一些垃圾数字文件名,而不是所选的实际文件名。这不是所选视频的实际文件名
有没有办法使用这个Android 13的照片/视频选择器,并获得用户选择的文件的实际文件名,而不是这个垃圾数字文件名?

5w9g7ksd

5w9g7ksd1#

据我所知,编译器返回的uri是一个内容提供者uri。内容提供者应该给予满足您用例的API,而不需要文件的实际路径。请随意阅读文档:https://developer.android.com/guide/topics/providers/content-providers
我目前想到的解决方法是使用_data列中的值作为路径。在我的情况下,我需要访问框架。我可以将此路径设置为MediaMetadataRetriever示例的数据源。下面是我的示例代码(* 免责声明:我绝不是AndroidMaven。此代码可能尚未准备好生产。*)。

fun processUri(selectedImageUri: Uri) {
        val cursor: Cursor? = contentResolver.query(
            selectedImageUri, null, null, null, null, null
        )

        if (cursor == null) {
            //...
        }
        if (cursor.count == 0) {
            //...
        }
        if (!cursor.moveToFirst()) {
            //...
        }

        val dataColIndex = cursor.getColumnIndex("_data")
        val dataPath: String = cursor.getString(dataColIndex)
        val frame = getFrame(dataPath, 0)

        state.update { _ ->
            // use frame
        }
    }

    private fun getFrame(dataPath: String, timeUs: Long): Bitmap? {
        val retriever = MediaMetadataRetriever()
        try {
            retriever.setDataSource(dataPath)
            return retriever.getFrameAtTime(timeUs, MediaMetadataRetriever.OPTION_CLOSEST)
        } catch (ex: IllegalArgumentException) {
            //...
        } catch (ex: RuntimeException) {
            //...
        } finally {
            try {
                retriever.release()
            } catch (ex: RuntimeException) {
                //...
            }
        }
    }

字符串
PS.使用_data列似乎是API中的一个约定。请参阅openFileHelper方法。

hgncfbus

hgncfbus2#

从我个人的研究,我不认为这是可能的,以获得文件/显示名称从照片选取器。
这是一个open issue(在撰写本文时),谷歌尚未回应请求。
我目前看到的唯一选择是要么接受我们没有得到文件名,并希望在未来修复或实现自己的文件/照片选择器(当然,这需要额外的权限,因为它不是一个系统应用程序)

相关问题