(Datenbank-)Datei für App bereitstellen bzw. ins Dateisystem der APP kopieren

S

Sempervivum

Fortgeschrittenes Mitglied
9
Ich entwickele gerade für jemand anders eine kleine App, die eine SQLite-Datenbank ausliest. Der Betreffende will die Datenbank selber füllen und pflegen. Dazu muss er in der Lage sein, die Datenbank-Datei der App zur Verfügung zu stellen. Ich habe schon gelernt, dass diese Datei im Dateisystem unter /data/data/<packagename>/databases/<dbname> liegt. Frage: Hat der Benutzer überhaupt Zugriff auf diesen Pfad, kann er die Datenbank-Datei einfach dort hinein legen? Wenn nicht, welche Alternativen gibt es? Durch die App die Datei aus einem öffentliche Pfad lesen und in das databases-Verzeichnis kopieren?
Edit: Zusatzfrage, wie mache ich das bei der Entwicklung in Android-Studio? Dort kann man das Dateisystem mit dem Device-Fileexplorer anschauen aber das scheint virtuell zu sein, ich finde es im Dateisystem von Windows nicht wieder. Es ist mir nicht gelungen, dort die Datenbank-Datei hinein zu legen.
Beste Grüße, Ulrich
 
Zuletzt bearbeitet:
Hallo Ulrich,

kann er die Datenbank-Datei einfach dort hinein legen?

Nein , du musst die DB entweder zur Laufzeit erstellen , oder sie fertig in den Assets mitliefern und bei der Installation ( erster Launch) dorthin synchroniseren.

Edit: Zusatzfrage, wie mache ich das bei der Entwicklung in Android-Studio? Dort kann man das Dateisystem mit dem Device-Fileexplorer anschauen aber das scheint virtuell zu sein, ich finde es im Dateisystem von Windows nicht wieder.
Siehe meine andere Antwort : du benötigst ein virtuelles Device und dann im AS -> rechts -> Device File Explorer .
(Aber nur im Debug Modus sichtbar)
 
Vielen Dank, der Benutzer hat den Wunsch, die Datenbank außerhalb der App zu erstellen, die Datenbank-Datei auf das Tablet zu legen und die App soll sie dann einlesen. Ist das überhaupt nicht machbar oder ist meine Vorstellung:
Wenn nicht, welche Alternativen gibt es? Durch die App die Datei aus einem öffentliche Pfad lesen und in das databases-Verzeichnis kopieren?
realisierbar?
 
Ich erlaube mir , aus deinem anderen Thread zu zitieren :
mit Capacitor auf der Basis von HTML, CSS und Javascript eine App zu entwickeln.

Das was du grundsätzlich vorhast ist NICHT möglich - Warum ?

Wenn du eine lokale Webseite laufen lassen möchtest , so muss der gesamte htdocs Inhalt in den Cache oder Files Ordnern sein.
Das heisst - vorher damit dorthin synchronisieren.

Wenn dann mal das sind, musst du dir einen lokalen Server bauen .
Ist der dann fertig, musst du Non SSL abfangen ( oder ein Certifikat erstellen) , denn ansonsten wird die App blockiert.
Und dann kommt das Hauptproblem : deine sql datenbank kann aus einer reinen css / htmls Umgebung NICHT geöffnet werden.
Das musst du mit nativen Code umsetzen
 
Zuletzt bearbeitet:
Hm, da ich das Ganze mit Capacitor entwickle geschieht alles, was mit dem Server zu tun hat im Verborgenen und ich habe keinen Einfluss darauf. Der lokale Server wird durch Capacitor eingerichtet. Capacitor stellt auch APIs zur Verfügung um u. a. auf das Dateisystem zuzugreifen und ich hatte die Vorstellung, dass ich damit umsetzen kann, was ich beschrieben habe.
 
Ich kenne Capacitor nicht , ich entwickle grundsätzlich seit Jahrzehnten nativ.
Und da du nach AS gefragt hattest, gabs auch die Antworten dazu ....

Wenn du die App öffentlich noch in die Stores stellen möchtest , so habe ich meine berechtigten Zweifel, dass diese App lange online bleiben wird .
Workarounds mit Cleartraffic protocoll werden grundsätzlich von den Betreibern mit Argusaugen betrachtet und schnell entfernt .
Da ist Tür und Tor geöffnet .

Ich empfehle daher, alles in Native ( Java/Kotlin) umzusetzen. Ggf REACT zu verwenden.
Das wäre es aber schon an Alternativen.
 
Stores sind kein Thema da die App nur privat benutzt werden soll und nicht publiziert.

