android sqlite introT8_wowomnom_Fotolia_85154667

Android SQLite Datenbank Tutorial – Teil 8: SQLite Datenbank Upgrade in Android


In der achten Lektion unseres mehrteiligen Android SQLite Tutorials werden wir die Entwicklung an unserer Einkaufslisten-App abschließen. Wir fügen der SQLite App eine Durchstreichen-Funktion hinzu.

Die User sollen Listeneinträge abhaken können, wenn sie kurz auf ein Element des ListViews klicken. Wir ein Listeneintrag abgehakt, dann lassen wir den Text des zugehörigen TextViews durchstreichen und ausgrauen.

Ob ein Eintrag abgehakt ist oder nicht, möchten wir in unserer SQLite Datenbank speichern. Um dies zu realisieren, müssen wir alle Klassen unseres Android Projekts überarbeiten.

Wir werden an den Klassen folgende Änderungen vornehmen:

  1. ShoppingMemo – Diese Klasse ist unser Datenmodell und repräsentiert einen Datensatz der SQLite Datenbank. Wir fügen in sie ein weiteres Attribut ein, mit dem wir den Status der jeweiligen ShoppingMemo als checked oder not checked speichern.
  2. ShoppingMemoDbHelper – Sie ist eine Hilfsklasse mit deren Hilfe wir die SQLite Datenbank erstellen lassen. Sie enthält weiterhin wichtige Konstanten, die wir für die Arbeit mit der Datenbank benötigen, wie den Tabellennamen, die Datenbankversion oder die Namen der Spalten. Wir fügen ihr eine weitere Spalte hinzu und implementieren ihre onUpgrade() Methode, um die SQLite Datenbank neu zu erstellen.
  3. ShoppingMemoDataSource – Diese Klasse ist unser Data Access Object und für das Verwalten der Daten verantwortlich. Sie unterhält die Datenbankverbindung und ist für das Hinzufügen, Auslesen und Löschen von Datensätzen zuständig. Wir nehmen in dieser Klasse Änderungen an den Methoden updateShoppingMemo() und cursorToShoppingMemo() vor.
  4. MainActivity – Von dieser Klasse aus, steuern wir unsere SQLite App. Wir fügen ihrem ListView einen OnItemClickListener zu, um damit auf kurze Klicks zu reagieren.

Im theoretischen Teil dieser Lektion werden wir uns mit der onUpgrade() der DbHelper-Klasse beschäftigen. Dabei werden wir zeigen, wie ein SQLite Datenbank Upgrade durchgeführt wird.

Am Ende der achten Lektion unseres Android SQLite Tutorials werden wir unsere App auf einem Android Gerät installieren und testen. Dabei werden wir auch wieder die Log-Meldungen analysieren und in einem kleinen Video die neue Funktion präsentieren.

Nun wünschen wir euch viel Spaß beim achten Teil unseres Android SQLite Datenbank Tutorials. Los geht’s!

1. SQLite Datenbank Upgrade in Android durchführen

Der SQLite Datenbank Upgrade ist recht unkompliziert. Damit wir unsere ShoppingMemoDbHelper-Klasse von der SQLiteOpenHelper-Klasse ableiten konnten, mussten wir die beiden Methoden onCreate() und onUpgrade() überschreiben.

Die onCreate() Methode wird nur aufgerufen, falls die SQLite Datenbank noch nicht existiert.

Die onUpgrade() Methode wird aufgerufen, sobald die neue Versionsnummer höher als die alte Versionsnummer ist und somit ein Datenbank-Upgrade notwendig wird.

Wir müssen daher die onUpgrade() Methode implementieren und in ihr den SQLite Datenbank Upgrade ausführen. Dafür gibt es verschiedene Ansätze. Man kann die bereits vorhandene Tabelle verändern mit dem SQL-Befehl alter und dadurch sicherstellen, dass keine Daten verloren gehen.

Da wir bisher aber nur Testdaten in unserer SQLite Datenbank gespeichert haben, werden wir einen anderen Ansatz wählen. Wir werden die bisherige Tabelle löschen und anschließend eine neue Tabelle mit vier anstelle der bisherigen drei Spalten erzeugen.

Dazu werden wir den folgenden Quellcode verwenden:


Mit den oberen Zeilen wird das SQLite Datenbank Upgrade durchgeführt, sobald die Versionsnummer der SQLite Datenbank erhöht wurde. Mit der Anweisung in Zeile 4 lassen wir die alte Tabelle aus der SQLite Datenbank entfernen.

Anschließend rufen wir in Zeile 5 die onCreate() Methode auf und lassen dadurch eine neue Tabelle erzeugen. Damit auch wirklich eine neue Tabelle in der SQLite Datenbank erzeugt wird, müssen vorher noch einige Konstanten der ShoppingMemoDbHelper-Klasse verändert werden. Welche das sind werden wir im dritten Abschnitt ausführlich besprechen.

2. Ein neues Attribut in der ShoppingMemo-Klasse anlegen

Um den Status der ShoppingMemo, also ob der jeweilige Einkaufslisten-Eintrag abgehakt ist oder nicht, speichern zu können, müssen wir ein zusätzliches Attribut in der ShoppingMemo-Klasse anlegen.

