Android-Speicher – Anwendungsfälle und Best Practices

Damit Nutzer mehr Kontrolle über ihre Dateien haben und um die Anzahl der Dateien zu begrenzen, wurde mit Android 10 ein neues Speicherparadigma für Apps eingeführt, das als begrenzter Speicher bezeichnet wird. Der begrenzte Speicher ändert die Art und Weise, wie Apps Dateien im externen Speicher eines Geräts speichern und darauf zugreifen. Damit Sie Ihre App so migrieren können, dass sie den begrenzten Speicher unterstützt, sollten Sie die Best Practices für gängige Anwendungsfälle bei der Speichernutzung befolgen, die in diesem Leitfaden beschrieben werden. Die Anwendungsfälle sind in zwei Kategorien unterteilt: Umgang mit Mediendateien und Umgang mit Nicht-Mediendateien.

In vielen Fällen erstellt Ihre App Dateien, auf die andere Apps nicht zugreifen müssen oder nicht zugreifen sollten. Das System bietet appspezifische Speicherorte zum Verwalten solcher Dateien.

Weitere Informationen zum Speichern von Dateien und zum Zugriff darauf unter Android finden Sie in den Schulungsleitfäden zum Speicher.

Mediendateien verarbeiten

In diesem Abschnitt werden einige der häufigsten Anwendungsfälle für die Verarbeitung von Mediendateien (Video-, Bild- und Audiodateien) beschrieben und der allgemeine Ansatz erläutert, den Ihre App verwenden kann. In der folgenden Tabelle sind die einzelnen Anwendungsfälle zusammengefasst. Außerdem finden Sie Links zu den Abschnitten mit weiteren Details.

Anwendungsfall Zusammenfassung
Alle Bild- oder Videodateien anzeigen Verwenden Sie für alle Android-Versionen denselben Ansatz.
Bilder oder Videos aus einem bestimmten Ordner anzeigen Verwenden Sie für alle Android-Versionen denselben Ansatz.
Auf Standortinformationen aus Fotos zugreifen Verwenden Sie einen Ansatz, wenn Ihre App den begrenzten Speicher verwendet. Verwenden Sie einen anderen Ansatz, wenn Ihre App den begrenzten Speicher nicht verwendet.
Speicherort für neue Downloads festlegen Verwenden Sie einen Ansatz, wenn Ihre App den begrenzten Speicher verwendet. Verwenden Sie einen anderen Ansatz, wenn Ihre App den begrenzten Speicher nicht verwendet.
Mediendateien von Nutzern auf ein Gerät exportieren Verwenden Sie für alle Android-Versionen denselben Ansatz.
Mehrere Mediendateien in einem einzigen Vorgang ändern oder löschen Verwenden Sie einen Ansatz für Android 11. Deaktiviere für Android 10 den begrenzten Speicher und verwende stattdessen den Ansatz für Android 9 und niedriger.
Einzelnes vorhandenes Image importieren Verwenden Sie für alle Android-Versionen denselben Ansatz.
Einzelnes Bild aufnehmen Verwenden Sie für alle Android-Versionen denselben Ansatz.
Mediendateien mit anderen Apps teilen Verwenden Sie für alle Android-Versionen denselben Ansatz.
Mediendateien mit einer bestimmten App teilen Verwenden Sie für alle Android-Versionen denselben Ansatz.
Auf Dateien über Code oder Bibliotheken zugreifen, die direkte Dateipfade verwenden Verwenden Sie einen Ansatz für Android 11. Deaktiviere für Android 10 den begrenzten Speicher und verwende stattdessen den Ansatz für Android 9 und niedriger.

Bild- oder Videodateien aus mehreren Ordnern anzeigen

Fragen Sie eine Mediensammlung mit der query() API ab. Wenn Sie die Mediendateien filtern oder sortieren möchten, passen Sie die Parameter projection, selection, selectionArgs und sortOrder an.

Bilder oder Videos aus einem bestimmten Ordner anzeigen

Gehen Sie so vor:

  1. Folgen Sie den Best Practices unter App-Berechtigungen anfordern und fordern Sie die Berechtigung READ_EXTERNAL_STORAGE an.
  2. Mediendateien werden anhand des Werts von MediaColumns.DATA abgerufen, der den absoluten Dateisystempfad zur Mediendatei auf dem Laufwerk enthält.

Hinweis:Wenn Sie auf eine vorhandene Mediendatei zugreifen, können Sie den Wert der Spalte DATA in Ihrer Logik verwenden. Das liegt daran, dass dieser Wert einen gültigen Dateipfad hat. Gehen Sie jedoch nicht davon aus, dass die Datei immer verfügbar ist. Seien Sie darauf vorbereitet, alle dateibasierten E/A-Fehler zu beheben, die auftreten können.