Leider habe ich nicht die Zeit, mich in die native Entwicklung mit Java/Kotlin einzuarbeiten. Daher war ich sehr erfreut als ich Capacitor gefunden hatte, aber da eine App zum Laufen zu bringen ist anscheinend bei weitem nicht so einfach wie unter Windows mit Electron.
 
Nein , das sind zwei völlig unterschiedliche Techniken und Plattformen, da es sich hier um ein mobiles System handelt und mit einer Fülle von Restriktionen belegt ist .

Man kann quasi keine App auf die Beine stellen ,wenn man nicht zu 100% genau weis , was das System macht.
Schließlich bewegst du dich hier auf einer reinen VM und nicht auf dem Betriebssystem-Kern ( a la Windows / Linux)
 
Hm, anscheinend muss ich dann akzeptieren, dass das was ich vor habe, mit vertretbarem Aufwand nicht machbar ist.
 
Inzwischen war ich nicht untätig, hier ein Update:
Weil ich dachte, dass es für eine App nicht möglich ist, eine Datei aus einem öffentlichen Ordner zu lesen, habe ich eine Alternative gesucht und versucht, die Datei von meinem Webspace herunter zu laden. Mit einigen Schwierigkeiten und guter Unterstützung des Entwicklers des Plugins blobwriter für Capacitor bin auch zum Ziel gekommen. Hier der Code:
Code:
        function readDatabaseFile(event) {
            Capacitor.Plugins.Filesystem.requestPermissions().then((status) => {
                console.log(status);
                fetch('https://example.com/path/db-cors.php')
                    .then(response => response.blob())
                    .then(blob => {
                        // console.log(blob);
                        window.capacitor_blob_writer({
                            path: 'file:///data/user/0/com.substanzen.app/databases/SubstancesSQLite.db',
                            blob: blob
                            // fast_mode: true
                        }).then(result => {
                            alert('Datenbankdatei wurde erfolgreich eingelesen');
                        });
                    });
            });
        }
Ich musste dazu die Datei für das CORS frei geben.

Auf das Web angewiesen zu sein fand ich jedoch unbefriedigend und ich habe weiter nach einer Lösung gesucht. Es hat sich dann heraus gestellt, dass die Situation ganz ähnlich wie bei Javascript ist: Zugriff auf öffentliche Ordner ist möglich aber nur mit Interaktion des Benutzers. Ich habe dann einen Filepicker verwendet und es war kein Problem, die Datei zu laden und im databases-Ordner der App zu speichern. Hier der Code:
Code:
        window.addEventListener('click', event => {
            if (event.target.id == 'btn-pick-db-file') {
                exportsFilepicker.pickFiles({
                    types: ['application/octet-stream'],
                    multiple: false
                }).then(result => {
                    console.log(result.files[0]);
                    Capacitor.Plugins.Filesystem.readFile({ path: result.files[0].path })
                        .then(file => {
                            console.log(file.data);
                            fetch('data:application/octet-stream;base64,' + file.data)
                                .then(res => res.blob())
                                .then(blob => {
                                    console.log(blob);
                                    window.capacitor_blob_writer({
                                        path: 'file:///data/user/0/com.substanzen.app/databases/SubstancesSQLite.db',
                                        blob: blob
                                        // fast_mode: true
                                    }).then(result => {
                                        alert('Datenbankdatei wurde erfolgreich eingelesen');
                                        displaySubstances();
                                    });
                                });
                        });
                });
            }
        });
Wie man sieht ist es ein ziemliches Drama, wenn man Capacitor verwendet, mit Binärdateien zu arbeiten. Davon abgesehen finde ich es genial, ist man mit Webentwicklung vertraut, kann man Apps entwickeln ohne in Java/Kotlin einsteigen zu müssen.
Beste Grüße, Ulrich
 
Natürlich ist es möglich eine Datei (sqlite) von der sdkarte in den eignen app speicher zu kopieren. Tipp dafür wäre SAF.
Beiträge automatisch zusammengeführt:

Einen direkten Zugriff auf den app eignen Speicher Bereich hat der User nicht. Außer das Handy ist gerooted.

Aber die App selber hat natührlich Zugriff. Wenn du also in der Abb einen Datei ex und Import anbietest. Könnte der User die Datei auch bearbeiten.
Natürlich darf er nichts an der db stucktur ändern. Denn dann wird sie in der app nicht mehr laufen.
Daten hinzufügen ist kein tehma wenn das extern geschieht. Und dann wider importiert wird.

Du hättest somit eine Backup Lösung für die DB auf auf der Sdkarte.
 
Zuletzt bearbeitet:
  • Danke
Reaktionen: Sempervivum
Natürlich ist es möglich eine Datei (sqlite) von der sdkarte in den eignen app speicher zu kopieren. Tipp dafür wäre SAF.
Danke für den Hinweis, darüber werde ich mich weiter informieren. Aber erst Mal bin ich glücklich, dass es mit dem Filepicker funktioniert.
 
