Android APIv29 FileNotFoundException EACCES (Berechtigung verweigert)

8

Ich kann beim Erstellen für targetSdkVersion v29 nicht auf den Speicher zugreifen.

Hier ist meine Gradle-Konfiguration:

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

HINWEIS: Die WRITE_EXTERNAL_STORAGEBerechtigung wird erteilt, und dasselbe Setup funktioniert beim Erstellen für targetSdkVersion 28.

Hier ist meine Implementierung:

        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 
        }

und hier ist die Ausnahme:

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)

Hoffe jemand hat eine Antwort, was vermisse ich hier?

Aktualisieren:

Hier kommt woher baseFolder. Beachten Sie, dass dies getExternalStorageDirectoryeine veraltete Methode ist.

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

Vielen Dank

Dinu
quelle
Versuchen Sie, diese Bibliothek für premissions github.com/googlesamples/easypermissions
Ruben Meiring
Wie bereits erwähnt, werden die erforderlichen Berechtigungen zum Schreiben von externem Speicher erteilt, und das gleiche Setup funktioniert beim Erstellen mit targetSdkVersion 28. Dies ist kein Berechtigungsproblem!
Dinu
Seine nebenstehende Premission kann laut Fehler keine Premsiion erhalten, um auf die Datei / storage / emulated / 0 / Chirp Auto Tester / 2019_10_17 10: 44: 43.raw: open failed: EACCES (Berechtigung verweigert) zuzugreifen , wenn Android 10 verwendet wird Scoped Storage
Ruben Meiring
Wie erklären Sie, dass es beim Bauen für targetSdkVersion 28dann funktioniert ? Laut Fehler handelt es sich um ein Problem mit Berechtigungen, jedoch nicht, weil die Berechtigungen nicht erteilt wurden.
Dinu
2
Sie haben keinen Dateisystemzugriff auf beliebige Speicherorte im externen und Wechselspeicher. Die Wechselspeicherbegrenzung wurde in Android 4.4 hinzugefügt. Die externe Speicherbeschränkung wurde in Android 10 hinzugefügt.
CommonsWare

Antworten:

14

Ab Android 11 wird die Speicherberechtigung widerrufen, und Entwickler müssten alternative Möglichkeiten für den Zugriff auf den benötigten Speicher über SAF oder Media Store in Betracht ziehen . Vorerst können Sie das, was Sie verwenden, weiter verwenden, indem Sie in Ihrem Manifest in den Anwendungs-Tags Folgendes hinzufügen:

android:requestLegacyExternalStorage="true"

Möglicherweise möchten Sie Ihr minSDK auf 19 ändern und getExternalFilesDir()einen Pfad abrufen, für den keine Berechtigungen erforderlich sind.

Nikos Hidalgo
quelle
Funktioniert immer noch nicht, schaut aber definitiv in die richtige Richtung, jetzt bekomme ich ENOENT (No such file or directory)jedoch das Verzeichnis definitiv. getExternalFilesDir()klingt nach der richtigen Entscheidung, um das Problem zu beheben.
Dinu
1
Nur ein kurzes Update, das ich vorerst verwendet habe getExternalFilesDir().
Dinu
2

Wenn Ihre App auf Build.VERSION_CODES.Q abzielt, ist der von dieser Methode zurückgegebene Pfad für Apps nicht mehr direkt zugänglich.

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

Weitere Informationen finden Sie unter Docs

Praveen
quelle
-1

Sie benötigen erneut die Anforderungsberechtigung Manifest.permission.WRITE_EXTERNAL_STORAGE.

Vor 9.0 fordern Sie nur Manifest.permission.READ_EXTERNAL_STORAGE an und Sie erhalten auch Manifest.permission.WRITE_EXTERNAL_STORAGE. Ab 9.0 können Sie jedoch nur eine Berechtigung erhalten, die Sie angefordert haben.

Vergib mir mein schlechtes Englisch.

Gerry_Liang
quelle
Dies ist kein Problem mit der Anforderung von Berechtigungen. Ich habe dies einige Male erwähnt. Sowohl die Berechtigungen WRITE als auch READ EXTERNAL_STORAGE werden erteilt. Weitere Informationen dazu, warum Sie auch dann nicht auf externen Speicher zugreifen können, wenn Berechtigungen erteilt wurden, finden Sie in der Antwort von Nikos. Und mach dir keine Sorgen um dein Englisch, es ist großartig.
Dinu
/ ** * public 相册 权限 , 去 打开 相册 * / public void galleryPicture () {if (ContextCompat.checkSelfPermission (mContext, Manifest.permission.READ_EXTERNAL_STORAGE)! = PackageManager.PERMISSION_GRANTED) {ActivityCompat.requestPermissions {Manifest.permission.READ_EXTERNAL_STORAGE, Manifest.permission.WRITE_EXTERNAL_STORAGE}, STORAGE_PERMISSIONS_REQUEST_CODE); } else {openPic (mContext, CODE_GALLERY_REQUEST); }}
Gerry_Liang