Die neue Instanzvariable soll den Namen checked tragen und vom Datentyp boolean sein. Um die Membervariable zu initialisieren, müssen wir auch den bisherigen Konstruktor anpassen.

Außerdem müssen wir die Get- und Set-Methoden der Membervariable definieren, damit wir den Wert des Attributs auslesen und festlegen können.

Die eben aufgezählten Änderungen werden wir nun an der ShoppingMemo-Klasse vornehmen. Dazu öffnen wir die Klassendatei ShoppingMemo.java im Editorfenster von Android Studio über einen Klick auf den entsprechenden Eintrag in der linken Projektleiste.

Anschließend fügen wir den gelb markierten Quellcode in die ShoppingMemo-Klasse ein:


Der eingefügte Quellcode ist selbsterklärend. Die neue Instanzvariable checked wird den Status der jeweiligen ShoppingMemo speichern. Der Wert true wird für abgehakt stehen, also dass das entsprechende Produkt gekauft wurde.

In Android Studio sollte die Klasse ShoppingMemo nun wie folgt aussehen:

android sqlite shopping memo

Die überarbeitete Klasse ShoppingMemo mit Markierungen

Da unser Datenmodell nun über eine neue Eigenschaft verfügt, repräsentiert es nicht mehr die Datensätze unserer bisherigen SQLite Datenbank. Dieses Problem müssen wir als Nächstes beheben und die Vorbereitungen für das SQLite Datenbank Upgrade treffen. Dazu nehmen wir Anpassungen an unserer Hilfsklasse ShoppingMemoDbHelper vor.

3. Die ShoppingMemoDbHelper-Klasse für den SQLite Datenbank Upgrade vorbereiten

An unserer Hilfsklasse ShoppingMemoDbHelper müssen wir nun einige Änderungen vornehmen, da sich das zugrunde liegende Datenmodell geändert hat.

Unsere ShoppingMemo besitzt nun vier Attribute, ein Datensatz unserer Tabelle aber nur drei Spalten.

Wir müssen daher die alte Tabelle aus der SQLite Datenbank entfernen und eine neue Tabelle, die vier Spalten besitzt, erstellen lassen.

Um dies zu realisieren, werden wir die folgenden Änderungen vornehmen:

  1. Erhöhen der Datenbank Versionsnummer – Konstante DB_VERSION von 1 auf 2 erhöhen.
  2. Definieren einer neuen Spalte – Neue Konstante COLUMN_CHECKED als vierte Spalte anlegen.
  3. Erweitern des Create-Befehls – Die Konstante SQL_CREATE erweitern, so dass durch sie nun eine Tabelle mit vier Spalten erzeugt wird.
  4. Definieren eines Drop-Befehls – Anlegen der neuen Konstante SQL_DROP, mit deren Hilfe die alte Tabelle aus der SQLite Datenbank gelöscht wird.
  5. Implementieren der onUpgrade() Methode – In der onUpgrade() Methode lassen wir die alte Tabelle entfernen und eine neue Tabelle mit vier Spalten erstellen.

In dem unten angegebenen Quellcode sind die oben aufgezählten Änderungen bereits vorgenommen worden. Die in der ShoppingMemoDbHelper-Klasse durchgeführten Änderungen sind gelb markiert.


In Android Studio sollte die Klasse ShoppingMemoDbHelper nun wie folgt aussehen:

android sqlite db helper column

Die überarbeitete Klasse ShoppingMemodBHelper mit Markierungen

In der oberen Abbildung sind die fünf Änderungen mit blauen Linien bzw. Rahmen markiert. Die Nummerierung entspricht der Aufzählung der Änderungen zu Beginn dieses Abschnitts.

Mit den nun vorgenommenen Änderungen an der DbHelper-Klasse haben wir unsere SQLite App für den Datenbank Upgrade vorbereitet. Würden wir nun unsere Anwendung ausführen, dann würde die SQLiteOpenHelper-Klasse anhand der erhöhten Versionsnummer erkennen, dass ein Datenbank Upgrade notwendig ist und die onUpgrade() Methode aufrufen.

Bevor wir jedoch unsere Android App starten können, müssen wir noch Änderungen an den restlichen beiden Klassen unseres Projekts vornehmen. Als Nächstes nehmen wir uns die Klasse ShoppingMemoDataSource vor und im Anschluss daran die MainActivity-Klasse.

4. Die ShoppingMemoDataSource-Klasse anpassen

Unsere Datenquelle müssen wir nun auch an die neue Tabellenstruktur anpassen. Betroffen sind die beiden Methoden updateShoppingMemo() und cursorToShoppingMemo(), sowie die Variable columns.

Wir öffnen die Klassendatei ShoppingMemoDataSource.java im Editorfenster von Android Studio über einen Klick auf den entsprechenden Eintrag in der linken Projektleiste.

Anschließend fügen wir den gelb markierten Quellcode in die ShoppingMemoDataSource-Klasse ein:


Mit der ersten Änderung im oberen Quellcode fügen wir dem String-Array columns ein weiteres Element, die neue Spalte, hinzu. Die neue Spalte fügen wir in Zeile 25 dem Array hinzu.

Anschließend überarbeiten wir die updateShoppingMemo() Methode. Wir erweitern ihre Parameterliste um einen vierten Parameter vom Datentyp boolean. Da die SQLite Datenbank diesen Datentyp nicht kennt, wandeln wir ihn mit der Anweisung in Zeile 73 in einen int-Wert um.

Diesen int-Wert fügen wir in Zeile 78 der ContentValues-Variable hinzu und legen ihn darin mit dem neuen Spaltennamen als Schlüssel ab. Somit werden ab jetzt drei Werte plus die ID in die Tabelle der SQLite Datenbank geschrieben.

Weitere Änderungen nehmen wir nicht an der updateShoppingMemo() Methode vor.

Als letzte Änderung im Quellcode passen wir die Methode cursorToShoppingMemo() an. In Zeile 100 fragen wir den Spaltenindex der neuen Spalte beim Cursor-Objekt an. Anschließend lesen wir in Zeile 105 den Wert der vierten Spalte im übergebenen Datensatz aus.

Da dieser Wert aber vom Datentyp int ist, wandeln wir ihn mit der Anweisung in Zeile 107 in einen boolean-Wert um. Jetzt können wir mit den ausgelesenen Datenbankwerte ein ShoppingMemo-Objekt erzeugen lassen. Wir müssen dazu aber noch Zeile 109 ändern und den Konstruktor der Klasse ShoppingMemo mit vier Argumenten aufrufen.

In Android Studio sollte die Klasse ShoppingMemoDataSource nun folgendermaßen aussehen:

android sqlite shopping memo data source

Die überarbeitete Klasse ShoppingMemoDataSource mit Markierungen

Jetzt haben wir alle notwendigen Änderungen an der Klasse ShoppingMemoDataSource durchgeführt. Unsere Datenquelle beachtet nun die neue Tabellenstruktur.

Als Nächstes nehmen wir umfassende Erweiterungen an unserer MainActivity-Klasse vor. Dies werden auch die letzten Änderungen an den Dateien unseres SQLite Projekts sein.

5. Erweitern der MainActivity-Klasse

Nun kommen wir zu den größten Änderungen bzw. Erweiterungen des Quellcodes. Wir werden in der Klasse MainActivity für unseren ListView einen OnItemClickListener registrieren. Mit dem Listener werden wir auf kurze Klicks auf die Listeneinträge reagieren und diese dann durchstreichen.

Um dies zu realisieren, nehmen wir die folgenden Änderungen am Quellcode der Klasse MainActivity vor:

  1. Einfügen der Import-Anweisungen – Zuerst importieren wir die benötigten Klassen.
  2. Deklarieren des ListViews als Membervariable – Anschließend werden wir die Membervariable mShoppingMemosListView deklarieren, so dass wir in den Methoden darauf zugreifen können.
  3. Überarbeiten der onCreate() Methode – Wir fügen in diese Methode eine Anweisung ein und zwar den Aufruf der initializeShoppingMemosListView() Methode, die wir im nächsten Arbeitsschritt definieren.
  4. Definieren der initializeShoppingMemosListView() Methode – Wir definieren eine neue Methode, die den ListView initialisiert und für ihn einen OnItemClickListener registriert.
  5. Überarbeiten der showAllListEntries() Methode – Bisher haben wir in dieser Methode den ArrayAdapter immer wieder neu erstellt, um neue Daten anzuzeigen. Dies verbessern wir nun, indem wir nicht mehr den ganzen Adapter löschen, sondern nur seinen Inhalt und ihm anschließend die neuen Daten zuweisen.
  6. Kleine Anpassung der createEditShoppingMemoDialog() Methode – Als letzten Arbeitsschritt passen wir den Methodenaufruf updateShoppingMemo() an. Wir übergeben der Methode nun vier anstelle der bisherigen drei Argumente.

Am Ende dieses Abschnitts haben wir nochmals den kompletten Quellcode der MainActivity-Klasse aufgeführt. Falls ihr bei den folgenden Schritten durcheinander kommt, könnt ihr ihn zur Kontrolle bzw. Orientierung nutzen.

Nun beginnen wir mit dem ersten Arbeitsschritt.

5.1 Einfügen der Import-Anweisungen

Wir öffnen als Erstes die Klassendatei MainActivity.java im Editorfenster von Android Studio über einen Klick auf den entsprechenden Eintrag in der linken Projektleiste.

Anschließend fügen wir den folgenden Quellcode unter den bereits vorhandenen Import-Anweisungen ein:


5.2 Deklarieren des ListViews als Membervariable

Nun legen wir die Membervariable mShoppingMemosListView im Variablenbereich der MainActivity-Klasse an. In der Variable speichern wir eine Referenz die auf unser ListView-Objekt verweist.

Wir fügen nun folgende Zeile in die Klasse MainActivity ein:


5.3 Überarbeiten der onCreate() Methode