Hallo @jogimuc
ich habe jetzt eine APK gebaut. Diese lässt sich installieren aber nach dem Build ist kein Verzeichnis databases mehr da. Ich könnte natürlich dieses Verzeichnis mit dem filesystem-Plugin einfach erzeugen aber habe die Befürchtung, dass es nach Beenden und Neustart wieder verschwunden ist. Trifft das zu? Oder bleibt dieses Verzeichnis und sein Inhalt, die Datenbank-Datei dann erhalten?
Beiträge automatisch zusammengeführt:

Ich könnte natürlich dieses Verzeichnis mit dem filesystem-Plugin einfach erzeugen
Habe ich jetzt getan und es funktioniert. Würde mich aber trotzdem interessieren ob es einen einfacheren Weg gibt.
 
Zuletzt bearbeitet:
Du hast sicherlich die alte apk deinstalliert. Dabei wird alles was in dem app eingnem Speicherbereich ist gelöscht. Und die db datei ist default genau in dem geschützten app eignen Speicherbereich.
Beiträge automatisch zusammengeführt:

Um welches Verzeichnis geht es denn genau?
 
Zuletzt bearbeitet:
Das ist das Verzeichnis "databases" parallel zu "files", "cache" etc. Ist Standard im Plugin für Sqlite.
Verstehe ich das jetzt richtig?
Es verschwindet wenn ich die App deinstalliere und neu installiere.
Es bleibt einschl. Inhalt erhalten wenn ich die App nur beende und neu starte.

Ich hatte mich nur gefragt, ob ich etwas machen kann, dass das Verzeichnis gleich im Build drin ist. Ist aber auch kein Drama, es neu anzulegen. Nur wenn es auch beim Neustart verschwindet wäre es unangenehm, dann müsste man jedes Mal die DB-Datei neu einlesen.
 
Sempervivum schrieb:
Es bleibt einschl. Inhalt erhalten wenn ich die App nur beende und neu starte.
Ja

Sempervivum schrieb:
Ich hatte mich nur gefragt, ob ich etwas machen kann, dass das Verzeichnis gleich im Build drin ist. Ist aber auch kein Drama, es neu anzulegen. Nur wenn es auch beim Neustart verschwindet wäre es unangenehm, dann müsste man jedes Mal die DB-Datei neu einlesen.
Deshalb kam der Vorschlag die DB in den Assets mitzugeben und beim ersten App start von den Assets in den App Speicher zu kopieren. wie gesagt nur beim ersten start der app dann nicht mehr. Den Asset Speicher kannst du nur lesen nicht schreiben deshalb Kopieren.
 
  • Danke
Reaktionen: Sempervivum
Danke für den Hinweis mit den Assets. Damit habe ich mich überhaupt noch nicht befasst. Das Verzeichnis wird jedoch automatisch beim Schreiben der Datei angelegt, so dass das Problem erst Mal gelöst ist. Nach Neuinstallation kann man ruhig das Datenbankfile schnell neu laden.
 
OK, ich bin noch sehr neu in dieser Materie und ein wenig überfordert damit, alles sofort aufzunehmen und umzusetzen.
Beiträge automatisch zusammengeführt:

BTW: Ich hatte hier:
Code:
                                    window.capacitor_blob_writer({
                                        path: 'file:///data/user/0/com.substanzen.app/databases/SubstancesSQLite.db',
                                        blob: blob
                                        // fast_mode: true
                                    }).then(result => {
noch einen gravierenden Fehler: Der absolute Pfad funktioniert auf meinem eigenen Handy aber als ein Freund die APK auf seinem installiert hat, stürzte sie ab. Habe ich mit viel Tüfteln finden und beheben können:
Code:
                                    window.capacitor_blob_writer({
                                        // path: 'file:///data/user/0/com.substanzen.app/databases/SubstancesSQLite.db',
                                        path: '../databases/SubstancesSQLite.db',
                                        blob: blob,
                                        recursive: true,
                                        directory: 'DATA',
                                        fast_mode: false
                                    }).then(result => {
 
Zuletzt bearbeitet:
Auf jedem Device müssen die Pfade zur Laufzeit ermittelt werden . je nach Hersteller / Betriebssystem sind Diese unterschiedlich.
FileIO Exceptions fängt man mit try/catch ab .
 

Ähnliche Themen

M
Antworten
3
Aufrufe
172
moin
M
netfreak
  • netfreak
Antworten
10
Aufrufe
463
netfreak
netfreak
Manny87
  • Manny87
Antworten
11
Aufrufe
167
swa00
swa00
Zurück
Oben Unten