Wenn Sie eine Mediendatei erstellen oder aktualisieren möchten, verwenden Sie die Spalte DATA nicht. Verwenden Sie stattdessen die Spalten DISPLAY_NAME und RELATIVE_PATH.

Auf Standortinformationen aus Fotos zugreifen

Wenn deine App den begrenzten Speicher verwendet, folge der Anleitung im Abschnitt Standortinformationen in Fotos des Leitfadens zum Medienspeicher.

Speicherort für neue Downloads festlegen

Wenn deine App den begrenzten Speicher verwendet, solltest du darauf achten, wo du heruntergeladene Mediendateien speicherst.

Wenn andere Apps Zugriff auf Dateien benötigen, können Sie klar definierte Mediensammlungen für Downloads oder Dokumentsammlungen verwenden.

Unter Android 11 und höher können andere Apps nicht auf die Dateien in Ihrem externen app-spezifischen Verzeichnis zugreifen, auch wenn Sie DownloadManager verwenden, um diese Dateien abzurufen.

Mediendateien von Nutzern auf ein Gerät exportieren

Legen Sie einen geeigneten Standardspeicherort für die Mediendateien der Nutzer fest:

Mehrere Mediendateien in einem einzigen Vorgang ändern oder löschen

Integrieren Sie Logik basierend auf den Android-Versionen, auf denen Ihre App ausgeführt wird.

Gerät mit Android 11

Gehen Sie so vor:

  1. Erstelle mit MediaStore.createWriteRequest() oder MediaStore.createTrashRequest() einen Pending Intent für die Schreib- oder Löschanfrage deiner App und fordere den Nutzer dann auf, die Berechtigung zum Bearbeiten einer Reihe von Dateien zu erteilen, indem du diesen Intent aufrufst.
  2. Bewerten Sie die Antwort des Nutzers:

    • Wenn die Berechtigung erteilt wurde, fahren Sie mit dem Änderungs- oder Löschvorgang fort.
    • Wenn die Berechtigung nicht gewährt wurde, erkläre dem Nutzer, warum die Funktion in deiner App die Berechtigung benötigt.

Weitere Informationen zum Verwalten von Gruppen von Mediendateien mit diesen Methoden, die unter Android 11 und höher verfügbar sind.

Android 10

Wenn Ihre App auf Android 10 (API-Level 29) ausgerichtet ist, deaktivieren Sie den begrenzten Speicher und verwenden Sie weiterhin den Ansatz für Android 9 und niedriger, um diesen Vorgang auszuführen.

Android 9 oder niedriger

Gehen Sie so vor:

  1. Folgen Sie den Best Practices unter App-Berechtigungen anfordern und fordern Sie die Berechtigung WRITE_EXTERNAL_STORAGE an.
  2. Verwenden Sie die MediaStore API, um die Mediendateien zu ändern oder zu löschen.

Einzelnes, bereits vorhandenes Bild importieren

Wenn Sie ein einzelnes, bereits vorhandenes Bild importieren möchten, z. B. als Profilbild eines Nutzers, kann Ihre App entweder die eigene Benutzeroberfläche oder die Systemauswahl verwenden.

Eigene Benutzeroberfläche präsentieren

Gehen Sie so vor:

  1. Folgen Sie den Best Practices unter App-Berechtigungen anfordern und fordern Sie die Berechtigung READ_EXTERNAL_STORAGE an.
  2. Verwenden Sie die query() API, um eine Mediensammlung abzufragen.
  3. Zeigen Sie die Ergebnisse in der benutzerdefinierten Benutzeroberfläche Ihrer App an.

Systemauswahl verwenden

Verwenden Sie den Intent ACTION_GET_CONTENT, bei dem der Nutzer aufgefordert wird, ein Bild zum Importieren auszuwählen.

Wenn du die Bildtypen filtern möchtest, die dem Nutzer in der Systemauswahl angezeigt werden, kannst du setType() oder EXTRA_MIME_TYPES verwenden.

Einzelnes Bild aufnehmen

Wenn du ein einzelnes Bild für deine App aufnehmen möchtest (z. B. als Foto für das Profil eines Nutzers), verwende den Intent ACTION_IMAGE_CAPTURE, um den Nutzer aufzufordern, ein Foto mit der Kamera des Geräts aufzunehmen. Das System speichert das aufgenommene Foto in der Tabelle MediaStore.Images.

Mediendateien mit anderen Apps teilen