Nun fügen wir in die onCreate() Methode der MainActivity den Methodenaufruf initializeShoppingMemosListView() ein. Die aufzurufende Methode werden wir im nächsten Arbeitsschritt definieren, sie wird das ListView-Objekt initialisieren.

Wir fügen nun die gelb markierte Zeile in die Methode onCreate() der Klasse MainActivity ein:


5.4 Definieren der initializeShoppingMemosListView() Methode

Im vierten Arbeitsschritt definieren wir die Methode initializeShoppingMemosListView(), die für uns den ListView initialisieren wird. Die neue Methode erstellt einen ArrayAdapter, weist diesen dem ListView zu und registriert einen OnItemClickListener für den ListView.

Dazu fügen wir den folgenden Quellcode in den Methodenbereich der MainActivity-Klasse ein.


Mit dem oberen Quellcode realisieren wir drei Dinge:

  1. Erstellen eines ArrayAdapters – Mit den Zeilen 7 bis 33 legen wir den ArrayAdapter an und überschreiben seine getView() Methode. Die getView() Methode wird immer dann aufgerufen, wenn ein Listeneintrag gezeichnet werden muss. In dieser Methode verändern die die Eigenschaften des TextView-Elements, mit welchem wir die jeweiligen SQLite Datenbankeinträge anzeigen. Wir prüfen, ob der entsprechende Datenbankeintrag abgehakt ist, also ob das Attribut checked den Wert true besitzt. Ist dies der Fall, streichen wir den Text durch und ändern die Schriftfarbe in ein helles Grau. Ist der Wert false, dann geben wir den Text normal aus.
  2. ArrayAdapter an den ListView binden – Anschließend binden wir den erzeugten ArrayAdapter mit der Anweisung in Zeile 35 an unseren ListView.
  3. Registrieren eines OnItemClickListener für den ListView – Damit wir auf kurze Klicks auf Listeneinträge reagieren können, registrieren wir mit den Zeilen 37 bis 48 einen OnItemClickListener für unseren ListView. In dem Listeners kehren wir den Status des angeklickten Listeneintrags um. Wir fragen dazu das angeklickte ShoppingMemo-Objekt an und setzen anschließend den checked-Wert neu. Den alten Wert kehren wir dafür um. Anschließend lassen wir den ListView neu zeichnen.

5.5 Überarbeiten der showAllListEntries() Methode

Als nächste Änderung werden wir die Methode showAllListEntries() überarbeiten. In ihr fragen wir alle Einträge aus der SQLite Datenbank an und übergeben die ausgelesenen Daten an den ArrayAdapter. Anschließend weisen wir über den ArrayAdapter unseren ListView an, sich neu zu zeichnen.

Wir löschen dazu unsere bisherige showAllListEntries() Methode im Methodenbereich der MainActivity-Klasse und ersetzen sie mit folgendem Quellcode:


5.6 Kleine Anpassung der createEditShoppingMemoDialog() Methode

Als letzte Änderung nehmen wir eine Anpassung am Aufruf der updateShoppingMemo() Methode in der Methode createEditShoppingMemoDialog() vor. Dies müssen wir tun, da die Methode updateShoppingMemo() jetzt 4 Argumente erwartet, anstelle der bisherigen drei.

Wir passen nun die gelb markierte Zeile in der Methode createEditShoppingMemoDialog() der Klasse MainActivity an:


5.7 Der komplette Quellcode der MainActivity-Klasse

Nun haben wir alle Änderungen an der MainActivity-Klasse vorgenommen.

Mit dem eingefügtem Quellcode reagieren wir auf kurze Klicks des Benutzers und ändern das Aussehen des angeklickten Listeneintrags.

In dem unten angegebenen Quellcode ist die gesamte MainActivity-Klasse zur Kontrolle für euch aufgeführt. Die neu eingefügten Zeilen sind gelb markiert.

Der vollständiger Quelltext der Klasse MainActivity:


Mit den beschriebenen Änderungen sollte die Klasse MainActivity nun wie folgt in Android Studio aussehen:

android sqlite mainactivity column

Die überarbeitete Klasse MainActivity mit Markierungen

In der oberen Abbildung sind die in den sechs Arbeitsschritten vorgenommenen Änderungen mit einem blauen Rahmen markiert. Neben den Rahmen ist jeweils ein nummeriertes Kästchen angeordnet. Die Nummerierung entspricht der Nummerierung der oben aufgezählten Arbeitsschritte.

Im nächsten Abschnitt werden wird unsere SQLite App testen und Einträge der Einkaufsliste und somit auch der hinterlegten SQLite Datenbank durchstreichen.

6. Starten und Testen unserer SQLite App

In diesem Abschnitt werden wir unsere Android App ausführen und überprüfen, ob der SQLite Datenbank Upgrade korrekt ausgeführt wird.

Dazu werden wir zunächst die Anwendung auf einem Android Gerät ausführen und anschließend die zurückgelieferten Log-Meldungen in Android Studio analysieren. Zusätzlich prüfen wir auch, ob die Einträge korrekt in dem ListView der MainActivity abgehakt werden können.

6.1 Ausführen der Android SQLite-App

