Android APIv29 FileNotFoundException EACCES(权限被拒绝)

Din*_*inu 3 android filenotfoundexception kotlin android-external-storage android-api-levels

为targetSdkVersion v29构建时,我无法访问存储。

这是我的gradle配置:

    compileSdkVersion 29
    buildToolsVersion "29.0.2"
    ...
        minSdkVersion 15
        targetSdkVersion 29
Run Code Online (Sandbox Code Playgroud)

请注意,WRITE_EXTERNAL_STORAGE为进行构建时,将授予权限并且相同的设置可以正常工作targetSdkVersion 28

这是我的实现:

        val outputFolder = File(baseFolder + File.separator + "Output Folder")
        if (!outputFolder.exists()) {
            if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
                Files.createDirectory(outputFolder.toPath()) //This allways returns false with targetSdkVersion 29
            } else {
                if (!outputFolder.mkdirs()) {
                    Log.e("SaveRaw", "Unable to create folder for audio recording")
                }
            }
        }

        outputFile = File("$baseFolder/Output Folder/$filename")
        try {
            fileOutputStream = FileOutputStream(outputFile)
        } catch (e: FileNotFoundException) {
            e.printStackTrace() // allways throwing exception here, even if Output Folder exists 
        }
Run Code Online (Sandbox Code Playgroud)

这是一个例外:

W/System.err: java.io.FileNotFoundException: /storage/emulated/0/Chirp Auto Tester/2019_10_17 10:44:43.raw: open failed: EACCES (Permission denied)
W/System.err:     at libcore.io.IoBridge.open(IoBridge.java:496)
        at java.io.FileOutputStream.<init>(FileOutputStream.java:235)
        at java.io.FileOutputStream.<init>(FileOutputStream.java:186)
Run Code Online (Sandbox Code Playgroud)

希望任何人都有答案,我在这里想念什么?

更新:

这是哪里baseFolder来的。请注意,这getExternalStorageDirectory是不建议使用的方法。

        val baseFolder: String = if (Environment.getExternalStorageState().equals(Environment.MEDIA_MOUNTED)) {
            Environment.getExternalStorageDirectory().absolutePath
        } else {
            context.filesDir.absolutePath
        }
Run Code Online (Sandbox Code Playgroud)

谢谢

Nik*_*lgo 6

从Android 11开始,存储权限被撤销,开发人员将需要考虑通过SAFMedia Store访问其所需存储的替代方法。目前,您可以通过在清单中的application标签内添加以下内容来继续使用所使用的内容:

android:requestLegacyExternalStorage="true"
Run Code Online (Sandbox Code Playgroud)

您可能要考虑将minSDK更改为19,并用于getExternalFilesDir()获取不需要任何权限的路径。