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

1k Views Asked by At

trying to get file(PDF) form internal storage to upload on server with the help of Android ResultLauncher API, getting Uri in result but I am unable to read that Uri. When trying to copy that file to my app's scope directory with the help of result Uri, getting permission error on contentResolver.openInputStream(uri). this is the error:

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

How can I copy file in app's scope directory? This is my ResultLauncher:

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

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

this is how I am launching:

singleTypeResultLauncher.launch("application/pdf")

this is method in with app is crashing:

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
    }

using provider paths:

<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

There are 1 best solutions below

0
On BEST ANSWER

I am unable to read that Uri

You are not trying to read that Uri. You are trying to read a different Uri:

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

Replace that with:

val tempUri = it

...or, just remove tempUri entirely and use it directly.

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

Note that you do not necessarily need to copy the content to upload it.