Nun wollen wir unsere App ausführen und testen. Dazu installieren wir die Anwendung auf unser angeschlossenes Android Gerät (Smartphone oder Tablet) oder in einer AVD des Android Emulators.

Wie eine Android App installiert wird, könnt ihr in den folgenden beiden Teilen unseres großen Android App Programmieren Tutorials nachlesen:

Hier noch einmal in Kürze die wichtigsten Arbeitsschritte.

Zuerst schließen wir unser Android Gerät an den PC an und stellen eine Verbindung über die ADB (Android Debug Bridge) her. Danach klicken wir auf das Run 'app'-Symbol. Unser Android Projekt wird dadurch neu erstellt und auf dem angeschlossenen Gerät ausgeführt.

Das Run 'app'-Symbol befindet sich in der oberen Menüleiste, siehe folgende Abbildung:

android sqlite app starten

Android App über das Run App-Symbol starten

Nach einigen Momenten öffnet sich der Choose Device-Dialog. In ihm nehmen wir die folgenden Einstellungen vor:

  1. Radio Button Choose a running device aktivieren
  2. Das angeschlossene Android Gerät auswählen
  3. Mit einem Klick auf den OK-Button die Installation unserer App auf das Gerät starten
android choose device

Auswählen des angeschlossenen Android Geräts zum Aufspielen unserer App

Der Dialog schließt sich und unsere Android App wird auf das angeschlossene Gerät übertragen und installiert. Die Installation dauert nur einen kurzen Augenblick und verläuft fast unbemerkt im Hintergrund. Danach wird unsere App automatisch gestartet.

6.2 Überprüfen der Log-Meldungen in Android Studio

Unsere SQLite-App sollte jetzt auf dem Android Gerät gestartet worden sein.

Um die Log-Meldungen zu überprüfen, öffnen wir in Android Studio die Android-Ansicht bei angeschlossenem Android Gerät.

In der unteren Abbildung sind die Log-Meldungen direkt nach dem Starten unserer Android App dargestellt. Der in Lektion 2 angelegte Log-Filter ist aktiviert (rote Markierung X). Unsere Meldungen werden im logcat-Textbereich angezeigt.

android sqlite log new table

Die Log-Meldungen in Android Studio mit aktivem Log-Filter – Das SQLite Datenbank Upgrade wurde durchgeführt

Uns werden die folgenden Log-Meldungen ausgegeben:

01: MainActivity﹕ Das Datenquellen-Objekt wird angelegt.
02: ShoppingMemoDataSource﹕ Unsere DataSource erzeugt jetzt den dbHelper.
03: ShoppingMemoDbHelper﹕ DbHelper hat die Datenbank: shopping_list.db erzeugt.
04: MainActivity﹕ Die Datenquelle wird geöffnet.
05: ShoppingMemoDataSource﹕ Eine Referenz auf die Datenbank wird jetzt angefragt.
06: ShoppingMemoDbHelper﹕ Die Tabelle mit Versionsnummer 1 wird entfernt.
07: ShoppingMemoDbHelper﹕ Die Tabelle wird mit SQL-Befehl: CREATE TABLE shopping_list(_id INTEGER PRIMARY KEY AUTOINCREMENT, product TEXT NOT NULL, quantity INTEGER NOT NULL, checked BOOLEAN NOT NULL DEFAULT 0); angelegt.
08: ShoppingMemoDataSource﹕ Datenbank-Referenz erhalten. Pfad zur Datenbank: /data/data/de.programmierenlernenhq.shoppinglisthq/databases/shopping_list.db
09: MainActivity﹕ Folgende Einträge sind in der Datenbank vorhanden:

Die meisten Log-Meldungen sind bereits bekannt. Neu sind die beiden Meldungen 06 und 07, die über den durchgeführten SQLite Datenbank Upgrade informieren.

Die alte Tabelle wir aus der SQLite Datenbank entfernt und eine neue Tabelle mit dem oben aufgeführten SQL-Befehl erstellt. Wir können auch erkennen, dass die vierte Spalte vom Datentyp boolean sein soll und den Standardwert 0 für jeden neuen Eintrag besitzt.

Der Standardwert ist nicht false, da die SQLite Datenbank keinen echten boolean Datentyp beherrscht, sondern dafür die Integer-Zahlen 0 und 1 verwendet.

In der unteren Abbildung ist das Vorgehen für das Durchstreichen eines ListView-Eintrags in unserer App dargestellt:

android sqlite column

Einträge aus der SQLite Datenbank im ListView durchstreichen (abhaken)

Ein Video veranschaulicht das Abhaken von Listeneinträgen aber viel besser als ein Bild. Daher haben wir eine kleine Funktionspräsentation unserer SQLite App in Form eines Videos erstellt.

6.3 Video – Funktionspräsentation unserer SQLite App

In dem unteren Video haben wir einen Eintrag aus dem ListView abgehakt und dadurch durchgestrichen. In der SQLite Datenbank wird dabei der Wert in der vierten Spalte entsprechend geändert. Im Video ist zu sehen, wie das Abhaken der Listeneinträge funktioniert.

Mit dieser weiteren Funktion ist die Einkaufslisten-App nun abgeschlossen und kann im Alltag verwendet werden. Es können natürlich noch zusätzliche Funktionen eingebaut werden, wie bspw. das Anlegen von verschiedenen Einkaufslisten.

Zusammenfassung

In diesem letzten Teil unseres Android SQLite Tutorials haben wir noch einmal Veränderungen an allen Klassen unseres Projekts vorgenommen. Dies war notwendig, da wir die Datenstruktur erweitert haben.

Wir haben folgende Änderungen durchgeführt:

  1. Erweitern der ShoppingMemo-Klasse um ein zusätzliches Attribut.
  2. Vorbereiten der ShoppingMemoDbHelper-Klasse für den SQLite Datenbank Upgrade.
  3. Anpassen der ShoppingMemoDataSource-Klasse an die neue Datenstruktur der SQLite Datenbank und des Datenmodells.
  4. Erweitern der MainActivity-Klasse um einen OnItemClickListener, mit dessen Hilfe wir Einträge des ListViews abhaken (durchstreichen) können.

Nun sind wir am Ende des SQLite Tutorials angelangt. Wir hoffen es hat bei euch alles so wie beschrieben funktioniert und ihr hattet Spaß bei der Entwicklung einer Android SQLite App.

Vielen Dank für euer Durchhaltevermögen und viel Erfolg bei euren zukünftigen Android Projekten.