Verwenden Sie die Methode insert(), um Einträge direkt in den MediaStore einzufügen. Weitere Informationen finden Sie im Abschnitt Element hinzufügen des Leitfadens zum Medienspeicher.

Mediendateien mit einer bestimmten App teilen

Verwenden Sie die Android-Komponente FileProvider, wie im Leitfaden Dateifreigabe einrichten beschrieben.

Zugriff auf Dateien über Code oder Bibliotheken, die direkte Dateipfade verwenden

Integrieren Sie Logik basierend auf den Android-Versionen, auf denen Ihre App ausgeführt wird.

Gerät mit Android 11

Gehen Sie so vor:

  1. Folgen Sie den Best Practices unter App-Berechtigungen anfordern und fordern Sie die Berechtigung READ_EXTERNAL_STORAGE an.
  2. Greifen Sie über direkte Dateipfade auf die Dateien zu.

Weitere Informationen finden Sie im Abschnitt zum Öffnen von Mediendateien über direkte Dateipfade.

Android 10

Wenn Ihre App auf Android 10 (API-Level 29) ausgerichtet ist, deaktivieren Sie den begrenzten Speicher und verwenden Sie weiterhin den Ansatz für Android 9 und niedriger, um diesen Vorgang auszuführen.

Android 9 oder niedriger

Gehen Sie so vor:

  1. Folgen Sie den Best Practices unter App-Berechtigungen anfordern und fordern Sie die Berechtigung WRITE_EXTERNAL_STORAGE an.
  2. Greifen Sie über direkte Dateipfade auf die Dateien zu.

Umgang mit Nicht-Mediendateien

In diesem Abschnitt werden einige der häufigsten Anwendungsfälle für den Umgang mit Nicht-Mediendateien beschrieben und der allgemeine Ansatz erläutert, den Ihre App verwenden kann. In der folgenden Tabelle sind die einzelnen Anwendungsfälle zusammengefasst. Außerdem finden Sie Links zu den Abschnitten mit weiteren Details.

Anwendungsfall Zusammenfassung
Dokumentdatei öffnen Verwenden Sie für alle Android-Versionen denselben Ansatz.
In Dateien auf sekundären Speicher-Volumes schreiben Verwenden Sie einen Ansatz für Android 11. Verwende für frühere Android-Versionen einen anderen Ansatz.
Vorhandene Dateien von einem Legacy-Speicherort migrieren Migriere deine Dateien nach Möglichkeit in den begrenzten Speicher. Deaktivieren Sie den begrenzten Speicher für Android 10, wenn nötig.
Inhalte mit anderen Apps teilen Verwenden Sie für alle Android-Versionen denselben Ansatz.
Nicht-Mediendateien im Cache speichern Verwenden Sie für alle Android-Versionen denselben Ansatz.
Nicht-Mediendateien auf ein Gerät exportieren Verwenden Sie einen Ansatz, wenn Ihre App den begrenzten Speicher verwendet. Verwenden Sie einen anderen Ansatz, wenn Ihre App den begrenzten Speicher nicht verwendet.

Dokumentdatei öffnen

Verwenden Sie den Intent ACTION_OPEN_DOCUMENT, um den Nutzer aufzufordern, eine Datei auszuwählen, die mit der Systemauswahl geöffnet werden soll. Wenn Sie die Dateitypen filtern möchten, die dem Nutzer in der Systemauswahl angezeigt werden, können Sie setType() oder EXTRA_MIME_TYPES verwenden.

Mit dem folgenden Code können Sie beispielsweise alle PDF-, ODT- und TXT-Dateien finden:

Kotlin

startActivityForResult(
        Intent(Intent.ACTION_OPEN_DOCUMENT).apply {
            addCategory(Intent.CATEGORY_OPENABLE)
            type = "*/*"
            putExtra(Intent.EXTRA_MIME_TYPES, arrayOf(
                    "application/pdf", // .pdf
                    "application/vnd.oasis.opendocument.text", // .odt
                    "text/plain" // .txt
            ))
        },
        REQUEST_CODE
      )

Java

Intent intent = new Intent(Intent.ACTION_OPEN_DOCUMENT);
        intent.addCategory(Intent.CATEGORY_OPENABLE);
        intent.setType("*/*");
        intent.putExtra(Intent.EXTRA_MIME_TYPES, new String[] {
                "application/pdf", // .pdf
                "application/vnd.oasis.opendocument.text", // .odt
                "text/plain" // .txt
        });
        startActivityForResult(intent, REQUEST_CODE);

In Dateien auf sekundären Speicher-Volumes schreiben

