如何在 android 11 中使用 android ResultLauncher 复制文件并获取 Uri(具有读取权限)

how to copy file and get Uri (with read permisssion) using android ResultLauncher in android 11

尝试在 Android ResultLauncher API 的帮助下从内部存储中获取文件 (PDF) 上传到服务器,得到 Uri 结果,但我无法阅读乌里。 在结果 Uri 的帮助下尝试将该文件复制到我的应用程序的范围目​​录时, 在 contentResolver.openInputStream(uri) 上获取权限错误。这是错误:

Permission Denial: reading com.android.providers.media.MediaDocumentsProvider uri <my file uri>  requires that you obtain access using ACTION_OPEN_DOCUMENT or related APIs

如何复制应用程序范围目录中的文件? 这是我的 ResultLauncher:

singleTypeResultLauncher =
            fragment.registerForActivityResult(ActivityResultContracts.GetContent()){
                    result ->
                result?.let{
                    val tempUri = Uri.parse(it.toString().replace("%3A", ":"))

                    val path = createCopyAndReturnRealPath(fragment.requireContext(), tempUri)
                }
            }

这就是我的启动方式:

singleTypeResultLauncher.launch("application/pdf")

这是应用程序崩溃的方法:

crashing on val inputStream = contentResolver.openInputStream(uri)

fun createCopyAndReturnRealPath(context: Context, uri: Uri): String? {
        val contentResolver = context.contentResolver ?: return null
        val mimeType = getMimeType(context, uri).getSafe()
        val fileExt = "." + mimeType.substring(mimeType.indexOf('/') + 1)
        val filePath: String = (context.dataDir.absolutePath + File.separator
                + System.currentTimeMillis())
        val file = File(filePath)
        try {
            file.parentFile.mkdirs()
            file.createNewFile()
            val inputStream = contentResolver.openInputStream(uri) ?: return null //crashing here
            val outputStream: OutputStream = FileOutputStream(file)
            val buf = ByteArray(1024)
            var len: Int
            while (inputStream.read(buf).also { len = it } > 0) outputStream.write(buf, 0, len)
            outputStream.close()
            inputStream.close()
        } catch (ignore: IOException) {
            return null
        }
        return file.absolutePath
    }

使用提供商路径:

<paths>
    <external-path
        name="external"
        path="." />
    <external-files-path
        name="external_files"
        path="." />
    <cache-path
        name="cache"
        path="." />
    <external-cache-path
        name="external_cache"
        path="." />
    <files-path
        name="files"
        path="." />
</paths>

I am unable to read that Uri

您没有试图阅读 Uri。您正在尝试阅读不同的 Uri:

val tempUri = Uri.parse(it.toString().replace("%3A", ":"))

将其替换为:

val tempUri = it

...或者,完全删除 tempUri 并直接使用 it

trying to get file(PDF) form internal storage to upload on server

注意 .