Android APIv29 FileNotFoundException EACCES (В доступе отказано) - PullRequest
2 голосов
/ 17 октября 2019

Я не могу получить доступ к хранилищу при сборке для targetSdkVersion v29.

Вот моя конфигурация gradle:

    compileSdkVersion 29
    buildToolsVersion "29.0.2"
    ...
        minSdkVersion 15
        targetSdkVersion 29

Обратите внимание, что разрешение 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 
        }

и вот исключение:

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)

Надеюсь, у кого-нибудь есть ответ,что мне здесь не хватает?

Обновление:

Вот откуда взято baseFolder. Обратите внимание, что getExternalStorageDirectory является устаревшим методом.

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

Спасибо

Ответы [ 4 ]

4 голосов
/ 17 октября 2019

Начиная с Android 11 разрешение на хранение аннулируется, и разработчикам необходимо будет рассмотреть альтернативные способы доступа к нужному хранилищу через SAF или Media Store . В настоящее время вы можете продолжать использовать то, что используете, добавив следующее в свой манифест в тегах приложения:

android:requestLegacyExternalStorage="true"

Возможно, вы захотите изменить minSDK на 19 и использовать getExternalFilesDir() чтобы получить путь, который не требует каких-либо разрешений.

0 голосов
/ 22 октября 2019

вам нужно запросить разрешение Manifest.permission.WRITE_EXTERNAL_STORAGE еще раз.

до 9.0, вы запрашиваете только Manifest.permission.READ_EXTERNAL_STORAGE, и вы получите также Manifest.permission.WRITE_EXTERNAL_STORAGE, но начните с 9.0, вы можете получитьтолько одно разрешение, которое вы запросили.

Прости мой плохой английский.

0 голосов
/ 17 октября 2019

Когда ваше приложение предназначено для Build.VERSION_CODES.Q, путь, возвращаемый этим методом, больше не доступен напрямую для приложений.

    val path = getExternalFilesDir(Environment.DIRECTORY_PICTURES.toString() + 
    File.separator + "Output Folder")
    val file = File(getExternalFilesDir(null), "filename.jpg")

Для получения более подробной информации посетите Документы

0 голосов
/ 17 октября 2019

может быть, это может помочь вам есть изменения в уровне Android 29 https://developer.android.com/about/versions/10/behavior-changes-10

...