Zu den sekundären Speichervolumes gehören SD-Karten. Mit der Klasse StorageVolume können Sie auf Informationen zu einem bestimmten Speicher-Volume zugreifen.

Integrieren Sie Logik basierend auf der Android-Version, auf der Ihre App ausgeführt wird.

Android 11

Gehen Sie so vor:

  1. Verwenden Sie das Modell Begrenzter Speicher.
  2. auf Android 10 (API-Level 29) oder niedriger ausgerichtet sein.
  3. Deklarieren Sie die Berechtigung WRITE_EXTERNAL_STORAGE.
  4. Führen Sie einen der folgenden Zugriffstypen aus:
    • Dateizugriff über die MediaStore API.
    • Direkter Dateipfadzugriff über APIs wie File oder fopen().

Ausführung auf älteren Versionen

Verwenden Sie das Storage Access Framework, mit dem Nutzer den Speicherort auf einem sekundären Speicher-Volume auswählen können, auf dem Ihre App die Datei schreiben kann.

Vorhandene Dateien von einem alten Speicherort migrieren

Ein Verzeichnis gilt als Legacy-Speicherort, wenn es sich nicht um ein App-spezifisches Verzeichnis oder ein öffentliches freigegebenes Verzeichnis handelt. Wenn Ihre App Dateien an einem alten Speicherort erstellt oder verwendet, empfehlen wir, die Dateien Ihrer App an Speicherorte zu migrieren, auf die mit begrenztem Speicher zugegriffen werden kann, und alle erforderlichen App-Änderungen vorzunehmen, um mit Dateien im begrenzten Speicher zu arbeiten.

Zugriff auf den alten Speicherort für die Datenmigration beibehalten

Ihre App muss weiterhin Zugriff auf den alten Speicherort haben, damit alle App-Dateien an Speicherorte migriert werden können, auf die mit begrenztem Speicher zugegriffen werden kann. Welchen Ansatz Sie verwenden sollten, hängt vom Ziel-API-Level Ihrer App ab.

Wenn Ihre App auf Android 11 ausgerichtet ist
  1. Setze das Flag preserveLegacyExternalStorage auf true, um das bisherige Speichermodell beizubehalten, damit deine App die Daten eines Nutzers migrieren kann, wenn er auf die neue Version deiner App aktualisiert, die auf Android 11 ausgerichtet ist.

  2. Deaktivieren Sie weiterhin den begrenzten Speicher, damit Ihre App auf Android 10-Geräten weiterhin auf Ihre Dateien im alten Speicherort zugreifen kann.

Wenn Ihre App auf Android 10 ausgerichtet ist

Deaktiviere den begrenzten Speicher, um das Verhalten deiner App in verschiedenen Android-Versionen leichter beizubehalten.

App-Daten migrieren

Wenn Ihre Anwendung für die Migration bereit ist, gehen Sie so vor:

  1. Android 10 oder niedriger als Zielversion verwenden
  2. Deaktiviere den begrenzten Speicher, damit deine App Zugriff auf die Dateien hat, die du migrieren möchtest.
  3. Stellen Sie Code bereit, der die File API verwendet, um Dateien von ihrem aktuellen Speicherort unter /sdcard/ an einen Speicherort zu verschieben, auf den mit begrenztem Speicher zugegriffen werden kann:

    1. Verschieben Sie alle privaten App-Dateien in das Verzeichnis, das von der Methode getExternalFilesDir() zurückgegeben wird.
    2. Verschiebe alle freigegebenen Nicht-Mediendateien in ein app-spezifisches Unterverzeichnis des Verzeichnisses Downloads/.
  4. Entfernen Sie die Legacy-Speicherverzeichnisse Ihrer App aus dem Verzeichnis /sdcard/.

Nachdem Nutzer die neue Version deiner App installiert haben, schließen sie die Datenmigration auf ihren Geräten ab. Sie können den Migrationsprozess für Ihre Nutzerbasis überwachen, indem Sie ein Analyseereignis erstellen.

Nachdem die Nutzer ihre Daten migriert haben, veröffentliche ein weiteres Update für deine App, das auf Android 11 ausgerichtet ist.

Inhalte mit anderen Apps teilen

Wenn Sie die Dateien Ihrer App mit einer einzelnen anderen App teilen möchten, verwenden Sie einen FileProvider. Für Apps, die alle Dateien untereinander freigeben müssen, empfehlen wir, für jede App einen Contentanbieter zu verwenden und dann die Daten zu synchronisieren, wenn Apps zur Sammlung hinzugefügt werden.

Nicht-Mediendateien im Cache speichern

Welche Vorgehensweise Sie verwenden sollten, hängt von der Art der Dateien ab, die Sie im Cache speichern müssen.

Dateien, die keine Mediendateien sind, auf ein Gerät exportieren

Definieren Sie einen geeigneten Standardspeicherort für Nicht-Mediendateien. Nutzern erlauben, Dateien aus anwendungsspezifischen Verzeichnissen an einen allgemein zugänglichen Speicherort zu exportieren. Verwende die Downloads oder Dokumentensammlungen von MediaStore, um Nicht-Mediendateien auf das Gerät zu exportieren.

App-spezifische Dateien verarbeiten

Wenn Ihre App Dateien erstellt, auf die andere Apps nicht zugreifen müssen oder sollen, können Sie diese Dateien in appspezifischen Speicherorten speichern.

Interne Speicherverzeichnisse

Das System verhindert, dass andere Apps auf diese Speicherorte zugreifen. Unter Android 10 (API-Level 29) und höher sind diese Speicherorte verschlüsselt. Diese Speicherorte eignen sich gut zum Speichern sensibler Daten, auf die nur Ihre App zugreifen kann.

Externe Speicherverzeichnisse

Wenn der interne Speicher nicht genügend Platz für App-spezifische Dateien bietet, solltest du stattdessen externen Speicher verwenden. Eine andere App kann zwar auf diese Verzeichnisse zugreifen, wenn sie die entsprechenden Berechtigungen hat, die in diesen Verzeichnissen gespeicherten Dateien sind jedoch nur für die Verwendung durch Ihre App vorgesehen.

Unter Android 4.4 (API-Level 19) oder höher muss Ihre App keine speicherbezogenen Berechtigungen anfordern, um auf App-spezifische Verzeichnisse im externen Speicher zuzugreifen.

Wenn der Nutzer Ihre App deinstalliert, werden die im App-spezifischen Speicher gespeicherten Dateien entfernt. Sie sollten diesen Speicher daher nicht verwenden, um Daten zu speichern, die der Nutzer unabhängig von Ihrer App behalten möchte.

Begrenzten Speicher vorübergehend deaktivieren

Bevor deine App vollständig mit dem begrenzten Speicher kompatibel ist, kannst du die Funktion vorübergehend deaktivieren, sowohl in deinen Tests als auch in deiner Produktions-App.

In Tests deaktivieren

Unter Android 10 (API-Level 29) und höher werden die Tests Ihrer App standardmäßig in einer Speicher-Sandbox ausgeführt. Diese Sandbox verhindert, dass Ihre App auf Dateien außerhalb des App-spezifischen Verzeichnisses und öffentlich freigegebener Verzeichnisse zugreift.

Wenn ein Test Dateien für den Host ausgibt, z. B. Screenshots, Debugging-Daten, Abdeckungsdaten oder Leistungsmesswerte, können Sie diese Dateien in globale Verzeichnisse schreiben. Fügen Sie dazu dem relevanten Harness, der am instrument aufruft, das folgende Flag hinzu:

-e no-isolated-storage 1

Dieses Flag wirkt sich auf das gesamte Verhalten des instrumentierten Testlaufs und auf den gesamten aufgerufenen Testcode aus. Wenn Sie dieses Flag verwenden, können Sie die Kompatibilität Ihrer App mit dem begrenzten Speicher nicht prüfen. Für die Testausgabe ist es besser, in einen App-spezifischen Speicher zu schreiben, der von der Shell gelesen werden kann. Anschließend können Sie dieses app-spezifische Verzeichnis abrufen. Rufen Sie getExternalMediaDirs() auf, um zu ermitteln, aus welchem Verzeichnis die Daten abgerufen werden sollen.

Deaktivierung in Ihrer Produktions-App

Wenn Ihre App auf Android 10 (API-Level 29) oder niedriger ausgerichtet ist, können Sie den begrenzten Speicher in Ihrer Produktions-App vorübergehend deaktivieren. Wenn Sie Android 10 als Ziel verwenden, müssen Sie jedoch den Wert von requestLegacyExternalStorage in der Manifestdatei Ihrer App auf true setzen:

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

Wenn du testen möchtest, wie sich eine App für Android 10 oder niedriger verhält, wenn sie den begrenzten Speicher verwendet, kannst du das Verhalten aktivieren, indem du den Wert von requestLegacyExternalStorage auf false setzt. Wenn Sie auf einem Gerät mit Android 11 testen, können Sie auch App-Kompatibilitäts-Flags verwenden, um das Verhalten Ihrer App mit oder ohne begrenzten Speicher zu testen.

Zusätzliche Ressourcen

Weitere Informationen zum Android-Speicher finden Sie in den folgenden Materialien:

Blogposts