Delphi-PRAXiS
Seite 1 von 2  1 2      

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Datenbanken (https://www.delphipraxis.net/15-datenbanken/)
-   -   SQLite unter Android (https://www.delphipraxis.net/200178-sqlite-unter-android.html)

oakley 26. Mär 2019 17:54

Datenbank: SQLite • Version: 4 • Zugriff über: Unidac

SQLite unter Android
 
Hallo zusammen,

ich spiele im Moment etwas mit Firemonkey herum und wollte eine SQLite Datenbank auf eine SD Karte packen und dann mit Unidac darauf zu greifen.
Abgesehen davon das ich Probleme habe direkt unter Windows etwas auf die Karte zu kopieren (mache das mit nem Adapter und schreibe direkt auf die Karte), welches Verzeichnis muss ich der Uniconnection angeben?
UniConnection1.Database := '/storage/sdCard/data.sqlite'; ?
Ich habe da schon etwas probiert bekomme aber immer Could not open Database.

Lg

Mirko

Rollo62 27. Mär 2019 12:16

AW: SQLite unter Android
 
Dafür brachst Du kein UniDac, es geht mit FireDac.
Und die Datei kannst Du der App per Deployment mitgeben, falls dir das etwas weiterhilft.
Auf externe Files wirst du u.U. nur begrenzt zugreifen können, weil die App in einer Sandbox lebt.
Dann wäre es eventuell besser eine DB-Datei per Internet auszutauschen.

Rollo

oakley 27. Mär 2019 12:34

AW: SQLite unter Android
 
Hallo Rollo,

Danke für die Info. Ich habe das gerade mal probiert.
Als Verzeichnis habe ich im Deployment einfach "./" gewälht.

Ich habe in der testdb.sqlite eine Tabelle namens testtab, die ich unter Windows mit SQLiteManager erzeugt habe.

Wenn ich nun die Verbindung mache bekomme ich "no table testtab". Woher kommt das?
Aber die Verbindung funktioniert jetzt.

Ich nutze folgenden Code:

UniConnection1.Database := './testdb.sqlite';
UniConnection1.Connect;

if UniConnection1.Connected = false then
ShowMessage('Keine Verbindung zur Datenbank')
else
ShowMessage('Verbunden'); <- Zeigt er so an !

UniQuery1.Close;
UniQuery1.SQL.Text := 'SELECT * from testtab';
UniQuery1.Execute; <- no such table testtab

LG

Mirko

Rollo62 27. Mär 2019 12:47

AW: SQLite unter Android
 
Du kannst versuchen einfach über Projekt\Resources und Images die Datei als Ressource anzulegen.
Das sollte normalerweise ein Deployment korrekt anlegen, auch wenn man die Resource nicht nutzt.
Der Pfad wäre dann "..\assets\internal\" wenn ich es richtig sehe.

Die Datei kann man dann wie beschrieben erreichen.
Ich würde immer erstmal mit FileExists prüfen was wo da ist.

oakley 27. Mär 2019 15:00

AW: SQLite unter Android
 
Danke für Deine Hilfe !!!

Das hat an der Resource gelegen denke ich.
Ich habe jetzt eine Verbindung und bekomme auch etwas aus der Tabelle gelesen.

Lg

Mirko

oakley 1. Jul 2019 13:27

AW: SQLite unter Android
 
Ich wollte nicht noch ein neues Thema starten weil es im Prinzip noch um die gleiche Sache geht.
Die Verbindung zu SQLite funktioniert jetzt einwandfrei mit Unidac.

Ich verwende aktuell beim onClick Event eines Buttons:

Code:

  UniConnection1.Database := TPath.Combine(TPath.GetDocumentsPath, 'testdb.sqlite');

  if UniConnection1.Connected = false then UniConnection1.Connect;
Wenn ich das gleiche nun im onCreate des Formulars mache blockiert die App.

Weil jemand woran das liegt?

LG

Mirko

mkinzler 1. Jul 2019 13:49

AW: SQLite unter Android
 
Verwende ein DataModule, welches dann als erstes erzeugt wird.

Rollo62 1. Jul 2019 13:54

AW: SQLite unter Android
 
Zitat:

Zitat von oakley (Beitrag 1435728)
Wenn ich das gleiche nun im onCreate des Formulars mache blockiert die App.

Am Besten legst Du alle zeitaufwändigen Operationen in OnShow der Form, im OnCreate könnte Android dich rauswerfen wenn der Thread zu lange blockiert.
Ich lege mir teilweise diese Operationen zeitversetzt in Funktionen nach OnShow, damit schonmal die App startet,
und eventuelle Datenoperationen können im Hintergrund, später erfolgen.

Ach ja, der Tipp mit DatenModulen bleibt davon natürlich unberührt, da gilt das Gleiche.

oakley 1. Jul 2019 14:18

AW: SQLite unter Android
 
Super onShow funktioniert es mit UniConnection1.Connect;
Wenn ich allerdings danach einen SELECT mache ist schon wieder Ende, die App blockt.

Code:
if UniConnection1.Connected then
begin
  UniQuery1.Close;
  UniQuery1.SQL.Text := 'SELECT * from testtable';
  UniQuery1.Execute;

  while not UniQuery1.EOF do
  begin
    TMSFMXGrid1.RowCount := TMSFMXGrid1.RowCount + 1;
    TMSFMXGrid1.Cells[0,TMSFMXGrid1.RowCount-1] := UniQuery1.FieldByName('test1').AsString;
    TMSFMXGrid1.Cells[1,TMSFMXGrid1.RowCount-1] := UniQuery1.FieldByName('test2').AsString;
    UniQuery1.Next();
  end;
end;
Wieso macht er den Connect aber die Abfrage schafft er dann nicht mehr?

Rollo Du schreibst Du legst Dir die Aktionen zeitversetzt. Machst Du das mit Timern?

LG

Mirko

Rollo62 1. Jul 2019 14:58

AW: SQLite unter Android
 
Ich arbeite jetzt weder mit UniDacx, noch mit TMS, aber es müsste so etwas in der Art wie unten dort geben um das UI-Update beim Zeicnen zu verhindern, so das erst nach dem ganzen Update der Screen upgedatet wird.
Das s.u. könnte das Problem erklären wenn Du schon sehr viele Datensätze in der DB hast.

Zitat:

Zitat von oakley (Beitrag 1435741)
Super onShow funktioniert es mit UniConnection1.Connect;
Code:
    TMSFMXGrid1.BeginUpdate;
    UniQuery1.ControlsDisable; // Kenne UniDac nicht, müsste es aber geben
    try

   
    finally
        UniQuery1.ControlsEnable;
        TMSFMXGrid1.EndUpdate;
    end;

Ob dein Ansatz mit Execute funktioniert bei UniDac habe ich nicht gecheckt, aber Du köntest stattdessen einfach UniQuery1.Active := True; setzen, es könnte aber auch alles Mögliche bei der Konfiguration in die Hose gehen.

Wenn die DB noch leer ist würde ich erstmal debuggen bis zu welcher Stelle Du kommst, um festzustellen was genau jetzt nicht geht.

Zitat:

Rollo Du schreibst Du legst Dir die Aktionen zeitversetzt. Machst Du das mit Timern?
Im Prinzip ja, ich habe mir da aber eine bequeme, threadsichere Klasse drumrum gekapselt.
Mit dieser Klasse kann ich eine anonyme Prozedur aufrufen, die dann mit einem Delay aufgerufen wird um Timings zu erzeugen.

Im Prinzip gibt es für solche Zwecke auch den TIdleWorker von Sir Rufo, ich hatte damit allerdings irgendwann mal ein Problem unter Android, dass die IdleMessages nicht aufgerufen wurden, seitdem bin ich wieder auf die Timerversion umgestiegen.
Trat immer nur selten und sporadisch auf, musste aber deswegen von dem IdleWorker wieder Abstand nehmen.
Eigentlich sollte der TIdleWorker aber super funktionieren, ich habe ihn nur danach nicht mehr getestet
(guter Hinweis das ich mir das nochmal auf die ToDo Liste schreibe :stupid:).


Alle Zeitangaben in WEZ +1. Es ist jetzt 09:02 Uhr.
Seite 1 von 2  1 2      

Powered by vBulletin® Copyright ©2000 - 2024, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024 by Thomas Breitkreuz