Copy files from external storage into internal storage in Android 11

Viewed 2269

I want to use some .pdf files in my app which are located in external storage. For using those files in android 10&11 I am going to copy files into internal storage. My code is working well in Android 10 but not in Android 11

Exception: java.io.FileNotFoundException: open failed: EACCES (Permission denied)

error is coming.

My code is as below;

manifest

<uses-permission
    android:name="android.permission.WRITE_EXTERNAL_STORAGE"
    android:maxSdkVersion="28" />
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />

<provider
        android:name="androidx.core.content.FileProvider"
        android:authorities="com.packagename"
        android:exported="false"
        android:grantUriPermissions="true">
        <meta-data
            android:name="android.support.FILE_PROVIDER_PATHS"
            android:resource="@xml/provider_paths" />
</provider>

provider_paths.xml

<?xml version="1.0" encoding="utf-8"?>
<paths>
<external-path
    name="external_files"
    path="." />
<files-path
    name="."
    path="/"/>
</paths>

in fragment

val contentUri = FileProvider.getUriForFile(
                context,
                "com.packagename",
              File("/sdcard/Documents/PDFConverter/my_file.pdf")
            )

ScopeStoreUtils.copyFileIntoFiles(context, contentUri)

util class

object ScopeStoreUtils {

fun copyFileIntoFilesDir(context: Context, fileUri: Uri) {
    if (Build.VERSION.SDK_INT >= 29) {
        // r for read
        try {
            val parcelFileDescriptor = 
            context.contentResolver.openFileDescriptor(fileUri, "r", null)
            val inputStream = FileInputStream(parcelFileDescriptor?.fileDescriptor)
            val destinationFile = File(context.filesDir, 
            context.contentResolver.getFileName(fileUri))
            val outputStream = FileOutputStream(destinationFile)
            copy(inputStream, outputStream)
        } catch (e: Exception) {
            Log.e("ScopeStoreUtils", "copyFileIntoFilesDir: Exception: $e")
        }
    }
}



private fun ContentResolver.getFileName(fileUri: Uri): String {
    var name = ""
    val returnCursor = this.query(fileUri, null, null, null, null)
    if (returnCursor != null) {
        val nameIndex = returnCursor.getColumnIndex(OpenableColumns.DISPLAY_NAME)
        returnCursor.moveToFirst()
        name = returnCursor.getString(nameIndex)
        returnCursor.close()
    }
    return name
}


@Throws(IOException::class)
fun copy(input: InputStream?, output: OutputStream?): Int {
    val count = copyLarge(input!!, output!!)
    return if (count > Int.MAX_VALUE) {
        -1
    } else count.toInt()
}


private const val DEFAULT_BUFFER_SIZE = 1024 * 4


@Throws(IOException::class)
fun copyLarge(input: InputStream, output: OutputStream): Long {
    val buffer = ByteArray(DEFAULT_BUFFER_SIZE)
    var count: Long = 0
    var n: Int
    while (-1 != input.read(buffer).also { n = it }) {
        output.write(buffer, 0, n)
        count += n.toLong()
    }
    return count
}


}
0 Answers
Related