Um Nutzern mehr Kontrolle über ihre Dateien zu geben und Dateien übersichtlicher zu gestalten, wurde mit Android 10 ein neues Speichermodell für Anwendungen namens eingeschränkter Speicher eingeführt. Begrenzter Speicher ändert die Art und Weise, wie Apps Dateien im externen Speicher eines Geräts speichern und darauf zugreifen. Damit Sie Ihre Anwendung zur Unterstützung von begrenztem Speicher migrieren können, sollten Sie sich an den Best Practices für gängige Speicheranwendungsfälle in diesem Leitfaden orientieren. Die Anwendungsfälle sind in zwei Kategorien unterteilt: Umgang mit Mediendateien und Umgang mit Nicht-Mediendateien.
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 häufigsten Anwendungsfälle für die Verarbeitung von Mediendateien (Video-, Bild- und Audiodateien) beschrieben und die allgemeine Vorgehensweise für Ihre Anwendung erläutert. In der folgenden Tabelle finden Sie eine Zusammenfassung dieser Anwendungsfälle und Links zu den einzelnen Abschnitten, die weitere Informationen enthalten.
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 die gleiche Herangehensweise. |
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 begrenzten 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 begrenzten Speicher deaktiviert. |
Nutzermediendateien auf ein Gerät exportieren | Verwenden Sie für alle Android-Versionen die gleiche Herangehensweise. |
Mehrere Mediendateien in einem Vorgang ändern oder löschen | Verwenden Sie einen Ansatz für Android 11. Deaktivieren Sie bei Android 10 den begrenzten 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 die gleiche Herangehensweise. |
Auf Dateien über Code oder Bibliotheken zugreifen, die direkte Dateipfade verwenden | Verwenden Sie einen Ansatz für Android 11. Deaktivieren Sie bei Android 10 den begrenzten Speicher und verwenden Sie stattdessen den Ansatz für Android 9 und niedriger. |
Bild- oder Videodateien aus mehreren Ordnern anzeigen
Mit der query()
API können Sie eine Mediensammlung 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:
- Fordern Sie 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 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. Sie sollten auf den Umgang mit dateibasierten E/A-Fehlern vorbereitet sein.
Um eine Mediendatei zu erstellen oder zu aktualisieren, solltest du jedoch nicht die Spalte DATA
verwenden. Verwenden Sie stattdessen die Spalten DISPLAY_NAME
und RELATIVE_PATH
.
Auf Standortinformationen in 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 Anwendung begrenzten Speicher verwendet, achten Sie darauf, an welchem Ort Sie die von Ihnen heruntergeladenen Mediendateien speichern.
Wenn andere Anwendungen Zugriff auf Dateien benötigen, sollten Sie gut 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 zum Speichern von Nutzermediendateien fest:
- Nutzer können mit app-spezifischem Speicher oder freigegebenem Speicher festlegen, ob ihre Mediendateien für andere Apps lesbar sein sollen oder nicht.
- Ermöglichen Sie Nutzern, Dateien aus anwendungsspezifischen Verzeichnissen an einen allgemein zugänglichen Speicherort zu exportieren. Verwende 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
Gehen Sie folgendermaßen vor:
- Erstellen Sie mit
MediaStore.createWriteRequest()
oderMediaStore.createTrashRequest()
einen ausstehenden Intent für die Schreib- oder Löschanfrage Ihrer Anwendung und bitten Sie den Nutzer dann um die Berechtigung zum Bearbeiten einer Reihe von Dateien, indem Sie diesen Intent aufrufen. Bewerten Sie die Antwort der Nutzenden:
- Wenn die Berechtigung gewährt wurde, fahren Sie mit dem Änderungs- oder Löschvorgang 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 mithilfe dieser Methoden, die unter Android 11 und höher verfügbar sind, findest du hier.
Läuft mit Android 10
Wenn deine App auf Android 10 (API-Level 29) ausgerichtet ist, deaktiviere den eingeschränkten Speicher und verwende für diesen Vorgang weiterhin die Methode für Android 9 und niedriger.
Android 9 oder niedriger
Gehen Sie folgendermaßen vor:
- Fordern Sie die Berechtigung
WRITE_EXTERNAL_STORAGE
gemäß den Best Practices unter App-Berechtigungen anfordern an. - Mit der
MediaStore
API kannst du die Mediendateien ändern oder löschen.
Einzelnes bereits vorhandenes Bild importieren
Wenn Sie ein bereits vorhandenes Bild importieren möchten, um es beispielsweise 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
Gehen Sie folgendermaßen vor:
- Fordern Sie die Berechtigung
READ_EXTERNAL_STORAGE
gemäß den Best Practices unter App-Berechtigungen anfordern an. - Verwenden Sie die
query()
API, um eine Mediensammlung abzufragen. - Zeigen Sie die Ergebnisse in der benutzerdefinierten UI Ihrer App an.
Systemauswahl verwenden
Verwenden Sie den Intent ACTION_GET_CONTENT
, mit dem der Nutzer aufgefordert wird, ein Image für den Import auszuwählen.
Wenn Sie die Bildtypen filtern möchten, die in der Systemauswahl dem Nutzer zur Auswahl angezeigt werden, können Sie setType()
oder EXTRA_MIME_TYPES
verwenden.
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
Mit der Methode insert()
können Sie Datensätze direkt dem MediaStore hinzufügen. Weitere Informationen finden Sie im Leitfaden zum Medienspeicher im Abschnitt Element hinzufügen.
Mediendateien mit einer bestimmten App teilen
Du kannst die Android-Komponente FileProvider
wie im Leitfaden Dateifreigabe einrichten beschrieben verwenden.
Auf Dateien über Code oder Bibliotheken zugreifen, die direkte Dateipfade verwenden
Integrieren Sie Logik basierend auf den Android-Versionen, auf denen Ihre App ausgeführt wird.
Mit Android 11
Gehen Sie folgendermaßen vor:
- Fordern Sie 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.
Läuft mit Android 10
Wenn deine App auf Android 10 (API-Level 29) ausgerichtet ist, deaktiviere den eingeschränkten Speicher und verwende für diesen Vorgang weiterhin die Methode für Android 9 und niedriger.
Android 9 oder niedriger
Gehen Sie folgendermaßen vor:
- Fordern Sie die Berechtigung
WRITE_EXTERNAL_STORAGE
gemäß den Best Practices unter App-Berechtigungen anfordern an. - Greifen Sie über direkte Dateipfade auf die Dateien zu.
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 und Links zu den einzelnen Abschnitten, die weitere Informationen enthalten.
Anwendungsfall | Zusammenfassung |
---|---|
Dokumente öffnen | Verwenden Sie für alle Android-Versionen die gleiche Herangehensweise. |
In Dateien auf sekundären Speicher-Volumes schreiben | Verwenden Sie einen Ansatz für Android 11. Verwenden Sie bei früheren Android-Versionen einen anderen Ansatz. |
Vorhandene Dateien von einem Legacy-Speicherort migrieren | Migrieren Sie Ihre Dateien nach Möglichkeit auf einen begrenzten Speicher. Deaktivieren Sie den begrenzten Speicher für Android 10 bei Bedarf. |
Inhalte mit anderen Apps teilen | Verwenden Sie für alle Android-Versionen die gleiche Herangehensweise. |
Nicht-Mediendateien im Cache speichern | Verwenden Sie für alle Android-Versionen die gleiche Herangehensweise. |
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 begrenzten Speicher deaktiviert. |
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 in der Systemauswahl dem Nutzer zur Auswahl angezeigt werden, können Sie setType()
oder EXTRA_MIME_TYPES
verwenden.
Beispielsweise können Sie alle PDF-, ODT- und TXT-Dateien mit dem folgenden Code 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
Sekundäre Speicher-Volumes enthalten 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.
Läuft mit Android 11
Gehen Sie folgendermaßen vor:
- Verwenden Sie das Modell Eingeschränkter Speicher.
- Die App muss auf Android 10 (API-Level 29) oder niedriger ausgerichtet sein.
- Geben Sie die Berechtigung
WRITE_EXTERNAL_STORAGE
an. - Sie haben folgende Zugriffsarten:
- Dateizugriff mit der
MediaStore
API. - Direkter Zugriff auf den Dateipfad mithilfe von APIs wie
File
oderfopen()
.
- Dateizugriff mit der
Unter älteren Versionen ausführen
Verwenden Sie das Storage Access Framework, mit dem Nutzer den Speicherort auf einem sekundären Speicher-Volume auswählen können, in das Ihre Anwendung die Datei schreiben kann.
Vorhandene Dateien von einem alten Speicherort migrieren
Ein Verzeichnis gilt als Legacy-Speicherort, wenn es sich nicht um ein anwendungsspezifisches Verzeichnis oder ein öffentliches freigegebenes Verzeichnis handelt. Wenn Ihre Anwendung Dateien an einem Legacy-Speicherort erstellt oder verwendet, sollten Sie die Dateien Ihrer Anwendung an Speicherorte migrieren, auf die mit eingeschränktem Speicher zugegriffen werden kann, und die 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. Ihr Ansatz hängt vom Ziel-API-Level Ihrer Anwendung 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 begrenzten Speicher, damit Ihre App auf Android 10-Geräten weiterhin auf Ihre Dateien am alten Speicherort zugreifen kann.
Wenn Ihre App auf Android 10 ausgerichtet ist
Deaktivieren Sie den begrenzten Speicher, um das Verhalten Ihrer App in verschiedenen Android-Versionen einfacher verwalten zu können.
App-Daten migrieren
Wenn Ihre Anwendung für die Migration bereit ist, gehen Sie so vor:
- Richten Sie Ihre App auf Android 10 oder niedriger aus.
- Deaktivieren Sie den begrenzten Speicher, damit Ihre Anwendung auf die Dateien zugreifen kann, die Sie migrieren müssen.
-
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 Legacy-Speicherverzeichnisse Ihrer Anwendung aus dem Verzeichnis
/sdcard/
.
Nachdem Nutzer die neue Version Ihrer 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 Nutzer ihre Daten migriert haben, veröffentliche ein weiteres Update in deiner App, wobei du Android 11 als Ziel verwendest.
Inhalte mit anderen Apps teilen
Wenn Sie die Dateien Ihrer Anwendung für eine einzelne andere Anwendung freigeben möchten, verwenden Sie eine FileProvider
. Für Anwendungen, die Dateien untereinander freigeben müssen, empfehlen wir, für jede Anwendung einen Contentanbieter zu verwenden und die Daten dann zu synchronisieren, wenn die Anwendungen der Sammlung 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 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. Ermöglichen Sie Nutzern, Dateien aus anwendungsspezifischen 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.
Eingeschränkten Speicher vorübergehend deaktivieren
Bevor Ihre Anwendung vollständig mit dem begrenzten Speicher kompatibel ist, können Sie sie vorübergehend in Ihren Tests und in Ihrer Produktions-App deaktivieren.
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 Anwendung auf Dateien außerhalb des anwendungsspezifischen Verzeichnisses und öffentlich freigegebenen Verzeichnissen zugreift.
Wenn bei einem Test Dateien für den Host ausgegeben werden, z. B. Screenshots, Daten zur Fehlerbehebung, Abdeckungsdaten oder Leistungsmesswerte, können Sie diese Dateien in globale Verzeichnisse schreiben. Fügen Sie dazu dem entsprechenden Netzwerk, 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 daher die Kompatibilität Ihrer Anwendung mit begrenztem Speicher nicht prüfen. Für die Testausgabe empfiehlt es sich, stattdessen in einen anwendungsspezifischen Speicher zu schreiben, der von der Shell gelesen werden kann. Anschließend können Sie das auf die App beschränkte Verzeichnis 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 begrenzten Speicher in deiner Produktions-App vorübergehend deaktivieren. Wenn deine App auf Android 10 ausgerichtet ist, musst du jedoch in der Manifestdatei deiner 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 Tests auf einem Gerät mit Android 11 durchführen, können Sie auch App-Kompatibilitäts-Flags verwenden, um das Verhalten Ihrer App mit oder ohne begrenztem Speicher zu testen.
Zusätzliche Ressourcen
Weitere Informationen zum Android-Speicherplatz finden Sie hier: