Android - Image speichern



  • Hallo,

    in meinem kleinen Projekt lasse ich mir das aktuelle Bild der Frontkamera in einem TImage anzeigen. Dieses Image möchte ich jetzt auf dem Tablet speichern. Das versuche ih mit:

    Image1->Bitmap->SaveToFile("Test123.jpg");
    

    Ich erhalte hier folgenden Error:

    Exception-Klasse EJNIException mit Meldung 'java.io.FileNotFoundException: Test123.jpg (Read-only file system)'.
    

    Meine Vermutung ist jetzt, dass der Zugriff auf das Android-Filesystem so ohne weiteres nicht möglich ist. Wie man bestimmt merkt, habe ich da noch nicht so viel Erfahrung mit.

    Kann mir da jemand einen Tip geben?

    Danke und Gruß
    Torsten



  • Ich kenn mich da nicht aus, aber ich denke, dass du im /bin (Unter-)Verzeichnis nicht schreiben darfst. Gibt´s vielleicht eine API Funktion, die dir das Datenverzeichnis für dein App gibt?



  • Es gibt internalDataPath als auch externalDataPath, s. Android - writing/saving files from native code only.



  • @Th69 Habe Teile des Codes aus dem Link in mein Projekt übernommen. Für 'internalDataPath'
    muss die

    #include <native_activity.h>
    

    eingebunden werden. Habe ich gemacht. Leider gibt es diese in meiner CBuilder-Version wohl nicht, obwohl das Android SDK 25 installiert ist. Ich erhalte diesen Fehler:

    'native_activity.h'-Datei nicht gefunden
    


  • Probier mal das (nicht getestet):

    #include <System.IOUtils.hpp>
    
    String myAppData = Ioutils::TPath::GetDocumentsPath()  + IOUtils::TPath::DirectorySeparatorChar + "myAppData" + IOUtils::TPath::DirectorySeparatorChar;
    
    Image1->Bitmap->SaveToFile(myAppData + "Test123.jpg");  
    


  • Erhalte dabei diesen Fehler:

    ...mit der Meldung 
    'java.io.FileNotFoundException: /data/user/0/
    com.embarcadero.Camera_Photo_03/files/myAppData/Test123.jpg (Noch such file or directory):'
    

    Auf dem Tablet habe ich diesen Pfad gefunden:
    "Interner Speicher/Android/data/com.embarcadero.Camera_Photo_03/files"
    Also "myAppData/" existiert nicht. Auch das /data/user/0/ finde ich so nicht.



  • Das Speichern geht. Hatte halt nur die Datei "Test123.jpg" erwartet. habe den Code jetzt wie folgt geändert:

    String myPath = Ioutils::TPath::GetDocumentsPath();
    Image1->Bitmap->SaveToFile(myPath + "/Test123.jpg");
    
    

    Er legt mir in dem jeweiligen Verzeichnis jetzt eine Datei ab. Und zwar "pskc_schema.xsd". ???



  • myAppData steht exemplarisch für deine eigene Anwendung, weswegen dieses Verzeichnis nicht existiert. Schau dir mal die Funktion ForceDirectories an.



  • So, um sicher zu stellen, dass ich überhaupt mal etwas speichern kann, habe ich es mal mit einem TextFile versucht. Dazu habe ich ein Memo platziert, in dem eine Zeile "Hallo Welt" steht.
    Jetzt möchte ich mit diesem Code den Inhalt des Memo in eine Textdatei speichern:

    String myPath = Ioutils::TPath::GetDocumentsPath();
    Memo1->Lines->SaveToFile(myPath + "/Test123.txt");
    

    Im Debugger erhalte ich dazu folgenden Pfad:

    /data/user/0/com.embarcadero.Camera_Photo_03/files/
    

    Ich erhalte keinen Fehler. Das Programm läuft durch. Aber ich sehe die Textdatei einfach nicht!
    Auf dem Tablet habe ich dieses Verzeichnis geöffnet:
    Interner Speicher/Android/data/com.embarcadero.Camera_Photo_03/files

    Aber da ist nix???

    Gruß
    Torsten



  • Die von dir angegebenen Pfade sind nicht identisch. Kann es daran liegen...?

    @torsten_156 sagte in Android - Image speichern:

    /data/user/0/com.embarcadero.Camera_Photo_03/files/

    @torsten_156 sagte in Android - Image speichern:

    Interner Speicher/Android/data/com.embarcadero.Camera_Photo_03/files



  • Ich vermute mal JA! Aber wie komme ich auf meinem Tablet denn an den Pfad "/data/user/0/" ran?

    Gruß
    Torsten



  • @torsten_156 sagte in Android - Image speichern:

    Aber wie komme ich auf meinem Tablet denn an den Pfad "/data/user/0/" ran?

    Vermutlich gar nicht, ohne root access...

    Google "android data user 0"



  • Danke für den Tip mit Google 😉
    Habe da eine Seite gefunden, auf der die jeweiligen Unterschiede der Speicherorte beschrieben war.
    (hier) Habe es dann mal so versucht:

    Image1->Bitmap->SaveToFile("/storage/emulated/0/Android/data/com.embarcadero.Camera_Photo_03/files/MeinFoto.jpg");
    
    Memo1->Lines->SaveToFile("/storage/emulated/0/Android/data/com.embarcadero.Camera_Photo_03/files/Test123.txt");
    

    So hat es funktioniert. Jetzt möchte ich den Pfad natürlich nicht hart codieren. Suche jetzt noch die passende Funktion/Library, um den Pfad zur Laufzeit ermitteln zu können.

    Gruß
    Torsten



  • Kennst du schon Standard RTL Path Functions across the Supported Target Platforms? (direkt über die Doku zu TPath::GetDocumentsPath gefunden)

    TPath::GetPublicPath() sollte also der richtige Pfad sein.



  • Genau das war es. Jetzt finde ich die Fotos auch wieder 😉

    Vielen Dank für die Hilfe.

    Gruß Torsten


Log in to reply