как скопировать файл и получить Uri (с разрешением на чтение) с помощью Android ResultLauncher в Android 11

попытка получить файл (PDF) из внутреннего хранилища для загрузки на сервер с помощью Android ResultLauncherAPI, в результате получаю Uri, но я не могу прочитать этот 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>

1 ответ

Я не могу прочитать это Ури

Вы не пытаетесь это прочитать. Вы пытаетесь прочитать другое Uri:

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

Замените это на:

      val tempUri = it

... или просто удалить tempUriполностью и использовать itнапрямую.

попытка получить файл (PDF) из внутреннего хранилища для загрузки на сервер

Обратите внимание, что вам не обязательно копировать контент, чтобы загрузить его .

Другие вопросы по тегам