Unter Android geben viele Befehle, die mit Dateien und Verzeichnissen arbeiten, Storage Access Framework (SAF) oder MediaStore-URIs anstatt herkömmliche Pfadangaben zurück, wie sie auf Desktop-Systemen verwendet werden. Der Vorteil von Inhalts-URIs, d.h. SAF- und MediaStore-URIs, besteht darin, dass sie auf praktisch alle Arten von Speicherorten verweisen können. Somit sind sie nicht auf Dateien und Verzeichnisse auf dem lokalen Gerät beschränkt, sondern können auch Dateien angeben, die in Clouds wie Google Drive gespeichert sind. Dies macht die Arbeit mit ihnen sehr flexibel, da die Verwendung von URIs das Laden von Dateien aus der Cloud oder das Speichern in der Cloud sehr einfach macht.
Dennoch sind bei der Arbeit mit diesen URIs einige Dinge zu beachten: Zunächst einmal reicht es beim Erstellen einer neuen Datei mit einem Inhalts-URI nicht aus, einfach OpenFile() mit einem Schreib-IO-Modus aufzurufen, wie Sie es bei normalen Dateien tun können. Alle Dateien, die mit Inhalts-URIs gespeichert werden, müssen zuerst erstellt werden, bevor Sie in sie schreiben können. Daher müssen Sie zuerst CreateFile() aufrufen und die gewünschte URI übergeben. Dadurch wird eine leere Datei (Null-Byte) für Sie erstellt. Danach können Sie die Datei mit OpenFile() zum Schreiben öffnen, genau wie bei normalen Dateien.
Zweitens verwenden Inhalts-URIs ein anderes Format als normale Dateipfade. Die Inhalts-URI eines Bildes in der Mediengalerie Ihres Telefons könnte beispielsweise wie folgt aussehen:
content://media/external_primary/images/media/1000039788 |
Wie Sie sehen können, gibt es in dieser URI überhaupt keine herkömmliche Dateinamen- und Erweiterungsspezifikation. Stattdessen hat die URI ein benutzerdefiniertes Format, das nur von den entsprechenden Android-Komponenten interpretiert werden kann. Es unterscheidet sich auch von Gerät zu Gerät und es kann viele Unterschiede zwischen den Android-Versionen geben. Daher dürfen Sie keine Annahmen über Inhalts-URIs treffen und diese nicht manuell durch einfaches Verknüpfen von Pfadkomponenten zusammenstellen. Aufgrund ihres undurchsichtigen benutzerdefinierten Formats ist es auch nicht möglich, Inhalts-URIs mit Befehlen wie FilePart() oder PathPart() zu analysieren. Wenn Sie den durch eine Inhalts-URI angegebenen Dateinamen herausfinden möchten, müssen Sie dazu GetFileAttributes() oder FileAttributes() verwenden.
Inhalts-URIs dürfen nur mit den richtigen Befehlen erstellt werden. Beispielsweise geben die Befehle FileRequest() oder PathRequest() Inhalts-URIs zurück, mit denen Sie arbeiten können. Angenommen, Sie möchten eine Datei an einem vom Benutzer ausgewählten Speicherort speichern, dann könnten Sie dies wie folgt tun:
p$ = PathRequest("Select path")
uri$ = CreateFile(p$, "test.txt") ; this is important, see above!
OpenFile(1, uri$, #MODE_WRITE)
WriteLine(1, "Hello World!")
CloseFile(1)
|
Natürlich können Sie stattdessen auch FileRequest() im Speichermodus verwenden. In diesem Fall erstellt FileRequest() die Datei bereits und Sie müssen CreateFile() überhaupt nicht aufrufen:
uri$ = FileRequest("Select file", {Mode = #REQ_SAVEMODE})
OpenFile(1, uri$, #MODE_WRITE)
WriteLine(1, "Hello World!")
CloseFile(1)
|
Wenn Sie eine Datei öffnen möchten, aber nicht über die vollständige Inhalts-URI verfügen, sondern nur über die Inhalts-URI ihres Pfads, können Sie FullPath() verwenden, um eine Inhalts-URI zu erstellen, die den Pfad und den Dateinamen enthält, z.B. wie folgt:
p$ = PathRequest("Select path")
uri$ = FullPath(p$, "test.txt")
OpenFile(1, uri$)
l$ = ReadLine(1)
CloseFile(1)
|
Wenn Sie eine neue Datei in einem der Standardordner von MediaStore erstellen möchten, gehen Sie wie folgt vor:
uri$ = CreateFile(#MEDIA_IMAGES, "test.png", {MIMEType = "image/png"})
SaveBrush(1, uri$, {Format = #IMGFMT_PNG})
|
Um diese Datei später zu laden, können Sie Folgendes tun:
uri$ = FullPath(#MEDIA_IMAGES, "test.png") LoadBrush(1, uri$) |
Da FullPath() nur Inhalts-URIs zu vorhandenen Dateien oder Verzeichnissen zurückgeben kann, können Sie ihn nicht verwenden, wenn Sie eine Inhalts-URI für eine nicht vorhandene Datei oder ein nicht vorhandenes Verzeichnis erstellen möchten. Aus diesem Grund können Sie MakeDirectory() nicht verwenden, um ein neues Verzeichnis mit einer Inhalts-URI zu erstellen: Er akzeptiert nur ein einziges Argument, sodass er nicht mit Inhalts-URIs verwendet werden kann, da wir keine Inhalts-URI erstellen können, die auf ein nicht vorhandenes Verzeichnis verweist. Daher müssen Sie CreateDirectory() verwenden, um ein neues Verzeichnis mit einer Inhalts-URI zu erstellen, da dieser Befehl zwei Argumente akzeptiert, z.B. wie folgt:
p$ = PathRequest("Select directory")
uri$ = CreateDirectory(p$, "Test")
|
Der obige Code erstellt ein Verzeichnis namens "Test" in dem vom Benutzer ausgewählten Verzeichnis.
Die meisten DOS-Bibliotheksbefehle von Hollywood können problemlos mit Inhalts-URIs verwendet werden. Es gibt nur die folgenden Ausnahmen: MoveFile() und SetFileAttributes() werden für Inhalts-URIs nicht unterstützt und sowohl CopyFile() als auch DeleteFile() können nur für einzelne Dateien verwendet werden, nicht für Verzeichnisse. Wenn Sie DeleteFile() für ein Inhalts-URI-Verzeichnis verwenden, muss das Verzeichnis leer sein, sonst schlägt der Vorgang fehl. Wenn es sich bei der Inhalts-URI um eine MediaStore-URI handelt, ist es außerdem nicht möglich, Verzeichnisse zu erstellen und alle Dateien in einem MediaStore-Verzeichnis zu durchlaufen. Beides ist nur mit SAF-URIs möglich, d.h. mit denen, die von Befehlen wie FileRequest() und PathRequest() zurückgegeben werden.
Dies waren die wichtigsten Punkte, die bei der Arbeit mit Inhalts-URIs zu beachten sind. Wie Sie sehen können, sind die meisten Punkte identisch mit normalen Pfaden. Es gibt nur wenige Fälle, die besondere Aufmerksamkeit erfordern.