Auf Geräten mit Android 4.4 (API-Level 19) und höher kann Ihre App über das Storage Access Framework mit einem Dokumentanbieter interagieren, einschließlich externer Speichermedien und cloudbasierter Speicher. Mit diesem Framework können Nutzer über eine Systemauswahl einen Dokumentanbieter auswählen und bestimmte Dokumente und andere Dateien auswählen, die Ihre App erstellen, öffnen oder ändern soll.
Da der Nutzer die Dateien oder Verzeichnisse auswählt, auf die Ihre App zugreifen kann, sind für diesen Mechanismus keine Systemberechtigungen erforderlich. Außerdem werden die Nutzerkontrolle und der Datenschutz verbessert. Außerdem verbleiben diese Dateien, die außerhalb eines app-spezifischen Verzeichnisses und außerhalb des Medienspeichers gespeichert sind, auf dem Gerät, nachdem Ihre App deinstalliert wurde.
Die Verwendung des Frameworks umfasst die folgenden Schritte:
- Eine App ruft einen Intent auf, der eine speicherbezogene Aktion enthält. Diese Aktion entspricht einem bestimmten Anwendungsfall, den das Framework zur Verfügung stellt.
- Der Nutzer sieht eine Systemauswahl, mit der er einen Dokumentanbieter durchsuchen und einen Speicherort oder ein Dokument auswählen kann, an dem die speicherbezogene Aktion ausgeführt wird.
- Die App erhält Lese- und Schreibzugriff auf einen URI, der den vom Nutzer ausgewählten Standort oder das vom Nutzer ausgewählte Dokument darstellt. Mit diesem URI kann die App Vorgänge am ausgewählten Standort ausführen.
Wenn Sie den Zugriff auf Mediendateien auf Geräten mit Android 9 (API-Level 28) oder niedriger unterstützen möchten, deklarieren Sie die Berechtigung READ_EXTERNAL_STORAGE
und legen Sie maxSdkVersion
auf 28
fest.
In diesem Leitfaden werden die verschiedenen Anwendungsfälle beschrieben, die das Framework für die Arbeit mit Dateien und anderen Dokumenten unterstützt. Außerdem wird beschrieben, wie Sie Vorgänge für den vom Nutzer ausgewählten Standort ausführen.
Anwendungsfälle für den Zugriff auf Dokumente und andere Dateien
Das Storage Access Framework unterstützt die folgenden Anwendungsfälle für den Zugriff auf Dateien und andere Dokumente.
- Neue Datei erstellen
- Mit der Intent-Aktion
ACTION_CREATE_DOCUMENT
können Nutzer eine Datei an einem bestimmten Speicherort speichern. - Dokument oder Datei öffnen
- Mit der Intent-Aktion
ACTION_OPEN_DOCUMENT
können Nutzer ein bestimmtes Dokument oder eine bestimmte Datei zum Öffnen auswählen. - Zugriff auf die Inhalte eines Verzeichnisses gewähren
- Mit der Intent-Aktion
ACTION_OPEN_DOCUMENT_TREE
, die ab Android 5.0 (API-Level 21) verfügbar ist, können Nutzer ein bestimmtes Verzeichnis auswählen und Ihrer App so Zugriff auf alle Dateien und Unterverzeichnisse in diesem Verzeichnis gewähren.
In den folgenden Abschnitten finden Sie Anleitungen zur Konfiguration der einzelnen Anwendungsfälle.
Neue Dateien erstellen
Verwenden Sie die Intent-Aktion ACTION_CREATE_DOCUMENT
, um die Systemdateiauswahl zu laden und dem Nutzer zu ermöglichen, einen Speicherort für den Inhalt einer Datei auszuwählen. Dieser Vorgang ähnelt dem in den „Speichern unter“-Dialogfeldern anderer Betriebssysteme.
Hinweis : Mit ACTION_CREATE_DOCUMENT
kann keine vorhandene Datei überschrieben werden. Wenn Ihre App versucht, eine Datei mit demselben Namen zu speichern, hängt das System eine Zahl in Klammern an das Ende des Dateinamens an.
Wenn Ihre App beispielsweise versucht, eine Datei mit dem Namen confirmation.pdf
in einem Verzeichnis zu speichern, in dem bereits eine Datei mit diesem Namen vorhanden ist, speichert das System die neue Datei unter dem Namen confirmation(1).pdf
.
Geben Sie beim Konfigurieren des Intents den Namen und den MIME-Typ der Datei an. Optional können Sie mit dem Intent-Extra EXTRA_INITIAL_URI
den URI der Datei oder des Verzeichnisses angeben, die bzw. das bei der ersten Ausführung der Dateiauswahl angezeigt werden soll.
Das folgende Code-Snippet zeigt, wie der Intent zum Erstellen einer Datei erstellt und aufgerufen wird:
Kotlin
// Request code for creating a PDF document. const val CREATE_FILE = 1 private fun createFile(pickerInitialUri: Uri) { val intent = Intent(Intent.ACTION_CREATE_DOCUMENT).apply { addCategory(Intent.CATEGORY_OPENABLE) type = "application/pdf" putExtra(Intent.EXTRA_TITLE, "invoice.pdf") // Optionally, specify a URI for the directory that should be opened in // the system file picker before your app creates the document. putExtra(DocumentsContract.EXTRA_INITIAL_URI, pickerInitialUri) } startActivityForResult(intent, CREATE_FILE) }
Java
// Request code for creating a PDF document. private static final int CREATE_FILE = 1; private void createFile(Uri pickerInitialUri) { Intent intent = new Intent(Intent.ACTION_CREATE_DOCUMENT); intent.addCategory(Intent.CATEGORY_OPENABLE); intent.setType("application/pdf"); intent.putExtra(Intent.EXTRA_TITLE, "invoice.pdf"); // Optionally, specify a URI for the directory that should be opened in // the system file picker when your app creates the document. intent.putExtra(DocumentsContract.EXTRA_INITIAL_URI, pickerInitialUri); startActivityForResult(intent, CREATE_FILE); }
Datei öffnen
Ihre App verwendet möglicherweise Dokumente als Speichereinheit, in die Nutzer Daten eingeben, die sie mit anderen teilen oder in andere Dokumente importieren möchten. Beispiele hierfür sind das Öffnen eines Produktivitätsdokuments oder eines als EPUB-Datei gespeicherten Buchs.
In diesen Fällen sollten Sie dem Nutzer die Möglichkeit geben, die zu öffnende Datei auszuwählen, indem Sie den Intent ACTION_OPEN_DOCUMENT
aufrufen. Dadurch wird die Dateiauswahl-App des Systems geöffnet. Wenn Sie nur die Dateitypen anzeigen möchten, die von Ihrer App unterstützt werden, geben Sie einen MIME-Typ an. Optional können Sie auch den URI der Datei angeben, die bei der ersten Ausführung der Dateiauswahl angezeigt werden soll. Verwenden Sie dazu das Intent-Extra EXTRA_INITIAL_URI
.
Das folgende Code-Snippet zeigt, wie der Intent zum Öffnen eines PDF-Dokuments erstellt und aufgerufen wird:
Kotlin
// Request code for selecting a PDF document. const val PICK_PDF_FILE = 2 fun openFile(pickerInitialUri: Uri) { val intent = Intent(Intent.ACTION_OPEN_DOCUMENT).apply { addCategory(Intent.CATEGORY_OPENABLE) type = "application/pdf" // Optionally, specify a URI for the file that should appear in the // system file picker when it loads. putExtra(DocumentsContract.EXTRA_INITIAL_URI, pickerInitialUri) } startActivityForResult(intent, PICK_PDF_FILE) }
Java
// Request code for selecting a PDF document. private static final int PICK_PDF_FILE = 2; private void openFile(Uri pickerInitialUri) { Intent intent = new Intent(Intent.ACTION_OPEN_DOCUMENT); intent.addCategory(Intent.CATEGORY_OPENABLE); intent.setType("application/pdf"); // Optionally, specify a URI for the file that should appear in the // system file picker when it loads. intent.putExtra(DocumentsContract.EXTRA_INITIAL_URI, pickerInitialUri); startActivityForResult(intent, PICK_PDF_FILE); }
Zugriffsbeschränkungen
Unter Android 11 (API‑Level 30) und höher können Sie die Intent-Aktion ACTION_OPEN_DOCUMENT
nicht verwenden, um den Nutzer aufzufordern, einzelne Dateien aus den folgenden Verzeichnissen auszuwählen:
- Das Verzeichnis
Android/data/
und alle Unterverzeichnisse. - Das Verzeichnis
Android/obb/
und alle Unterverzeichnisse.
Zugriff auf den Inhalt eines Verzeichnisses gewähren
Apps zur Dateiverwaltung und Medienerstellung verwalten in der Regel Gruppen von Dateien in einer Verzeichnishierarchie. Wenn Sie diese Funktion in Ihrer App anbieten möchten, verwenden Sie die Intent-Aktion ACTION_OPEN_DOCUMENT_TREE
. Damit kann der Nutzer Zugriff auf eine gesamte Verzeichnisstruktur gewähren, mit einigen Ausnahmen ab Android 11 (API-Level 30). Ihre App kann dann auf alle Dateien im ausgewählten Verzeichnis und in allen zugehörigen Unterverzeichnissen zugreifen.
Wenn Sie ACTION_OPEN_DOCUMENT_TREE
verwenden, erhält Ihre App nur Zugriff auf die Dateien in dem Verzeichnis, das der Nutzer auswählt. Sie haben keinen Zugriff auf Dateien anderer Apps, die sich außerhalb des vom Nutzer ausgewählten Verzeichnisses befinden. Durch diesen nutzergesteuerten Zugriff können Nutzer genau auswählen, welche Inhalte sie mit Ihrer App teilen möchten.
Optional können Sie mit dem Intent-Extra EXTRA_INITIAL_URI
den URI des Verzeichnisses angeben, das bei der ersten Ausführung der Dateiauswahl angezeigt werden soll.
Das folgende Code-Snippet zeigt, wie der Intent zum Öffnen eines Verzeichnisses erstellt und aufgerufen wird:
Kotlin
fun openDirectory(pickerInitialUri: Uri) { // Choose a directory using the system's file picker. val intent = Intent(Intent.ACTION_OPEN_DOCUMENT_TREE).apply { // Optionally, specify a URI for the directory that should be opened in // the system file picker when it loads. putExtra(DocumentsContract.EXTRA_INITIAL_URI, pickerInitialUri) } startActivityForResult(intent, your-request-code) }
Java
public void openDirectory(Uri uriToLoad) { // Choose a directory using the system's file picker. Intent intent = new Intent(Intent.ACTION_OPEN_DOCUMENT_TREE); // Optionally, specify a URI for the directory that should be opened in // the system file picker when it loads. intent.putExtra(DocumentsContract.EXTRA_INITIAL_URI, uriToLoad); startActivityForResult(intent, your-request-code); }
Zugriffsbeschränkungen
Unter Android 11 (API‑Level 30) und höher können Sie die Intent-Aktion ACTION_OPEN_DOCUMENT_TREE
nicht verwenden, um Zugriff auf die folgenden Verzeichnisse anzufordern:
- Das Stammverzeichnis des internen Speichervolumes.
- Das Stammverzeichnis jedes SD-Karten-Volumes, das der Gerätehersteller als zuverlässig betrachtet, unabhängig davon, ob die Karte emuliert oder entfernbar ist. Ein zuverlässiges Volume ist ein Volume, auf das eine App die meiste Zeit erfolgreich zugreifen kann.
- Das Verzeichnis
Download
.
Außerdem können Sie unter Android 11 (API‑Level 30) und höher die Intent-Aktion ACTION_OPEN_DOCUMENT_TREE
nicht verwenden, um den Nutzer aufzufordern, einzelne Dateien aus den folgenden Verzeichnissen auszuwählen:
- Das Verzeichnis
Android/data/
und alle Unterverzeichnisse. - Das Verzeichnis
Android/obb/
und alle Unterverzeichnisse.
Vorgänge für den ausgewählten Standort ausführen
Nachdem der Nutzer eine Datei oder ein Verzeichnis über die Dateiauswahl des Systems ausgewählt hat, können Sie den URI des ausgewählten Elements mit dem folgenden Code in onActivityResult()
abrufen:
Kotlin
override fun onActivityResult( requestCode: Int, resultCode: Int, resultData: Intent?) { if (requestCode == your-request-code && resultCode == Activity.RESULT_OK) { // The result data contains a URI for the document or directory that // the user selected. resultData?.data?.also { uri -> // Perform operations on the document using its URI. } } }
Java
@Override public void onActivityResult(int requestCode, int resultCode, Intent resultData) { if (requestCode == your-request-code && resultCode == Activity.RESULT_OK) { // The result data contains a URI for the document or directory that // the user selected. Uri uri = null; if (resultData != null) { uri = resultData.getData(); // Perform operations on the document using its URI. } } }
Wenn Ihre App einen Verweis auf den URI des ausgewählten Elements erhält, kann sie verschiedene Vorgänge für das Element ausführen. Sie können beispielsweise auf die Metadaten des Elements zugreifen, das Element direkt bearbeiten und das Element löschen.
In den folgenden Abschnitten wird beschrieben, wie Sie Aktionen für die vom Nutzer ausgewählten Dateien ausführen.
Unterstützte Vorgänge eines Anbieters ermitteln
Bei verschiedenen Inhaltsanbietern können unterschiedliche Vorgänge für Dokumente ausgeführt werden, z. B. das Kopieren des Dokuments oder das Anzeigen der Miniaturansicht eines Dokuments. Um herauszufinden, welche Vorgänge ein bestimmter Anbieter unterstützt, sehen Sie sich den Wert von Document.COLUMN_FLAGS
an.
In der Benutzeroberfläche Ihrer App können dann nur die vom Anbieter unterstützten Optionen angezeigt werden.
Berechtigungen beibehalten
Wenn Ihre App eine Datei zum Lesen oder Schreiben öffnet, erteilt das System Ihrer App eine URI-Berechtigung für diese Datei, die bis zum Neustart des Geräts des Nutzers gültig ist. Angenommen, Ihre App ist eine Bildbearbeitungs-App und Sie möchten, dass Nutzer direkt über Ihre App auf die fünf zuletzt bearbeiteten Bilder zugreifen können. Wenn das Gerät des Nutzers neu gestartet wurde, müssen Sie den Nutzer zurück zur Systemauswahl leiten, damit er die Dateien finden kann.
Damit der Zugriff auf Dateien auch nach einem Neustart des Geräts erhalten bleibt und die Nutzerfreundlichkeit verbessert wird, kann Ihre App die vom System angebotene persistente URI-Berechtigung „übernehmen“, wie im folgenden Code-Snippet gezeigt:
Kotlin
val contentResolver = applicationContext.contentResolver val takeFlags: Int = Intent.FLAG_GRANT_READ_URI_PERMISSION or Intent.FLAG_GRANT_WRITE_URI_PERMISSION // Check for the freshest data. contentResolver.takePersistableUriPermission(uri, takeFlags)
Java
final int takeFlags = intent.getFlags() & (Intent.FLAG_GRANT_READ_URI_PERMISSION | Intent.FLAG_GRANT_WRITE_URI_PERMISSION); // Check for the freshest data. getContentResolver().takePersistableUriPermission(uri, takeFlags);
Dokumentmetadaten untersuchen
Wenn Sie den URI für ein Dokument haben, erhalten Sie Zugriff auf die zugehörigen Metadaten. In diesem Snippet werden die Metadaten für ein Dokument abgerufen, das durch den URI angegeben wird, und protokolliert:
Kotlin
val contentResolver = applicationContext.contentResolver fun dumpImageMetaData(uri: Uri) { // The query, because it only applies to a single document, returns only // one row. There's no need to filter, sort, or select fields, // because we want all fields for one document. val cursor: Cursor? = contentResolver.query( uri, null, null, null, null, null) cursor?.use { // moveToFirst() returns false if the cursor has 0 rows. Very handy for // "if there's anything to look at, look at it" conditionals. if (it.moveToFirst()) { // Note it's called "Display Name". This is // provider-specific, and might not necessarily be the file name. val displayName: String = it.getString(it.getColumnIndex(OpenableColumns.DISPLAY_NAME)) Log.i(TAG, "Display Name: $displayName") val sizeIndex: Int = it.getColumnIndex(OpenableColumns.SIZE) // If the size is unknown, the value stored is null. But because an // int can't be null, the behavior is implementation-specific, // and unpredictable. So as // a rule, check if it's null before assigning to an int. This will // happen often: The storage API allows for remote files, whose // size might not be locally known. val size: String = if (!it.isNull(sizeIndex)) { // Technically the column stores an int, but cursor.getString() // will do the conversion automatically. it.getString(sizeIndex) } else { "Unknown" } Log.i(TAG, "Size: $size") } } }
Java
public void dumpImageMetaData(Uri uri) { // The query, because it only applies to a single document, returns only // one row. There's no need to filter, sort, or select fields, // because we want all fields for one document. Cursor cursor = getActivity().getContentResolver() .query(uri, null, null, null, null, null); try { // moveToFirst() returns false if the cursor has 0 rows. Very handy for // "if there's anything to look at, look at it" conditionals. if (cursor != null && cursor.moveToFirst()) { // Note it's called "Display Name". This is // provider-specific, and might not necessarily be the file name. String displayName = cursor.getString( cursor.getColumnIndex(OpenableColumns.DISPLAY_NAME)); Log.i(TAG, "Display Name: " + displayName); int sizeIndex = cursor.getColumnIndex(OpenableColumns.SIZE); // If the size is unknown, the value stored is null. But because an // int can't be null, the behavior is implementation-specific, // and unpredictable. So as // a rule, check if it's null before assigning to an int. This will // happen often: The storage API allows for remote files, whose // size might not be locally known. String size = null; if (!cursor.isNull(sizeIndex)) { // Technically the column stores an int, but cursor.getString() // will do the conversion automatically. size = cursor.getString(sizeIndex); } else { size = "Unknown"; } Log.i(TAG, "Size: " + size); } } finally { cursor.close(); } }
Dokument öffnen
Wenn Sie einen Verweis auf den URI eines Dokuments haben, können Sie ein Dokument zur weiteren Verarbeitung öffnen. In diesem Abschnitt finden Sie Beispiele für das Öffnen einer Bitmap und eines Eingabestreams.
Bitmap
Das folgende Code-Snippet zeigt, wie eine Bitmap
-Datei anhand ihres URI geöffnet wird:
Kotlin
val contentResolver = applicationContext.contentResolver @Throws(IOException::class) private fun getBitmapFromUri(uri: Uri): Bitmap { val parcelFileDescriptor: ParcelFileDescriptor = contentResolver.openFileDescriptor(uri, "r") val fileDescriptor: FileDescriptor = parcelFileDescriptor.fileDescriptor val image: Bitmap = BitmapFactory.decodeFileDescriptor(fileDescriptor) parcelFileDescriptor.close() return image }
Java
private Bitmap getBitmapFromUri(Uri uri) throws IOException { ParcelFileDescriptor parcelFileDescriptor = getContentResolver().openFileDescriptor(uri, "r"); FileDescriptor fileDescriptor = parcelFileDescriptor.getFileDescriptor(); Bitmap image = BitmapFactory.decodeFileDescriptor(fileDescriptor); parcelFileDescriptor.close(); return image; }
Nachdem Sie die Bitmap geöffnet haben, können Sie sie in einem ImageView
anzeigen.
Eingabestream
Das folgende Code-Snippet zeigt, wie ein InputStream-Objekt anhand seines URI geöffnet wird. In diesem Snippet werden die Zeilen der Datei in einen String gelesen:
Kotlin
val contentResolver = applicationContext.contentResolver @Throws(IOException::class) private fun readTextFromUri(uri: Uri): String { val stringBuilder = StringBuilder() contentResolver.openInputStream(uri)?.use { inputStream -> BufferedReader(InputStreamReader(inputStream)).use { reader -> var line: String? = reader.readLine() while (line != null) { stringBuilder.append(line) line = reader.readLine() } } } return stringBuilder.toString() }
Java
private String readTextFromUri(Uri uri) throws IOException { StringBuilder stringBuilder = new StringBuilder(); try (InputStream inputStream = getContentResolver().openInputStream(uri); BufferedReader reader = new BufferedReader( new InputStreamReader(Objects.requireNonNull(inputStream)))) { String line; while ((line = reader.readLine()) != null) { stringBuilder.append(line); } } return stringBuilder.toString(); }
Dokumente bearbeiten
Mit dem Storage Access Framework können Sie ein Textdokument direkt bearbeiten.
Das folgende Code-Snippet überschreibt den Inhalt des Dokuments, das durch den angegebenen URI dargestellt wird:
Kotlin
val contentResolver = applicationContext.contentResolver private fun alterDocument(uri: Uri) { try { contentResolver.openFileDescriptor(uri, "w")?.use { FileOutputStream(it.fileDescriptor).use { it.write( ("Overwritten at ${System.currentTimeMillis()}\n") .toByteArray() ) } } } catch (e: FileNotFoundException) { e.printStackTrace() } catch (e: IOException) { e.printStackTrace() } }
Java
private void alterDocument(Uri uri) { try { ParcelFileDescriptor pfd = getActivity().getContentResolver(). openFileDescriptor(uri, "w"); FileOutputStream fileOutputStream = new FileOutputStream(pfd.getFileDescriptor()); fileOutputStream.write(("Overwritten at " + System.currentTimeMillis() + "\n").getBytes()); // Let the document provider know you're done by closing the stream. fileOutputStream.close(); pfd.close(); } catch (FileNotFoundException e) { e.printStackTrace(); } catch (IOException e) { e.printStackTrace(); } }
Dokument löschen
Wenn Sie den URI für ein Dokument haben und das Document.COLUMN_FLAGS
des Dokuments SUPPORTS_DELETE
enthält, können Sie das Dokument löschen. Beispiel:
Kotlin
DocumentsContract.deleteDocument(applicationContext.contentResolver, uri)
Java
DocumentsContract.deleteDocument(applicationContext.contentResolver, uri);
Entsprechenden Media-URI abrufen
Die Methode getMediaUri()
gibt einen Media Store-URI zurück, der dem angegebenen URI des Dokumentanbieters entspricht. Die beiden URIs verweisen auf dasselbe zugrunde liegende Element. Mit dem MediaStore-URI können Sie einfacher auf Mediendateien aus dem freigegebenen Speicher zugreifen.
Die getMediaUri()
-Methode unterstützt ExternalStorageProvider
-URIs. Unter Android 12 (API-Level 31) und höher unterstützt die Methode auch MediaDocumentsProvider
-URIs.
Virtuelle Datei öffnen
Unter Android 7.0 (API-Level 25) und höher kann Ihre App virtuelle Dateien verwenden, die vom Storage Access Framework zur Verfügung gestellt werden. Auch wenn virtuelle Dateien keine binäre Darstellung haben, kann Ihre App ihren Inhalt öffnen, indem sie sie in einen anderen Dateityp konvertiert oder die Dateien mit der Intent-Aktion ACTION_VIEW
aufruft.
Wenn Sie virtuelle Dateien öffnen möchten, muss Ihre Clientanwendung eine spezielle Logik für die Verarbeitung dieser Dateien enthalten. Wenn Sie eine Byte-Darstellung der Datei abrufen möchten, um beispielsweise eine Vorschau der Datei zu sehen, müssen Sie beim Dokumentanbieter einen alternativen MIME-Typ anfordern.
Nachdem der Nutzer eine Auswahl getroffen hat, verwenden Sie den URI in den Ergebnisdaten, um festzustellen, ob die Datei virtuell ist, wie im folgenden Code-Snippet gezeigt:
Kotlin
private fun isVirtualFile(uri: Uri): Boolean { if (!DocumentsContract.isDocumentUri(this, uri)) { return false } val cursor: Cursor? = contentResolver.query( uri, arrayOf(DocumentsContract.Document.COLUMN_FLAGS), null, null, null ) val flags: Int = cursor?.use { if (cursor.moveToFirst()) { cursor.getInt(0) } else { 0 } } ?: 0 return flags and DocumentsContract.Document.FLAG_VIRTUAL_DOCUMENT != 0 }
Java
private boolean isVirtualFile(Uri uri) { if (!DocumentsContract.isDocumentUri(this, uri)) { return false; } Cursor cursor = getContentResolver().query( uri, new String[] { DocumentsContract.Document.COLUMN_FLAGS }, null, null, null); int flags = 0; if (cursor.moveToFirst()) { flags = cursor.getInt(0); } cursor.close(); return (flags & DocumentsContract.Document.FLAG_VIRTUAL_DOCUMENT) != 0; }
Nachdem Sie bestätigt haben, dass es sich bei dem Dokument um eine virtuelle Datei handelt, können Sie die Datei in einen alternativen MIME-Typ wie "image/png"
umwandeln. Das folgende Code-Snippet zeigt, wie Sie prüfen, ob eine virtuelle Datei als Bild dargestellt werden kann, und wie Sie gegebenenfalls einen Eingabestream aus der virtuellen Datei abrufen:
Kotlin
@Throws(IOException::class) private fun getInputStreamForVirtualFile( uri: Uri, mimeTypeFilter: String): InputStream { val openableMimeTypes: Array<String>? = contentResolver.getStreamTypes(uri, mimeTypeFilter) return if (openableMimeTypes?.isNotEmpty() == true) { contentResolver .openTypedAssetFileDescriptor(uri, openableMimeTypes[0], null) .createInputStream() } else { throw FileNotFoundException() } }
Java
private InputStream getInputStreamForVirtualFile(Uri uri, String mimeTypeFilter) throws IOException { ContentResolver resolver = getContentResolver(); String[] openableMimeTypes = resolver.getStreamTypes(uri, mimeTypeFilter); if (openableMimeTypes == null || openableMimeTypes.length < 1) { throw new FileNotFoundException(); } return resolver .openTypedAssetFileDescriptor(uri, openableMimeTypes[0], null) .createInputStream(); }
Zusätzliche Ressourcen
Weitere Informationen zum Speichern und Zugreifen auf Dokumente und andere Dateien finden Sie in den folgenden Ressourcen.
Produktproben
- ActionOpenDocument, verfügbar auf GitHub.
- ActionOpenDocumentTree, verfügbar auf GitHub.