Comments 25

  1. Kevin

    Hallo,
    ich habe mit dem Code

    Folgenden Fehler:

    Error:(110, 37) error: constructor ShoppingMemo in class ShoppingMemo cannot be applied to given types;
    required: String,int,long
    found: String,int,long,Boolean
    reason: actual and formal argument lists differ in length

    Irgendeine Idee ?
    Das Tut ist nebenbei echt sehr gut erzählt, vielen Dank für die Mühe und Arbeit!

    MfG Kevin

    1. Post
      Author
      Chris

      Hallo Kevin,

      Deine Fehlermeldung weist auf ein Problem mit dem Konstruktor der ShoppingMemo-Klasse hin. In Deinem Quellcode ist ein entsprechender Konstruktor mit 3 Parametern vorhanden, es wird aber ein Konstruktor mit 4 Parametern benötigt.

      In Schritt 2 von Teil 8 haben wir den Konstruktor der Klasse ShoppingMemo.java um einen vierten Parameter erweitert, von:

      hin zu:

      Vielleicht hast Du diesen Schritt übersprungen oder es hat sich ein kleiner Tippfehler in Deinem Quellcode eingeschlichen.

      Außerdem sollte die Variable isChecked vom primitiven Typ boolean sein. In Deinem Quellcode ist sie vom Objekt-Typ Boolean (java.lang.Boolean).

      Viele Grüße, Chris

      1. Kevin

        Hallo Chris,

        Vielen Dank für die schnelle Antwort, ein Semikolon hatte gefehlt, beim erneuten hinschauen viel es mir dann auf, vielen dank.

        Ist es möglich eine Datenbank online zu speichern und abzurufen ?

        Vielen Dank für die Hilfe
        MfG Kevin

        1. Post
          Author
          Chris

          Hallo Kevin,

          schön wenn es jetzt funktioniert.

          Ja es ist möglich auf eine online Datenbank zuzugreifen. Man benötigt dafür einen Server auf dem die Datenbank ausgeführt wird und eine Schnittstelle über die man vom Android Gerät auf die Datenbank zugreifen kann. Als Anfrage-Ergebnisse kann man sich XML oder JSON Daten liefern lassen und diese in der App dann weiterverarbeiten.

          Viele Grüße, Chris

  2. Norbert Schomborg

    Hallo Chris, was du auf deiner Seite anbietest ist aussergewöhnlich. Für einen Android- Anfänger wie mich (73) mit einiger Erfahrung in PASCAL ist das Projekt ziemlich anspruchsvoll, aber ich habe mich durchgekämpft.Was ich nicht geschafft habe: ich will die erzeugte SQLITE-Datei von außen mit einem DB-Drowser manipulieren. Leider gelingt es mir nicht , diese Datei im Projekt zu finden, ich finde schon den Pfad nicht. Wenn du mir da helfen könntest, fiele mir die beabsichtigte Spende noch leichter !
    Nochmals danke ! Norbert

    1. Post
      Author
      Chris

      Hallo Norbert,

      danke für Deine lobenden Worte!

      Es gibt mehrere Wege, um an die Datenbank einer Android App zu gelangen.

      Wenn man die App auf dem Emulator in einem AVD ausführt, kann man mit Hilfe des Android Device Monitors zur Datenbankdatei navigieren und die Datei dann mit “Pull a file from the device” vom AVD herunterladen und auf der Festplatte speichern.

      Um dies zu tun, führt man zuerst die App auf dem AVD aus und startet anschließend den Android Device Manager (ADM) in Android Studio über Tools>Android>Android Device Manager. Im ADM wählt man als Device den Emulator aus und klickt danach auf den Reiter File Explorer. Dort kann man frei in dem Dateisystem des Android Virtual Devices navigieren. Die Datenbank liegt in dem Ordner data/data/de.programmierenlernenhq.shoppinglisthq/databases und trägt den Namen shopping_list.db.

      Die Datei wird nun ausgewählt und kann dann mit Hilfe des Buttons “Pull a file from the device” auf die Festplatte kopiert werden. Der Button ist rechts oben im ADM-Fenster angebracht und sieht aus wie eine Diskette mit einem lila Pfeil (der nach links zeigt).

      Die überarbeitete Datenbankdatei kann auf diesem Wege auch wieder aus das AVD kopiert werden. Dazu muss der Button “Push a file onto the device” rechts daneben verwendet werden.

      Möchte man die Datenbankdatei von einem physischen Android Gerät laden, geht der eben beschriebene Weg leider nicht, da man keine Leserechte auf die “data”-Verzeichnisse besitzt. Um dennoch auf die Datei zugreifen zu können, kann man sich die Datei auf eine SD Karte kopieren lassen. Bei StackOverflow.com gibt es dazu einige erfolgversprechende Anleitungen zu finden, bspw. hier: location of sqlite database on the device

      Man kann scheinbar die Datenbank auch direkt auf der SD-Karte erzeugen lassen. Ich habe dies aber noch nicht selbst ausprobiert. Der Quellcode könnte wie folgt aussehen:

      Ich hoffe meine Ausführungen helfen Dir etwas weiter und wünsche noch viel Freude bei der Android Programmierung :)

      Viele Grüße, Chris

    1. Post
      Author
  3. Amir

    Hallo lieber Chris,

    Dankeschön für so einen tollen Beitrag, das hat mir wirklich mit Begeisterung geholfen. Bleibe gesund!

    Gruß aus Berlin

    Amir

    1. Post
      Author
      Chris

      Hallo Amir,

      Danke für Dein Lob! Es freut mich sehr, wenn der Beitrag hilfreich und zugleich interessant war.

      Viele Grüße, Chris

  4. Rob

    Hi, sehr gutes Tutorial!
    Hat mir sehr weiter geholfen :)

    Ich möchte nun eine weitere Tabelle anlegen, die die gleiche Struktur wie die erste besitzt. Wie kann ich das am einfachsten machen, ohne DataSource, Helper und Entry neu anlegen zu müssen?

    Viele Grüße und weiter so!

    1. Post
      Author
      Chris

      Hallo Rob,

      in der Helper-Klasse einfach eine neue Tabelle definieren (Tabellenname als Konstante, SQL-Create Anweisung, in onCreate() die Tabelle erstellen lassen) und nicht vergessen die DB-Version um 1 zu erhöhen.

      In der DataSource-Klasse dann die benötigten zusätzlichen Methoden, die mit der neu angelegten Tabelle (mittels Tabellennamen) arbeiten, implementieren und von der Activity wie gehabt auf die DataSource-Methoden zugreifen.

      Viele Grüße, Chris

  5. Wilfried

    Hallo Chris,

    ich bin begeistert. Mir geht es ähnlich, wie deinem Fan Norbert Schomburg. Ich habe die 66 auch schon überschritten und mich an die Android-Programmierung gewagt. Dank deines ausgezeichneten Tutorials habe ich die App sogar auf meinem SAMSUNG Galaxy S5 zum Laufen gebracht. Jetzt würde ich nur noch wissen wollen, wie man die Checkbox mit einem Häkchen füllen bzw. wieder leeren kann.

    Hast du da einen Tipp?

    1. Post
      Author
      Chris

      Hallo Wilfried,

      danke für Dein Lob!

      Im SQLite-Tutorial nehmen wir für die Checkboxen ein Standardlayout (simple_list_item_multiple_choice). Damit ist es schwierig zu erklären, wie eine Checkbox in Android funktioniert.

      Ich habe mich mal im Web umgesehen und ein sehr anschauliches Tutorial gefunden, das Checkboxen im Detail behandelt. Auch der Beitrag auf der Android Developer Seite ist zu empfehlen.

      https://www.mkyong.com/android/android-checkbox-example/
      https://developer.android.com/reference/android/widget/CheckBox.html

      Ich hoffe Dir helfen die Links weiter.

      Viele Grüße, Chris

  6. Katja

    Hallo zusammen,
    ich habe ein neues Problem: Die App läuft, wenn ich die Methode “public void activateAddButton” und den entsprechenden Methodenaufruf auskommentiere. Aber mit der Methode wird mir an genau diesen Stellen ein Fehler gemeldet mit einer NullPointerException: java.lang.NullPointerException: Attempt to invoke virtual method ‘void android.widget.Button.setOnClickListener(android.view.View$OnClickListener)’ on a null object reference
    at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:3319)

    Ich weiß nicht, wo ich einen Fehler gemacht habe.

    Ich hoffe es kann mir jemand schnell helfen.

    Vielen Dank, Katja

    1. Post
      Author
      Chris

      Hallo Katja,

      wie es scheint, wird versucht auf einem leeren Objekt eine Methode aufzurufen. Die Ursache des Fehlers findet man am besten mit dem Debugger. Wenn du möchtest, kannst Du mir deine Projektdateien (den ganzen Android Studio Projektordner, aber OHNE die build-Unterordner) als ZIP per E-Mail zusenden. Die E-Mail Adresse kannst Du im Impressum finden. Ich schaue dann mal, ob ich etwas herausfinden kann.

      Viele Grüße, Chris

  7. André

    Super Tutorial, wirklich eins der besten was es im web gibt.
    Sehr ausführlich, übersichtlich markiert und immer wieder der ganze Quellcode damit nichts schief gehen kann. Hat mir sehr geholfen, Danke!

    1. Post
      Author
      Chris

      Hallo André,

      danke für’s Lob! Ja das Tutorial sollte so verständlich wie möglich sein, da beim Programmieren schon winzige Kleinigkeiten zu großen Problemen führen können. Diese frustrierenden Momente sollte unseren Lesern erspart bleiben.

      Viele Grüße, Chris

  8. Hans-Jürgen

    Hallo,

    das Tutorial ist sehr gut. Das Programm funktioniert sowohl auf einem Emulator als auch auf einem angeschlossenen Samsung Galaxy S4 Mini. Leider werden im Android Device Monitor keine Dateien und Unterverzeichnisse angezeigt. Ich sehe auf der linken Seite nur die oberste Verzeichnisebene beim Emulatorsystem. Wie kann ich das ändern?

    Viele Grüße,
    Hans-Jürgen

    1. Post
      Author
  9. Vito

    Hallo
    zuerst, es ist ein super Tutorial, ich bin wirklich ein Anfänger.

    hab aber ein Problem,
    laut Log ist alles einwandfrei siehe unten, aber auf dem Handy stürzt die APP ab mit dem Fehler
    ” ShoppingListHQ angehalten”
    was mache ich Falsch?
    Viele Grüsse
    Vito

    01-27 14:02:36.349 29607-29607/de.programmierenlernenhq.shoppinglisthq D/MainActivity: Das Datenquellen-Objekt wird angelegt.
    01-27 14:02:36.349 29607-29607/de.programmierenlernenhq.shoppinglisthq D/ShoppingMemoDataSource: Unsere DataSource erzeugt jetzt den dbHelper.
    01-27 14:02:36.349 29607-29607/de.programmierenlernenhq.shoppinglisthq D/ShoppingMemoDbHelper: DbHelper hat die Datenbank: shopping_list.db erzeugt.
    01-27 14:02:36.359 29607-29607/de.programmierenlernenhq.shoppinglisthq D/MainActivity: Die Datenquelle wird geöffnet.
    01-27 14:02:36.359 29607-29607/de.programmierenlernenhq.shoppinglisthq D/ShoppingMemoDataSource: Eine Referenz auf die Datenbank wird jetzt angefragt.
    01-27 14:02:36.369 29607-29607/de.programmierenlernenhq.shoppinglisthq D/ShoppingMemoDbHelper: Die Tabelle wird mit SQL-Befehl: CREATE TABLE shopping_list(_id INTEGER PRIMARY KEY AUTOINCREMENT, product TEXT NOT NULL, quantity INTEGER NOT NULL, checkedBOOLEAN NOT NULL DEFAULT 0); angelegt.
    01-27 14:02:36.369 29607-29607/de.programmierenlernenhq.shoppinglisthq D/ShoppingMemoDataSource: Datenbank-Referenz erhalten. Pfad zur Datenbank: /data/user/0/de.programmierenlernenhq.shoppinglisthq/databases/shopping_list.db
    01-27 14:02:36.369 29607-29607/de.programmierenlernenhq.shoppinglisthq D/MainActivity: Folgende Einträge sind in der Datenbank vorhanden:

    1. Post
      Author
      Chris

      Hallo Vito,

      momentan kann ich mich aus Zeitgründen leider kaum den Kommentaren widmen, daher kommt meine Antwort so spät :(

      Wenn du möchtest, kannst Du mir deine Projektdateien (den ganzen Android Studio Projektordner, aber OHNE die build-Unterordner) als ZIP per E-Mail zusenden. Die E-Mail Adresse kannst Du im Impressum finden. Ich schaue dann mal, ob ich etwas herausfinden kann.

      Viele Grüße, Chris

  10. Klaus Bauer

    Hallo Chris
    Danke für die tollen Kurse. Wirklich super gemacht.
    Hier noch ein Verbesserungsvorschlag: Wenn du ein UI-Element beschreibst (z.B. ein neues Menu) fände ich es sinnvoll, gleich am Anfang einen Screenshot davon zu zeigen. Dann wissen die Leser schon mal, um was es geht und können sich auf den Inhalt konzentrieren, anstatt sich erstmal vorstellen zu müssen, wie das denn genau aussehen wird.

    Gruss
    Klaus

    1. Post
      Author
      Chris

      Hallo Klaus,

      danke für Dein Lob und den sehr hilfreichen Verbesserungsvorschlag! Den werde ich für zukünftige Tutorials berücksichtigen.

      Viele Grüße, Chris

Hinterlasse eine Antwort

Deine E-Mail-Adresse wird nicht veröffentlicht. Erforderliche Felder sind markiert *