Mit Android 10 wurde ein neues Speichermodell für Anwendungen namens Bereichsspeicher eingeführt, um Nutzern mehr Kontrolle über ihre Dateien zu geben und das Durcheinander zu reduzieren. Begrenzter Speicher ändert die Art und Weise, wie Apps Dateien im externen Speicher eines Geräts speichern und darauf zugreifen. Folgen Sie den Best Practices für gängige Speicheranwendungsfälle, die in diesem Leitfaden beschrieben werden, um die Migration Ihrer Anwendung zur Unterstützung von beschränktem Speicher zu erleichtern. Die Anwendungsfälle sind in zwei Kategorien unterteilt: Mediendateien verarbeiten und Nicht-Mediendateien verarbeiten.
Weitere Informationen zum Speichern und Abrufen von Dateien unter Android findest du in den Trainingsleitfäden für 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 Anwendung verwenden kann. In der folgenden Tabelle werden die einzelnen Anwendungsfälle zusammengefasst und Links zu den einzelnen Abschnitten mit weiteren Details angegeben.
Anwendungsfall | Zusammenfassung |
---|---|
Alle Bild- oder Videodateien anzeigen | Verwende für alle Android-Versionen denselben Ansatz. |
Bilder oder Videos aus einem bestimmten Ordner anzeigen | Verwende für alle Android-Versionen denselben Ansatz. |
Auf Standortinformationen aus Fotos zugreifen | Verwenden Sie einen Ansatz, wenn Ihre Anwendung beschränkten Speicher verwendet. Verwenden Sie einen anderen Ansatz, wenn Ihre Anwendung den beschränkten Speicher deaktiviert. |
Speicherort für neue Downloads festlegen | Verwenden Sie einen Ansatz, wenn Ihre Anwendung beschränkten Speicher verwendet. Verwenden Sie einen anderen Ansatz, wenn Ihre Anwendung den beschränkten Speicher deaktiviert. |
Mediendateien von Nutzern auf ein Gerät exportieren | Verwende für alle Android-Versionen denselben Ansatz. |
Mehrere Mediendateien in einem einzigen Vorgang ändern oder löschen | Verwende einen Ansatz für Android 11. Bei Android 10 solltest du den beschränkten Speicher deaktivieren und stattdessen die Methode für Android 9 und niedriger verwenden. |
Vorhandenes einzelnes Image importieren | Verwende für alle Android-Versionen denselben Ansatz. |
Ein einzelnes Bild aufnehmen | Verwende für alle Android-Versionen denselben Ansatz. |
Mediendateien mit anderen Apps teilen | Verwende für alle Android-Versionen denselben Ansatz. |
Mediendateien für eine bestimmte App freigeben | Verwende für alle Android-Versionen denselben Ansatz. |
Auf Dateien über Code oder Bibliotheken zugreifen, die direkte Dateipfade verwenden | Verwende einen Ansatz für Android 11. Bei Android 10 solltest du den beschränkten Speicher deaktivieren und stattdessen die Methode für Android 9 und niedriger verwenden. |
Bild- oder Videodateien aus mehreren Ordnern anzeigen
Verwenden Sie die query()
API zum Abfragen einer Mediensammlung. Passen Sie die Parameter projection
, selection
, selectionArgs
und sortOrder
an, um die Mediendateien zu filtern oder zu sortieren.
Bilder oder Videos aus einem bestimmten Ordner anzeigen
Verwenden Sie diesen Ansatz:
- Fordern Sie gemäß den Best Practices unter App-Berechtigungen anfordern die Berechtigung
READ_EXTERNAL_STORAGE
an. - Rufen Sie Mediendateien anhand des Werts von
MediaColumns.DATA
ab, der den absoluten Dateisystempfad zum Medienelement 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 auf den Umgang mit möglichen dateibasierten E/A-Fehlern vorbereitet.
Verwenden Sie zum Erstellen oder Aktualisieren einer Mediendatei jedoch nicht die Spalte DATA
. Verwende stattdessen die Spalten DISPLAY_NAME
und RELATIVE_PATH
.
Auf Standortinformationen aus Fotos zugreifen
Wenn Ihre Anwendung beschränkten Speicher verwendet, führen Sie die Schritte im Abschnitt Standortinformationen in Fotos des Leitfadens zum Medienspeicher aus.
Speicherort für neue Downloads festlegen
Wenn Ihre Anwendung begrenzten Speicher verwendet, achten Sie auf den Speicherort, an dem Sie die heruntergeladenen Mediendateien speichern.
Wenn andere Apps Zugriff auf Dateien benötigen, sollten Sie klar definierte Mediensammlungen für Downloads oder Dokumentsammlungen verwenden.
Unter Android 11 und höher sind die Dateien in Ihrem externen app-spezifischen Verzeichnis nicht für andere Apps zugänglich, auch wenn Sie diese Dateien mit DownloadManager
abrufen.
Nutzermediendateien auf ein Gerät exportieren
Legen Sie einen geeigneten Standardspeicherort für die Mediendateien von Nutzern fest:
- Nutzern erlauben, über app-specific-storage oder freigegebenen Speicher auszuwählen, ob ihre Mediendateien für andere Apps lesbar sind.
- Nutzern erlauben, Dateien aus anwendungsspezifischen Verzeichnissen an einen allgemeineren Ort zu exportieren Verwenden Sie die Bilder-, Video- und Audiosammlungen von MediaStore, um Mediendateien in die Galerie des Geräts zu exportieren.
Mehrere Mediendateien in einem einzigen Vorgang ändern oder löschen
Füge Logik ein, die auf den Android-Versionen deiner App basiert.
Unter Android 11
Verwenden Sie diesen Ansatz:
- Erstellen Sie mit
MediaStore.createWriteRequest()
oderMediaStore.createTrashRequest()
einen ausstehenden Intent für die Schreib- oder Löschanfrage Ihrer App und fordern Sie dann den Nutzer auf, um die Berechtigung zum Bearbeiten einer Gruppe von Dateien zu erhalten, indem Sie den entsprechenden Intent aufrufen. Bewerten Sie die Antwort der Nutzenden:
- Wenn die Berechtigung erteilt wurde, fahren Sie mit dem Ändern oder Löschen fort.
- Wenn die Berechtigung nicht erteilt wurde, erklären Sie dem Nutzer, warum die Berechtigung für die Funktion in Ihrer App erforderlich ist.
Weitere Informationen zum Verwalten von Gruppen von Mediendateien mit diesen Methoden, die unter Android 11 und höher verfügbar sind
Mit Android 10
Wenn Ihre App auf Android 10 (API-Level 29) ausgerichtet ist, deaktivieren Sie den begrenzten Speicher und verwenden Sie für diesen Vorgang weiterhin den Ansatz für Android 9 und niedriger.
Wenn Sie Android 9 oder niedriger verwenden
Verwenden Sie diesen Ansatz:
- Fordern Sie gemäß den Best Practices unter App-Berechtigungen anfordern die Berechtigung
WRITE_EXTERNAL_STORAGE
an. - Verwenden Sie die
MediaStore
API, um die Mediendateien zu ändern oder zu löschen.
Einzelnes Image importieren, das bereits vorhanden ist
Wenn Sie ein einzelnes Bild importieren möchten, das bereits vorhanden ist (z. B. um es als Foto für ein Nutzerprofil zu verwenden), kann Ihre Anwendung entweder ihre eigene UI für den Vorgang oder die Systemauswahl verwenden.
Ihre eigene Benutzeroberfläche präsentieren
Verwenden Sie diesen Ansatz:
- Fordern Sie gemäß den Best Practices unter App-Berechtigungen anfordern die Berechtigung
READ_EXTERNAL_STORAGE
an. - Verwenden Sie die
query()
API, um eine Mediensammlung abzufragen. - Lassen Sie die Ergebnisse in der benutzerdefinierten UI Ihrer App anzeigen.
Systemauswahl verwenden
Verwenden Sie den Intent ACTION_GET_CONTENT
, bei dem der Nutzer aufgefordert wird, ein Bild für den Import auszuwählen.
Wenn Sie die Bildtypen filtern möchten, die dem Nutzer in der Systemauswahl zur Auswahl angezeigt werden, können Sie setType()
oder EXTRA_MIME_TYPES
verwenden.
Einzelnes Bild aufnehmen
Wenn du ein einzelnes Bild erfassen möchtest, das in deiner App verwendet werden soll (z. B. als Foto für ein Nutzerprofil), verwende den ACTION_IMAGE_CAPTURE
-Intent, um den Nutzer aufzufordern, ein Foto mit der Kamera des Geräts aufzunehmen. Das aufgenommene Foto wird in der Tabelle MediaStore.Images
gespeichert.
Mediendateien mit anderen Apps teilen
Verwenden Sie die Methode insert()
, um Einträge direkt im MediaStore hinzuzufügen. Weitere Informationen finden Sie im Leitfaden zum Medienspeicher im Abschnitt Element hinzufügen.
Mediendateien mit einer bestimmten App teilen
Verwenden Sie die Android-Komponente FileProvider
wie unter Dateifreigabe einrichten beschrieben.
Auf Dateien über Code oder Bibliotheken zugreifen, die direkte Dateipfade verwenden
Füge Logik ein, die auf den Android-Versionen deiner App basiert.
Unter Android 11
Verwenden Sie diesen Ansatz:
- Fordern Sie gemäß den Best Practices unter App-Berechtigungen anfordern die Berechtigung
READ_EXTERNAL_STORAGE
an. - Sie können über direkte Dateipfade auf die Dateien zugreifen.
Weitere Informationen finden Sie im Abschnitt zum Öffnen von Mediendateien über direkte Dateipfade.
Mit Android 10
Wenn Ihre App auf Android 10 (API-Level 29) ausgerichtet ist, deaktivieren Sie den begrenzten Speicher und verwenden Sie für diesen Vorgang weiterhin den Ansatz für Android 9 und niedriger.
Wenn Sie Android 9 oder niedriger verwenden
Verwenden Sie diesen Ansatz:
- Fordern Sie gemäß den Best Practices unter App-Berechtigungen anfordern die Berechtigung
WRITE_EXTERNAL_STORAGE
an. - Sie können über direkte Dateipfade auf die Dateien zugreifen.
Nicht-Mediendateien verarbeiten
In diesem Abschnitt werden einige der häufigsten Anwendungsfälle für die Verarbeitung von Nicht-Mediendateien beschrieben und der allgemeine Ansatz erläutert, den Ihre Anwendung verwenden kann. In der folgenden Tabelle werden die einzelnen Anwendungsfälle zusammengefasst und Links zu den einzelnen Abschnitten mit weiteren Details angegeben.
Anwendungsfall | Zusammenfassung |
---|---|
Dokumentdateien öffnen | Verwende für alle Android-Versionen denselben Ansatz. |
In Dateien auf sekundären Speicher-Volumes schreiben | Verwende einen Ansatz für Android 11. Wähle für frühere Android-Versionen einen anderen Ansatz. |
Vorhandene Dateien von einem alten Speicherort migrieren | Migrieren Sie Ihre Dateien nach Möglichkeit auf einen begrenzten Speicher. Bei Bedarf können Sie den beschränkten Speicher für Android 10 deaktivieren. |
Inhalte mit anderen Apps teilen | Verwende für alle Android-Versionen denselben Ansatz. |
Nicht-Mediendateien im Cache speichern | Verwende für alle Android-Versionen denselben Ansatz. |
Nicht-Mediendateien auf ein Gerät exportieren | Verwenden Sie einen Ansatz, wenn Ihre Anwendung beschränkten Speicher verwendet. Verwenden Sie einen anderen Ansatz, wenn Ihre Anwendung den beschränkten Speicher deaktiviert. |
Öffnen einer Dokumentdatei
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 zur Auswahl angezeigt werden, können Sie setType()
oder EXTRA_MIME_TYPES
verwenden.
Mit dem folgenden Code können Sie beispielsweise nach allen PDF-, ODT- und TXT-Dateien suchen:
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 Speicher-Volumes gehören SD-Karten. Mithilfe der Klasse StorageVolume
können Sie auf Informationen zu einem bestimmten Speicher-Volume zugreifen.
Binde Logik ein, die auf der Android-Version basiert, auf der deine App ausgeführt wird.
Mit Android 11
Verwenden Sie diesen Ansatz:
- Verwenden Sie das Modell für begrenzten Speicher.
- Ausrichtung auf Android 10 (API-Level 29) oder niedriger.
- Deklarieren Sie die Berechtigung
WRITE_EXTERNAL_STORAGE
. - Sie haben folgende Möglichkeiten:
- Dateizugriff mit der
MediaStore
API. - Direkter Zugriff auf den Dateipfad über APIs wie
File
oderfopen()
.
- Dateizugriff mit der
Mit älteren Versionen ausgeführt
Verwenden Sie das Storage Access Framework. Damit können Nutzer den Speicherort auf einem sekundären Speicher-Volume auswählen, an dem Ihre Anwendung die Datei schreiben kann.
Vorhandene Dateien von einem alten Speicherort migrieren
Ein Verzeichnis gilt als Legacy-Speicherort, wenn es weder ein anwendungsspezifisches Verzeichnis noch ein öffentliches freigegebenes Verzeichnis ist. Wenn Ihre Anwendung Dateien an einem Legacy-Speicherort erstellt oder nutzt, empfehlen wir, die Dateien der Anwendung an Speicherorte zu migrieren, auf die mit eingeschränktem Speicher zugegriffen werden kann. Außerdem sollten Sie alle erforderlichen Änderungen an der Anwendung vornehmen, um mit Dateien im beschränkten Speicher zu arbeiten.
Zugriff auf den alten Speicherort für die Datenmigration beibehalten
Ihre Anwendung muss weiterhin Zugriff auf den Legacy-Speicherort haben, um Anwendungsdateien an Speicherorte zu migrieren, auf die mit eingeschränktem Speicher zugegriffen werden kann. Welche Methode Sie verwenden sollten, hängt vom Ziel-API-Level Ihrer App ab.
Wenn deine App auf Android 11 ausgerichtet ist
Setze das Flag
preserveLegacyExternalStorage
auftrue
, um das alte Speichermodell beizubehalten. So kann deine App die Daten eines Nutzers migrieren, wenn er auf die neue Version deiner App aktualisiert wird, die auf Android 11 ausgerichtet ist.Fahren Sie fort, den beschränkten Speicher zu deaktivieren, damit Ihre App weiterhin auf Ihre Dateien am alten Speicherort auf Android 10-Geräten zugreifen kann.
Wenn deine App auf Android 10 ausgerichtet ist
Deaktivieren Sie den begrenzten Speicher, um die Verwaltung des App-Verhaltens in verschiedenen Android-Versionen zu erleichtern.
App-Daten migrieren
Wenn Ihre Anwendung für die Migration bereit ist, verwenden Sie den folgenden Ansatz:
- Ausrichtung auf Android 10 oder niedriger.
- Deaktivieren Sie den begrenzten Speicher, damit Ihre Anwendung auf die zu migrierenden Dateien zugreifen kann.
-
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 eingeschränktem Speicher zugegriffen werden kann:- Verschieben Sie alle privaten Anwendungsdateien in das Verzeichnis, das von der Methode
getExternalFilesDir()
zurückgegeben wird. - Verschieben Sie alle freigegebenen Nicht-Mediendateien in ein anwendungsspezifisches Unterverzeichnis des Verzeichnisses
Downloads/
.
- Verschieben Sie alle privaten Anwendungsdateien in das Verzeichnis, das von der Methode
- Entfernen Sie die alten Speicherverzeichnisse der Anwendung 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 gesamte Nutzerbasis überwachen, indem Sie ein Analyseereignis erstellen.
Nachdem Nutzer ihre Daten migriert haben, kannst du ein weiteres Update für deine App veröffentlichen, die auf Android 11 ausgerichtet ist.
Inhalte mit anderen Apps teilen
Um die Dateien Ihrer App für eine einzelne andere App freizugeben, verwenden Sie ein FileProvider
. Für Anwendungen, die alle Dateien untereinander freigeben müssen, sollten Sie für jede Anwendung einen Contentanbieter verwenden und die Daten synchronisieren, wenn Anwendungen der Sammlung hinzugefügt werden.
Nicht-Mediendateien im Cache speichern
Welche Methode Sie verwenden sollten, hängt von der Art der Dateien ab, die Sie im Cache speichern müssen.
- Kleine Dateien oder Dateien mit vertraulichen Daten: Verwenden Sie
Context#getCacheDir()
. - Große Dateien oder Dateien, die keine vertraulichen Daten enthalten: Verwenden Sie
Context#getExternalCacheDir()
.
Nicht-Mediendateien auf ein Gerät exportieren
Legen Sie einen geeigneten Standardspeicherort zum Speichern von Nicht-Mediendateien fest. Nutzern erlauben, Dateien aus anwendungsspezifischen Verzeichnissen an einen allgemeineren Ort zu exportieren Verwenden Sie die Downloads oder Dokumentsammlungen von MediaStore, um Nicht-Mediendateien auf das Gerät zu exportieren.
Zugewiesenen Speicher vorübergehend deaktivieren
Bevor Ihre App vollständig mit bereichsspezifischem Speicher kompatibel ist, können Sie diese Funktion vorübergehend deaktivieren, sowohl in Ihren Tests als auch in Ihrer Produktionsanwendung.
Von Tests abmelden
Unter Android 10 (API-Level 29) und höher werden die Tests deiner App standardmäßig in einer Speicher-Sandbox ausgeführt. Diese Sandbox verhindert, dass Ihre Anwendung auf Dateien außerhalb des anwendungsspezifischen Verzeichnisses und öffentlich freigegebenen 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 das folgende Flag dem entsprechenden Speicher hinzu, der am instrument
aufruft:
-e no-isolated-storage 1
Dieses Flag wirkt sich auf das gesamte Verhalten des instrumentierten Testlaufs sowie auf den gesamten aufgerufenen Testcode aus. Wenn Sie dieses Flag verwenden, können Sie daher nicht prüfen, ob Ihre Anwendung mit begrenztem Speicher kompatibel ist. Für die Testausgabe ist es besser, stattdessen in einen App-bezogenen Speicher zu schreiben, der für die Shell lesbar ist. Anschließend können Sie dieses Verzeichnis auf Anwendungsebene abrufen. Rufen Sie getExternalMediaDirs()
auf, um zu ermitteln, aus welchem Verzeichnis abgerufen werden soll.
In der Produktions-App deaktivieren
Wenn deine App auf Android 10 (API-Level 29) oder niedriger ausgerichtet ist, kannst du den beschränkten Speicher in deiner Produktions-App vorübergehend deaktivieren. Wenn deine App jedoch auf Android 10 ausgerichtet ist, musst du in der Manifestdatei deiner App den Wert von requestLegacyExternalStorage
auf true
setzen:
<manifest ... > <!-- This attribute is "false" by default on apps targeting Android 10. --> <application android:requestLegacyExternalStorage="true" ... > ... </application> </manifest>
Wenn Sie testen möchten, wie sich eine App, die auf Android 10 oder niedriger ausgerichtet ist, bei Verwendung von begrenztem Speicher verhält, können Sie das Verhalten aktivieren. Dazu setzen Sie den Wert von requestLegacyExternalStorage
auf false
. Wenn Sie die Tests auf einem Gerät mit Android 11 ausführen, können Sie auch App-Kompatibilitäts-Flags verwenden, um das Verhalten Ihrer App mit oder ohne bereichsspezifischen Speicher zu testen.
Weitere Informationen
Weitere Informationen zum Android-Speicherplatz finden Sie in den folgenden Ressourcen: