In Android 10 kann kein Verzeichnis erstellt werden

8

Ich kann kein Verzeichnis in Android 10 erstellen. Es funktioniert auf Geräten bis Android Oreo.

Ich habe zwei Möglichkeiten zum Erstellen von Ordnern ausprobiert.

Verwenden von File.mkdir() :

   File f = new File(Environment.getExternalStorageDirectory().getAbsolutePath() + "/Pastebin");
                    if (!f.isFile()) {
                        if (!(f.isDirectory())) {
                               success =  f.mkdir();
                        }

Hier ist die Variable success immer falsch, was bedeutet, dass das Verzeichnis nicht erstellt wird.

Verwenden von Files.createDirectory() :

   File f = new File(Environment.getExternalStorageDirectory().getAbsolutePath() + "/Pastebin");
                    if (!f.isFile()) {
                        if (!(f.isDirectory())) {
                            if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
                                try {
                                    Files.createDirectory(Paths.get(f.getAbsolutePath()));
                                } catch (IOException e) {
                                    e.printStackTrace();
                                    Toast.makeText(getApplicationContext(), R.string.unable_to_download, Toast.LENGTH_LONG).show();
                                }
                            } else {
                                f.mkdir();
                            }
                        }

was diese Ausnahme verursacht:

pzy64.pastebinpro W/System.err: java.nio.file.AccessDeniedException: /storage/emulated/0/Pastebin
pzy64.pastebinpro W/System.err:     at sun.nio.fs.UnixFileSystemProvider.createDirectory(UnixFileSystemProvider.java:391)
pzy64.pastebinpro W/System.err:     at java.nio.file.Files.createDirectory(Files.java:674)

Ich habe die Laufzeitberechtigungen implementiert und

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

sind alle eingestellt.

pz64_
quelle

Antworten:

24

Wie wurde zum ersten Mal zurück März 2019 offenbart ist , Sie keinen Zugriff mehr standardmäßig beliebigen Stellen auf externen Speicher oder Wechselspeicher auf Android 10+. Dies schließt Environment.getExternalStorageDirectory()und andere Methoden ein Environment(z getExternalStoragePublicDirectory().

Für Android 10 können Sie android:requestLegacyExternalStorage="true"Ihrem <application>Element im Manifest hinzufügen . Dadurch werden Sie in das ältere Speichermodell aufgenommen, und Ihr vorhandener externer Speichercode funktioniert. Dies funktioniert jedoch nicht mit Android R und höher, sodass dies nur eine kurzfristige Lösung ist.

Sie haben folgende Möglichkeiten:

  • Verwenden Sie Methoden Context, getExternalFilesDir()um beispielsweise auf Verzeichnisse im externen Speicher zuzugreifen, in die Ihre App schreiben kann. Sie benötigen keine Berechtigungen, um diese Verzeichnisse unter Android 4.4+ zu verwenden. Die Daten, die Sie dort speichern, werden jedoch entfernt, wenn Ihre App deinstalliert wird.

  • Verwenden Sie das Storage Access Framework, z. B. ACTION_OPEN_DOCUMENTund ACTION_CREATE_DOCUMENT.

  • Wenn es sich bei Ihrem Inhalt um Medien handelt, können Sie MediaStoredie Medien an Standardmedienpositionen platzieren.

CommonsWare
quelle
1
Wollen Sie damit sagen, dass es unter Android Q keine Möglichkeit gibt, ein eigenes Verzeichnis zu erstellen?
Xihuny
1
@Xihuny: Sie können gerne Unterverzeichnisse getExternalFilesDir()und ähnliche Speicherorte erstellen, die von bereitgestellt werden Context. Sie können Unterverzeichnisse nicht direkt aus den Wurzeln des externen oder Wechseldatenspeichers mithilfe von Dateisystem-APIs erstellen.
CommonsWare
1
Ich möchte das nicht tun, da die Dateien entfernt werden, wenn der Benutzer die App deinstalliert.
Xihuny
1
@Xihuny: Verwenden Sie dann das Storage Access Framework und lassen Sie den Benutzer auswählen, wo auf dem Gerät des Benutzers Sie den Inhalt des Benutzers ablegen möchten.
CommonsWare
1
Ich habe es versucht, konnte aber kein eigenes Verzeichnis erstellen. Gibt es eine Möglichkeit, mit SAF ein eigenes benutzerdefiniertes Verzeichnis zu erstellen?
Xihuny
3

Für Android 10 können Sie hinzufügen

android:requestLegacyExternalStorage="true"

zu Ihrem Element im Manifest. Dadurch werden Sie in das Legacy-Speichermodell aufgenommen, und Ihr vorhandener externer Speichercode funktioniert. Dieser Fix funktioniert jedoch nicht unter Android R und höher, daher handelt es sich nur um einen kurzfristigen Fix.

Sujit Jamdade
quelle
1

Seit Q Beta 4 ist es möglich, diese Funktion zu deaktivieren, indem Sie:

Targeting von API 28 (oder niedriger) mithilfe des Manifestattributs requestLegacyExternalStorage:

<manifest ... >
  <!-- This attribute is "false" by default on apps targeting Android Q. -->
  <application android:requestLegacyExternalStorage="true" ... >
    ...
  </application>
</manifest>
Amit_android
quelle
-1

Das funktioniert bei mir und ich denke, es funktioniert unter Android 10>

            ContentResolver resolver = getContentResolver();
            ContentValues contentValues = new ContentValues();
            contentValues.put(MediaStore.MediaColumns.RELATIVE_PATH, Environment.DIRECTORY_PICTURES + "/Folder Example");
            String path = String.valueOf(resolver.insert(MediaStore.Images.Media.EXTERNAL_CONTENT_URI, contentValues));
            File folder = new File(path);
            boolean isCreada = folder.exists();
            if(!isCreada) {
                folder.mkdirs();
            }
JP711
quelle
Sie fragen a ab File, daher müssen Sie hinzufügen, android:requestLegacyExternalStorage="true"wenn Sie auf Android 10> abzielen. In diesem Fall können Sie genauso gut weiter verwenden getExternalStoragePublicDirectory(Environment.DIRECTORY_PICTURES).
HB.
getExternalStoragePublicDirectory ist in API-Level 29
JP711 vor
Ja und? Wie in der Dokumentation angegeben When an app targets Build.VERSION_CODES.Q, the path returned from this method is no longer directly accessible, können Sie es android:requestLegacyExternalStorage="true"in Ihrem Manifest weiterhin verwenden.
HB.
"Ja und?" und, wie die Dokumentation besagt, Apps can continue to access content stored on shared/external storage by migrating to alternatives such as Context#getExternalFilesDir(String), MediaStore, or Intent#ACTION_OPEN_DOCUMENTbin ich neu in diesem Bereich, aber dann wäre meine Frage, ob mein Vorschlag falsch ist oder warum die negative Abstimmung? Ich weiß nicht genau, wie das funktioniert. Ist es besser, weiterzumachen getExternalStoragePublicDirectory?
JP711 vor
1
Sie müssen keinen Ordner erstellen. Wenn Sie in Uriden Ordner schreiben, wird dieser automatisch erstellt.
HB.