Search code examples
androidkotlinandroid-permissionsfile-permissions

File cannot be updated in external storage


I have a file in storage and I'm trying to write data into that file. But an exception os thrown.

val file = File(myFilePath)
val data : String = my_data
var bW: BufferedWriter
try {
    bW = BufferedWriter(FileWriter(file, true));
    bW.write(data);
    bW.newLine();
    bW.flush();
    bW.close();
} catch (e: Exception) {
    Log.d("log", "error = $e")
}

The error I'm getting

java.io.FileNotFoundException: /storage/emulated/0/Download/myFolder/myFile.txt: open failed: EACCES (Permission denied)

I have placed the file in above path and I cross checked frequently that the file exists there. But why I'm getting FileNotFoundException I don't know.

My Android version is 10 QP1A and mobile I'm using redmi note 8 pro.

I tried all solutions that exists (5 to 8 years old) and nothing was working.


Solution

  • For API 29 (Android 10),

    1. Ensure you have android.permission.WRITE_EXTERNAL_STORAGE granted.

    2. Add android:requestLegacyExternalStorage="true" to your application element in your manifest file. Reference

    E.g.

    AndroidManifest.xml

    <manifest ...>
    
        <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
    
        <application
            ...
            android:requestLegacyExternalStorage="true">
            ...
        </application>
    
    </manifest>
    

    MyActivity.kt

    ...
    
            val permissionStatus = ActivityCompat.checkSelfPermission(this, Manifest.permission.WRITE_EXTERNAL_STORAGE)
            if(permissionStatus == PackageManager.PERMISSION_GRANTED) {
                lifecycleScope.launch(Dispatchers.IO) {
                    writeToFile()
                }
            } else {
                ActivityCompat.requestPermissions(this@MainActivity,
                    arrayOf(Manifest.permission.WRITE_EXTERNAL_STORAGE),
                    PERMISSION_REQUEST_CODE)
            }
    
    ...
    
        override fun onRequestPermissionsResult(requestCode: Int, permissions: Array<out String>, grantResults: IntArray) {
            super.onRequestPermissionsResult(requestCode, permissions, grantResults)
    
            if(grantResults.all { it == PackageManager.PERMISSION_GRANTED }) {
                lifecycleScope.launch(Dispatchers.IO) {
                    writeToFile()
                }
            }
        }
    
    ...
    
        @WorkerThread
        private fun writeToFile() {
            val file = File(<myFilePath>)
            val data = <my_data>
    
            with(BufferedWriter(FileWriter(file, true))) {
                write(data)
                newLine()
                flush()
                close()
            }
        }
    }