Um Nutzern mehr Kontrolle über ihre Dateien zu geben und die Datenflut einzudämmen, wurde in Android 10 ein neues Speicherparadigma für Apps eingeführt, der befristete Speicher. Begrenzter Speicher ändert die Art und Weise, wie Apps Dateien im externen Speicher eines Geräts speichern und darauf zugreifen. Wenn Sie Ihre App auf den abgegrenzten Speicher umstellen möchten, sollten Sie die Best Practices für gängige Anwendungsfälle bei der Speichernutzung befolgen, die in diesem Leitfaden beschrieben sind. Die Anwendungsfälle sind in zwei Kategorien unterteilt: Verarbeitung von Mediendateien und Verarbeitung von nicht medialen Dateien.
In vielen Fällen erstellt Ihre App Dateien, auf die andere Apps nicht zugreifen müssen oder sollten. Das System bietet app-spezifische Speicherorte zur Verwaltung solcher Dateien.
Weitere Informationen zum Speichern und Aufrufen von Dateien unter Android finden Sie in den Trainingsleitfäden für das Speicher.
Mediendateien verarbeiten
In diesem Abschnitt werden einige der gängigen Anwendungsfälle für die Verarbeitung von Mediendateien (Video-, Bild- und Audiodateien) beschrieben. Außerdem wird der allgemeine Ansatz erläutert, den Sie in Ihrer App verwenden können. In der folgenden Tabelle sind diese Anwendungsfälle zusammengefasst. Außerdem finden Sie Links zu den einzelnen Abschnitten mit weiteren Informationen.
Anwendungsfall | Zusammenfassung |
---|---|
Alle Bild- oder Videodateien anzeigen | Verwenden Sie für alle Android-Versionen die gleiche Herangehensweise. |
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 Sie die Funktion „Begrenzter Speicher“ für Ihre App deaktivieren. |
Speicherort für neue Downloads festlegen | Verwenden Sie einen Ansatz, wenn Ihre App den begrenzten Speicher verwendet. Verwenden Sie einen anderen Ansatz, wenn Sie die Funktion „Begrenzter Speicher“ für Ihre App deaktivieren. |
Nutzermediendateien 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. Deaktivieren Sie bei Android 10 den abgegrenzten Speicher und verwenden Sie stattdessen den Ansatz für Android 9 und niedriger. |
Einzelnes bereits vorhandenes Image importieren | Verwenden Sie für alle Android-Versionen die gleiche Herangehensweise. |
Ein einzelnes Bild aufnehmen | Verwenden Sie für alle Android-Versionen die gleiche Herangehensweise. |
Mediendateien mit anderen Apps teilen | Verwenden Sie für alle Android-Versionen die gleiche Herangehensweise. |
Mediendateien für eine bestimmte App freigeben | Verwenden Sie für alle Android-Versionen denselben Ansatz. |
Auf Dateien aus Code oder Bibliotheken zugreifen, die direkte Dateipfade verwenden | Verwenden Sie einen Ansatz für Android 11. Deaktivieren Sie bei Android 10 den abgegrenzten Speicher und verwenden Sie stattdessen den Ansatz für Android 9 und niedriger. |
Bild- oder Videodateien aus mehreren Ordnern anzeigen
Eine Mediensammlung mit der query()
API abfragen 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 folgendermaßen vor:
- Fordere die Berechtigung
READ_EXTERNAL_STORAGE
gemäß den Best Practices unter App-Berechtigungen anfordern an. - Rufen Sie Mediendateien basierend auf dem Wert von
MediaColumns.DATA
ab, der den absoluten Dateisystempfad zum Medienelement auf dem Laufwerk enthält.
Hinweis:Wenn du auf eine vorhandene Mediendatei zugreifst, kannst du den Wert der Spalte DATA
in deiner Logik verwenden. Das liegt daran, dass dieser Wert einen gültigen Dateipfad hat.
Sie können jedoch nicht davon ausgehen, dass die Datei immer verfügbar ist. Seien Sie bereit, mit möglichen dateibasierten E/A-Fehlern umzugehen.
Wenn Sie hingegen 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 Ihre App begrenzten Speicher verwendet, folgen Sie den Schritten im Abschnitt Standortinformationen in Fotos des Leitfadens zum Medienspeicher.
zugegriffen wird.Speicherort für neue Downloads festlegen
Wenn Ihre App den Speicher mit begrenztem Zugriff verwendet, achten Sie darauf, wo Sie die heruntergeladenen Mediendateien speichern.
Wenn andere Apps Zugriff auf Dateien benötigen, können Sie für Downloads oder Dokumentensammlungen gut definierte Mediensammlungen 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 diese Dateien mit DownloadManager
abrufen.
Mediendateien von Nutzern auf ein Gerät exportieren
Legen Sie einen geeigneten Standardspeicherort für die Speicherung von Nutzermediendateien fest:
- Sie können Nutzern die Möglichkeit geben, zu entscheiden, ob ihre Mediadateien von anderen Apps gelesen werden können. Verwenden Sie dazu den appspezifischen Speicher oder den freigegebenen Speicher.
- Nutzern erlauben, Dateien aus app-spezifischen Verzeichnissen an einen allgemein zugänglichen Speicherort 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 Vorgang ändern oder löschen
Integrieren Sie Logik basierend auf den Android-Versionen, auf denen Ihre App ausgeführt wird.
Mit Android 11
Verwenden Sie diesen Ansatz:
- Erstellen Sie mit
MediaStore.createWriteRequest()
oderMediaStore.createTrashRequest()
eine ausstehende Intent-Anfrage für die Schreib- oder Löschanfrage Ihrer App und bitten Sie den Nutzer dann, die Berechtigung zum Bearbeiten einer Reihe von Dateien zu erteilen, indem Sie diesen Intent aufrufen. Bewerten Sie die Antwort der Nutzenden:
- Wenn die Berechtigung gewährt wurde, fahren Sie mit dem Ändern oder Löschen fort.
- Wenn die Berechtigung nicht gewährt wurde, erläutere 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 abgegrenzten Speicher und verwenden Sie für diesen Vorgang weiterhin den Ansatz für Android 9 und niedriger.
Android 9 oder niedriger
Gehen Sie folgendermaßen vor:
- Fordere die Berechtigung
WRITE_EXTERNAL_STORAGE
gemäß den Best Practices unter App-Berechtigungen anfordern an. - Verwende die
MediaStore
API, um die Mediendateien zu ändern oder zu löschen.
Einzelnes vorhandenes Bild importieren
Wenn Sie ein einzelnes Bild importieren möchten, das bereits vorhanden ist (z. B. als Foto für das Profil eines Nutzers), kann Ihre App entweder ihre eigene Benutzeroberfläche für die Operation verwenden oder die Systemauswahl.
Eigene Benutzeroberfläche präsentieren
Gehen Sie folgendermaßen vor:
- Fordere die Berechtigung
READ_EXTERNAL_STORAGE
gemäß den Best Practices unter App-Berechtigungen anfordern an. - Verwenden Sie die
query()
API, um eine Mediensammlung abzufragen. - Die Ergebnisse in der benutzerdefinierten Benutzeroberfläche Ihrer App anzeigen
Systemauswahl verwenden
Verwenden Sie die ACTION_GET_CONTENT
-Intention, bei der der Nutzer aufgefordert wird, ein Bild zum Importieren auszuwählen.
Wenn Sie die Arten von Bildern filtern möchten, die der Nutzer in der Systemauswahl auswählen kann, verwenden Sie setType()
oder EXTRA_MIME_TYPES
.
Einzelnes Bild aufnehmen
Wenn Sie ein einzelnes Bild aufnehmen und in Ihrer App verwenden möchten (z. B. als Foto für ein Nutzerprofil), verwenden Sie den Intent ACTION_IMAGE_CAPTURE
, 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 in den MediaStore aufzunehmen. Weitere Informationen finden Sie im Abschnitt Element hinzufügen des Leitfadens zum Medienspeicher.
Mediendateien für eine bestimmte App freigeben
Verwenden Sie die Android-Komponente FileProvider
, wie im Leitfaden Dateifreigabe einrichten beschrieben.
Auf Dateien aus Code oder Bibliotheken zugreifen, die direkte Dateipfade verwenden
Berücksichtigen Sie die Logik der Android-Versionen, unter denen Ihre App ausgeführt wird.
Mit Android 11
Verwenden Sie diesen Ansatz:
- Fordere die Berechtigung
READ_EXTERNAL_STORAGE
gemäß den Best Practices unter App-Berechtigungen anfordern an. - Greifen Sie über direkte Dateipfade auf die Dateien zu.
Weitere Informationen finden Sie im Abschnitt zum Öffnen von Mediendateien mithilfe von direkten Dateipfaden.
Android 10
Wenn Ihre App auf Android 10 (API-Level 29) ausgerichtet ist, deaktivieren Sie den abgegrenzten Speicher und verwenden Sie für diesen Vorgang weiterhin den Ansatz für Android 9 und niedriger.
Android 9 oder niedriger
Verwenden Sie diesen Ansatz:
- Fordere die Berechtigung
WRITE_EXTERNAL_STORAGE
gemäß den Best Practices unter App-Berechtigungen anfordern 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. Außerdem wird der allgemeine Ansatz erläutert, den Ihre Anwendung verwenden kann. In der folgenden Tabelle sind diese Anwendungsfälle zusammengefasst. Außerdem finden Sie Links zu den einzelnen Abschnitten mit weiteren Informationen.
Anwendungsfall | Zusammenfassung |
---|---|
Dokumente öffnen | Verwenden Sie für alle Android-Versionen die gleiche Herangehensweise. |
In Dateien auf sekundären Speichervolumes schreiben | Verwenden Sie einen Ansatz für Android 11. Für ältere Android-Versionen ist ein anderer Ansatz erforderlich. |
Vorhandene Dateien von einem bisherigen Speicherort migrieren | Migrieren Sie Ihre Dateien nach Möglichkeit in den Speicher mit begrenztem Zugriff. Deaktivieren Sie bei Bedarf die Speicherbeschränkung für Android 10. |
Inhalte für andere Apps freigeben | 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 Sie die Funktion „Begrenzter Speicher“ für Ihre App deaktivieren. |
Dokumentdatei öffnen
Verwenden Sie die ACTION_OPEN_DOCUMENT
-Intent, um den Nutzer aufzufordern, eine Datei über die Systemauswahl auszuwählen. Wenn Sie die Dateitypen filtern möchten, die in der Systemauswahl dem Nutzer zur Auswahl 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 Speichervolume zugreifen.
Berücksichtigen Sie die Logik der Android-Version, unter der Ihre App ausgeführt wird.
Android 11
Gehen Sie folgendermaßen vor:
- Verwenden Sie das Modell für Speicher mit Bereichsbeschränkung.
- Richten Sie Ihre App auf Android 10 (API-Level 29) oder niedriger aus.
- Deklarieren Sie die Berechtigung
WRITE_EXTERNAL_STORAGE
. - Sie haben folgende Zugriffsarten:
- Dateizugriff über die
MediaStore
API - Direkter Dateipfadzugriff über APIs wie
File
oderfopen()
- Dateizugriff über die
Unter älteren Versionen ausführen
Verwenden Sie das Storage Access Framework, mit dem Nutzer den Speicherort auf einem sekundären Speichervolume auswählen können, an dem Ihre App die Datei schreiben kann.
Vorhandene Dateien von einem bisherigen Speicherort migrieren
Ein Verzeichnis gilt als altmodischer Speicherort, wenn es sich nicht um ein app-spezifisches Verzeichnis oder ein öffentlich freigegebenes Verzeichnis handelt. Wenn Ihre App Dateien an einem bisherigen Speicherort erstellt oder verwendet, empfehlen wir Ihnen, die Dateien Ihrer App an einen Speicherort zu migrieren, auf den mit dem abgegrenzten Speicher zugegriffen werden kann. Nehmen Sie außerdem alle erforderlichen App-Änderungen vor, damit sie mit Dateien im abgegrenzten Speicher funktioniert.
Zugriff auf den bisherigen Speicherort für die Datenmigration beibehalten
Ihre App muss Zugriff auf den bisherigen Speicherort haben, um App-Dateien an Orte zu migrieren, auf die mit befristetem 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
Setzen Sie das Flag
preserveLegacyExternalStorage
auftrue
, um das alte Speichermodell beizubehalten. So kann Ihre App die Daten eines Nutzers migrieren, wenn dieser auf die neue Version Ihrer App für Android 11 aktualisiert wird.Deaktivieren Sie weiterhin den abgegrenzten Speicher, damit Ihre App weiterhin auf Ihre Dateien am bisherigen Speicherort auf Android 10-Geräten zugreifen kann.
Wenn Ihre App auf Android 10 ausgerichtet ist
Deaktivieren Sie den befristeten Speicher, um das Verhalten Ihrer App in verschiedenen Android-Versionen einfacher zu verwalten.
App-Daten migrieren
Wenn Ihre App für die Migration bereit ist, gehen Sie so vor:
- Die App muss auf Android 10 oder niedriger ausgerichtet sein.
- Deaktivieren Sie den Speicher mit Bereichsbeschränkung, damit Ihre App auf die Dateien zugreifen kann, die Sie migrieren müssen.
-
Stellen Sie Code bereit, mit dem Dateien über die
File
API von ihrem aktuellen Speicherort unter/sdcard/
an einen Speicherort verschoben werden, auf den mit einem Speicherort mit Bereichsbeschränkung 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 bisherigen Speicherverzeichnisse Ihrer App aus dem Verzeichnis
/sdcard/
.
Nachdem Nutzer die neue Version Ihrer App installiert haben, führen sie die Datenmigration auf ihren Geräten durch. Sie können den Migrationsprozess für Ihre gesamte Nutzerbasis im Blick behalten, indem Sie ein Analyseereignis erstellen.
Nachdem Nutzer ihre Daten migriert haben, veröffentlichen Sie ein weiteres Update für Ihre App, bei dem Sie Android 11 als Zielversion angeben.
Inhalte mit anderen Apps teilen
Wenn Sie die Dateien Ihrer App für eine einzelne andere App freigeben möchten, verwenden Sie einen FileProvider
. Wenn Dateien zwischen allen Apps geteilt werden müssen, empfehlen wir, für jede App einen Inhaltsanbieter zu verwenden und die Daten dann zu synchronisieren, wenn der Sammlung Apps hinzugefügt werden.
Nicht-Mediendateien im Cache speichern
Welchen Ansatz Sie verwenden sollten, hängt vom Typ der Dateien ab, die Sie im Cache speichern müssen.
- Kleine Dateien oder Dateien mit vertraulichen Informationen: Verwenden Sie
Context#getCacheDir()
. - Große Dateien oder Dateien ohne vertrauliche Informationen: Verwenden Sie
Context#getExternalCacheDir()
.
Nicht-Mediendateien auf ein Gerät exportieren
Legen Sie einen geeigneten Standardspeicherort für nicht-mediale Dateien fest. Nutzern erlauben, Dateien aus app-spezifischen Verzeichnissen an einen allgemein zugänglichen Speicherort zu exportieren. Verwenden Sie 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 sollten, können Sie diese Dateien an appspezifischen Speicherorten speichern.
Interne Speicherverzeichnisse
Das System verhindert, dass andere Apps auf diese Speicherorte zugreifen. Unter Android 10 (API-Level 29) und höher werden diese Speicherorte verschlüsselt. Diese Speicherorte eignen sich gut für vertrauliche Daten, auf die nur Ihre App zugreifen kann.
Externe Speicherverzeichnisse
Wenn der interne Speicher nicht genügend Platz für appspezifische Dateien bietet, können Sie stattdessen externen Speicher verwenden. Andere Apps können zwar auf diese Verzeichnisse zugreifen, wenn sie die entsprechenden Berechtigungen haben, die darin gespeicherten Dateien sind jedoch nur für Ihre App bestimmt.
Unter Android 4.4 (API-Level 19) oder höher muss Ihre App keine speicherbezogenen Berechtigungen anfordern, um auf appspezifische Verzeichnisse im externen Speicher zuzugreifen.
Wenn der Nutzer Ihre App deinstalliert, werden die im app-spezifischen Speicher gespeicherten Dateien entfernt. Daher sollten Sie dort nichts speichern, was der Nutzer unabhängig von Ihrer App aufbewahren möchte.
Speicherplatzbeschränkung vorübergehend deaktivieren
Solange Ihre App nicht vollständig mit dem abgegrenzten Speicher kompatibel ist, können Sie ihn sowohl in Ihren Tests als auch in Ihrer Produktions-App vorübergehend deaktivieren.
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 Anwendung auf Dateien außerhalb des anwendungsspezifischen Verzeichnisses und öffentlich freigegebenen Verzeichnissen 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 entsprechenden Harness, das am instrument
aufruft, das folgende Flag hinzu:
-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 die Kompatibilität Ihrer App mit dem abgegrenzten Speicher nicht überprüfen. Für die Testausgabe empfiehlt es sich, stattdessen in einen anwendungsspezifischen Speicher zu schreiben, der von der Shell gelesen werden kann. Sie können dann dieses Verzeichnis auf App-Ebene abrufen. Rufen Sie getExternalMediaDirs()
auf, um festzulegen, aus welchem Verzeichnis die Daten abgerufen werden sollen.
In der Produktions-App deaktivieren
Wenn Ihre App auf Android 10 (API-Level 29) oder niedriger ausgerichtet ist, können Sie den abgegrenzten Speicher in Ihrer Produktions-App vorübergehend deaktivieren. Wenn Sie jedoch auf Android 10 ausgerichtet sind, müssen Sie in der Manifestdatei Ihrer App den Wert von requestLegacyExternalStorage
auf true
festlegen:
<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 auf Android 10 oder niedriger ausgerichtete App bei eingeschränktem Speicher verhält, können Sie das Verhalten aktivieren. Setzen Sie dazu den Wert von requestLegacyExternalStorage
auf false
. Wenn Sie auf einem Gerät mit Android 11 testen, können Sie auch Flags zur App-Kompatibilität verwenden, um das Verhalten Ihrer App mit oder ohne Speicher mit begrenztem Zugriff zu testen.
Weitere Informationen
Weitere Informationen zum Android-Speicher finden Sie in den folgenden Artikeln: