android sqlite_wowomnom_Fotolia_85154667

Android SQLite Datenbank Tutorial – Teil 4: Daten in die SQLite Datenbank schreiben und auslesen


Am Ende der vierten Lektion des Android SQLite Tutorials werden wir unsere App ausführen und dabei überprüfen, ob die Daten korrekt in die SQLite Datenbank geschrieben werden.

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

1. Daten in die SQLite Datenbank schreiben und auslesen

Android Apps Programmieren Online-Kurs

Unser großes
Android Online-Kurs
Gesamtpaket



Weitere Infos

Auf eine SQLite Datenbank können vier Grundoperationen angewandt werden, die unter dem Akronym CRUD zusammengefasst werden.

Die vier Grundoperatoren sind:

  • Create – Erstellen neuer Datensätze.
  • Read – Auslesen von Datensätzen.
  • Update – Aktualisieren von Datensatzinhalten.
  • Delete – Löschen von Datensätzen.

Alle Grundoperationen können als SQL-String vorgegeben werden und dann mit Hilfe der Methode execSQL() auf dem SQLiteDatabase-Objekt ausgeführt werden.

Es geht aber auch bequemer. Für einfache Datenbankoperationen können die von der SQLDatabase-Klasse zur Verfügung gestellten Methoden verwendet werden. Für diese Basiszugriffe werden keine expliziten SQL-Kommando benötigt.

Wie dabei vorzugehen ist, zeigen wir euch in den folgenden Unterabschnitten. Zuerst werden wir beschreiben wie Daten in die SQLite Datenbank geschrieben werden. Dabei stellen wir die Klasse ContentValues und den Insert-Befehl vor.


Anschließend zeigen wir, wie das Auslesen von Datensätzen aus der SQLite Datenbank abläuft. Dabei zeigen wir was ein Cursor ist und wie er verwendet wird.

Im dritten Unterabschnitt stellen wir die die Hilfsmethode cursorToShoppingMemo() vor. Wir verwenden diese Methode, um Datensätze aus der Datenbank in ShoppingMemos umzuwandeln.

1.1 Daten in die SQLite Datenbank schreiben

Datensätze lassen sich in Android sehr einfach in die SQLite Datenbank einfügen.

Wir benötigen dafür ein Hilfsobjekt vom Typ ContentValues, in das wir die einzutragenden Inhalte als Key-Value Pairs (Schlüssel-Wert Paare) ablegen.

Das ContentValues-Objekt können wir dann in die SQLite Datenbank einfügen.

Die Schlüsselnamen (Keys) müssen dabei unbedingt den Spaltennamen der Tabelle entsprechen. Pro Schlüssel kann genau ein Wert zugewiesen werden.

Im unteren Quelltext erzeugen wir ein ContentValues-Objekt und legen darin zwei Schlüssel-Wert Paare ab:

ContentValues values = new ContentValues();
values.put(ShoppingMemoDbHelper.COLUMN_PRODUCT, product);
values.put(ShoppingMemoDbHelper.COLUMN_QUANTITY, quantity);

Mit der put() Methode werden die Schlüssel-Wert Paare abgelegt. Dabei entspricht das erste Argument dem Spaltennamen der Tabelle und das zweite Argument übergibt den abzuspeichernden Wert.

Im Quellcode arbeiten wir mit der Hilfsklasse ShoppingMemoDbHelper, die uns die korrekten Spaltennamen als String-Konstanten liefert.

Es muss nicht für jede Spalte der Tabelle ein Wert übergeben werden. Unsere Tabelle besteht aus den Spalten _id, product und quantity. Da wir die Spalte _id mit AUTOINCREMENT definiert haben, wird dieser Wert automatisch vom SQLite Datenbanksystem gesetzt.

Wir dürfen daher keinen Eintrag für die _id-Spalte in dem ContentValues-Objekt einfügen. Die anderen beiden Spalten müssen zwingend mit Werten gefüllt werden, da wir in der Tabellendefinition für die Spalten product und quantity den Zusatz NOT NULL vorgegeben haben.

Um die vorbereiteten Daten in die Datenbank einzutragen, übergeben wir das ContentValues-Objekt der insert() Methode, die wir auf dem SQLiteDatabase-Objekt aufrufen.

Mit der folgenden Anweisung wird ein Datensatz in die Tabelle der SQLite Datenbank eingefügt:

long insertId = database.insert(ShoppingMemoDbHelper.TABLE_SHOPPING_LIST, null, values);

Die Methode insert() erwartet drei Argumente, von denen wir nur das erste und letzte verwenden. Mit dem ersten Argument übergeben wir den Namen unserer Tabelle und mit dem dritten Argument schließlich die einzutragenden Werte in Form des vorher befüllten ContentValues-Objekts. Das zweite Argument wird nur benötigt, wenn man ein leeres ContentValues-Objekts übergeben würde.

Ist das Einfügen der Werte in die Tabelle der Datenbank erfolgreich gewesen, erhalten wir eine eindeutige ID für den erzeugten Datensatz zurück. Diese ID ist vom Datentyp long und sollte unbedingt gespeichert werden, damit wir später direkt auf den eben eingefügten Datensatz zugreifen können.

Weiterführende Informationen über ContentValues und die insert() Methode sind auf der Android Developer Webseite zu finden.

1.2 Daten aus der SQLite Datenbank auslesen

Wir können sehr einfach nach Einträgen in der Android SQLite Datenbank suchen.

Dafür werden Queries (Suchanfragen) verwendet, in denen über bestimmte Suchkriterien die zu liefernden Datensätze beschrieben werden.

Das Verwenden komplexer Suchanfragen ist ein wesentlicher Vorteil von Datenbanken gegenüber anderen Speicherformen.

Die Klasse SQLiteDatabase stellt uns für diese Zwecke die query() Methode zur Verfügung.

Die Methode ist vierfach überladen und erwartet mindestens 7 Argumente, von denen wir aber nicht alle mit Werten füllen müssen. Als Rückgabewert liefert sie ein Cursor-Objekt zurück, eine Art Zeiger auf eine Zeile der SQLite Tabelle. Man bezeichnet einen Cursor daher auch häufig als Datensatzzeiger.

Genaue Angaben über die Parameterliste der query() Methoden könnt ihr auf der Android Developer Webseite nachlesen.

Mit folgendem Quellcode suchen wir nach einem Datensatz mit einer bestimmten ID:

Cursor cursor = database.query(ShoppingMemoDbHelper.TABLE_SHOPPING_LIST,
                columns, ShoppingMemoDbHelper.COLUMN_ID + "=" + insertId,
                null, null, null, null);

Folgende Argumente werden von uns beim Aufruf der query() Methode genutzt:

  • Argument 1: Enthält den Namen der zu durchsuchenden Tabelle. Wir nutzen wieder die Hilfsklasse ShoppingMemoDbHelper, die uns den korrekten Tabellennamen als String-Konstante liefert.
  • Argument 2: Enthält den Namen der Tabellenspalten, die von der Suchanfrage zurückgeliefert werden sollen. Bei null werden alle Spalten zurückgeliefert.
  • Argument 3: Enthält den String mit den Suchkriterien. Dieser Such-String enthält den Namen der zu vergleichenden Spalte und testet mit dem = Operator, ob die Werte den vorgegebenen Daten entsprechen. Wenn der Such-String null ist, werden alle Datensätze der Tabelle zurückgeliefert.
  • Argumente 4-7: Diese werden nicht von uns benutzt und tragen den Wert null. Über sie kann die Suche weiter verfeinert werden.

Als Ergebnis der Suchanfrage erhalten wir ein spezielles Datenzugriffsobjekt (Data Access Object) vom Typ Cursor zurück. Mit diesem Cursor können wir die Datensätze im Suchergebnis durchlaufen und auf ihre inneren Werte zugreifen.

Um zu einem anderen Datensatz zu navigieren, kann der Cursor (Datensatzzeiger) durch Aufrufen der folgenden Methoden explizit an eine andere Stelle (Datensatz) verschoben werden:

  • moveToFirst() – Bewegt den Cursor zum ersten Datensatz.
  • moveToNext() – Bewegt den Cursor zum nächsten Datensatz.
  • moveToPrevious() – Bewegt den Cursor zum vorherigen Datensatz.
  • moveToLast() – Bewegt den Cursor zum letzten Datensatz.
  • moveToPosition(int pos) – Bewegt den Cursor zum Datensatz an einer bestimmten Positon.

Jede Methode liefert als Rückgabewert true oder false zurück und zeigt damit an, ob die Cursor-Verschiebung erfolgreich durchgeführt werden konnte. Die Anzahl der gefundenen Datensätze kann mit der Methode getCount() abgefragt werden.

Die Werte in den Datensätzen können mit den verschiedenen get-Methoden des Cursor-Interfaces ausgelesen werden. Die Methoden getString(), getInt(), getLong() und getFloat() liefern die Spaltenwerte des ausgewählten Datensatzes zurück. Als Argument erwarten sie den Index der Spalte (Column Index), deren Wert ausgelesen werden soll.

plhq_teaser_hbox_gelb_fotolia_RA Studio_46292813

Unser großes
Android Online-Kurs
Gesamtpaket



Weitere Infos

Die Indizes der Spalten entsprechen der Erstellungsreihenfolge, nach der die Spalten in die Tabelle angelegt wurden. Die Indizes der Tabellenspalten können auch nach dem Erzeugen der Tabelle mit der Methode getColumnIndex(String columnName) noch ausgelesen werden. Man muss dazu aber den Namen der Spalte wissen. Ist die Spalte nicht vorhanden wird der Wert -1 zurückgeliefert, sonst der Index der Spalte.

Wie das Cursor-Objekt in der Praxis eingesetzt wird und damit Werte aus den Datensätzen der Datenbank ausgelesen werden, beschreiben wir im nächsten Unterabschnitt genauer.

1.3 Die Hilfsmethode cursorToShoppingMemo()

In unserer SQLite-App werden wir die Hilfsmethode cursorToShoppingMemo() verwenden, um ein Cursor-Objekt in ein ShoppingMemo-Objekt umzuwandeln.

Dabei benutzen wir vier wichtige Methoden des Cursor-Interfaces, diese sind:

  • getColumnIndex(String columnName) – Durch Angabe des Spaltennamens unserer Tabelle erhalten wir den Index der Spalte zurück.
  • getString(int columnIndex) – Mit dem übergebenen Spaltenindex wird die relevante Spalte gefunden und der darin gespeicherte String-Wert zurückgegebenen.
  • getInt(int columnIndex) – In diesem Fall wird als Rückgabewert ein int-Wert zurückgeliefert.
  • getLong(int columnIndex) – In diesem Fall wird als Rückgabewert ein long-Wert zurückgeliefert.

Mit dem folgenden Quellcode definieren wir die Hilfsmethode cursorToShoppingMemo():

private ShoppingMemo cursorToShoppingMemo(Cursor cursor) {
    int idIndex = cursor.getColumnIndex(ShoppingMemoDbHelper.COLUMN_ID);
    int idProduct = cursor.getColumnIndex(ShoppingMemoDbHelper.COLUMN_PRODUCT);
    int idQuantity = cursor.getColumnIndex(ShoppingMemoDbHelper.COLUMN_QUANTITY);

    String product = cursor.getString(idProduct);
    int quantity = cursor.getInt(idQuantity);
    long id = cursor.getLong(idIndex);

    ShoppingMemo shoppingMemo = new ShoppingMemo(product, quantity, id);

    return shoppingMemo;
}

Der Code ist größtenteils selbsterklärend. In den Zeilen 2 bis 4 lesen wir die Indizes unserer Tabellenspalten aus. Anschließend lassen wir uns in den Zeilen 6 bis 8 die Inhalte der Suchanfrage mit den get-Methoden ausgeben. Dazu nutzen wir die vorher erhaltenen Spaltenindizes.

Das Cursor-Objekt zeigt dabei auf einen Datensatz der vorher ausgeführten Suchanfrage. Über die Spaltenindizes kann auf die Zellen des Datensatzes zugegriffen und mit der entsprechenden get-Methode deren Inhalt ausgelesen werden.

In Zeile 10 erzeugen wir schließlich mit den ausgelesenen Daten das ShoppingMemo-Objekt. Dieses können wir nun in unserer Anwendung weiterverwenden, bspw. in einem ListView anzeigen lassen, und geben es daher als Rückgabewert zurück.

Die eben beschriebene Hilfsmethode werden wir in unserer Android SQLite App öfter verwenden. Mit ihrer Hilfe könne sehr einfach und bequem Datensätze in ShoppingMemo-Objekte umgewandelt werden.

Nun haben wir den theoretischen Teil dieser Lektion des Android SQLite Datenbank Tutorials abgeschlossen und können des Erlernte in unserem Android Projekt einsetzen.

Dazu werden wir in dem nächsten Abschnitt den Quellcode unserer Datenquelle, der ShoppingMemoDataSource-Klasse, vervollständigen, so dass wir Daten in unsere SQLite Datenbank schreiben und auch wieder auslesen können.

2. Mit Hilfe unserer Datenquelle Daten in die SQLite Datenbank speichern und aus dieser auslesen

Jetzt werden wir unserer Datenquelle wichtige Zugriffsfunktionen hinzufügen. Dies werden wir durch die drei folgenden Änderungen an dem Quellcode der Klasse ShoppingMemoDataSource verwirklichen:

  1. Einfügen der Import-Anweisungen – Zuerst importieren wir die benötigten Klassen und Interfaces.
  2. Anlegen des Spalten-Arrays – Die Spaltennamen unserer Tabelle speichern wir in einem String-Array.
  3. Definieren der Methoden – Wir definieren drei Methoden, die uns beim Zugreifen auf Datensätze der SQLite Datenbank helfen. Eine Methode wird das Schreiben von Datensätzen in die Datenbank realisieren. Eine andere Methode wird für das Auslesen aller Datensätze aus der SQLite Datenbank zuständig sein. Die dritte Methode ist die bereits weiter oben vorgestellte Hilfsmethode cursorToShoppingMemo() und wandelt ein Cursor-Objekt in ein ShoppingMemo-Objekt um.

Hinweis: Wir werden jetzt die Arbeitsschritte der Reihe nach ausführen. Sollte etwas unklar sein, könnt ihr am Ende dieses Abschnitts den gesamten Quellcode der ShoppingMemoDataSource-Klasse in Ruhe analysieren und direkt erkennen, an welcher Stelle welcher Code-Block eingefügt werden muss.

Nun beginnen wir mit dem ersten Arbeitsschritt.

2.1 Einfügen der Import-Anweisungen

Als Erstes öffnen wir die Klassendatei ShoppingMemoDataSource.java in dem Editor von Android Studio. Die Klassendatei befindet sich im Package-Ordner de.codeyourapp.shoppinglist unseres Projekts. Das Gerüst der Klasse haben wir bereits in der vorherigen Lektion des SQLite Tutorials angelegt.

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

ShoppingMemoDataSource.java

import android.content.ContentValues;
import android.database.Cursor;
import java.util.ArrayList;
import java.util.List;

Die vier Klassen bzw. Interfaces machen wir mittels Import-Anweisungen innerhalb der Klasse ShoppingMemoDataSource sichtbar, so dass wir sie ohne den Namen ihres Packages verwenden können.

Die Klasse ContentValues benötigen wir für das Schreiben von Daten in die SQLite Datenbank. Das Interface Cursor nutzen wir für Lese-Zugriffe auf die Datenbank. Das Interface List und die Klasse ArrayList werden wir für das Speichern von ShoppingMemo-Objekten in einer Liste verwenden. Den Inhalt der Liste werden wir später vom ListView unserer Android App ausgeben lassen.

2.2 Anlegen des Spalten-Arrays

Auch der zweite Arbeitsschritt ist schnell ausgeführt. Den folgenden Quellcode fügen wir direkt unter den bereits angelegten Membervariablen in die Klasse ShoppingMemoDataSource.java ein:

ShoppingMemoDataSource.java

private String[] columns = {
  ShoppingMemoDbHelper.COLUMN_ID,
  ShoppingMemoDbHelper.COLUMN_PRODUCT,
  ShoppingMemoDbHelper.COLUMN_QUANTITY
};

Den Spalten-Array werden wir später für Suchanfragen verwenden. Er enthält die Namen der drei Spalten unserer Tabelle. Die Namen geben wir nicht selbst ein, sondern nutzen dafür die String-Konstanten der Hilfsklasse ShoppingMemoDbHelper.

2.3 Definieren der Methoden

Im letzten Arbeitsschritt werden wir drei Methoden definieren, die uns beim Zugriff auf die SQLite Datenbank unterstützen. Die Hilfsmethode cursorToShoppingMemo() haben wir bereits im theoretischen Teil dieser Lektion kennengelernt. Die beiden anderen Methoden sind neu. Wir werden sie daher im Anschluss an den Quelltext ausführlich beschreiben.

Jetzt fügen wir den folgenden Quellcode in den Methodenbereich der ShoppingMemoDataSource-Klasse direkt nach der close() Methode ein:

ShoppingMemoDataSource.java

public ShoppingMemo createShoppingMemo(String product, int quantity) {
  ContentValues values = new ContentValues();
  values.put(ShoppingMemoDbHelper.COLUMN_PRODUCT, product);
  values.put(ShoppingMemoDbHelper.COLUMN_QUANTITY, quantity);

  long insertId = database.insert(ShoppingMemoDbHelper.TABLE_SHOPPING_LIST, null, values);

  Cursor cursor = database.query(ShoppingMemoDbHelper.TABLE_SHOPPING_LIST,
                  columns, ShoppingMemoDbHelper.COLUMN_ID + "=" + insertId,
                  null, null, null, null);

  cursor.moveToFirst();
  ShoppingMemo shoppingMemo = cursorToShoppingMemo(cursor);
  cursor.close();

  return shoppingMemo;
}

private ShoppingMemo cursorToShoppingMemo(Cursor cursor) {
  int idIndex = cursor.getColumnIndex(ShoppingMemoDbHelper.COLUMN_ID);
  int idProduct = cursor.getColumnIndex(ShoppingMemoDbHelper.COLUMN_PRODUCT);
  int idQuantity = cursor.getColumnIndex(ShoppingMemoDbHelper.COLUMN_QUANTITY);

  String product = cursor.getString(idProduct);
  int quantity = cursor.getInt(idQuantity);
  long id = cursor.getLong(idIndex);

  ShoppingMemo shoppingMemo = new ShoppingMemo(product, quantity, id);

  return shoppingMemo;
}

public List<ShoppingMemo> getAllShoppingMemos() {
  List<ShoppingMemo> shoppingMemoList = new ArrayList<>();

  Cursor cursor = database.query(ShoppingMemoDbHelper.TABLE_SHOPPING_LIST,
                  columns, null, null, null, null, null);

  cursor.moveToFirst();
  ShoppingMemo shoppingMemo;

  while(!cursor.isAfterLast()) {
    shoppingMemo = cursorToShoppingMemo(cursor);
    shoppingMemoList.add(shoppingMemo);
    Log.d(LOG_TAG, "ID: " + shoppingMemo.getId() + ", Inhalt: " + shoppingMemo.toString());
    cursor.moveToNext();
  }

  cursor.close();

  return shoppingMemoList;
}

Mit der ersten Methode createShoppingMemo() können wir Datensätze in die Tabelle unserer SQLite Datenbank einfügen. In der Methode erzeugen wir in den Zeilen 2 bis 4 ein ContentValues-Objekt, in das wir den Produktnamen und die Menge einfügen.

Anschließend tragen wir diese Werte mit Hilfe des ContentValues-Objekts in die Tabelle ein. Dazu verwenden wir den insert-Befehl in Zeile 6, den wir auf dem SQLiteDatabase-Objekt ausführen. Als Argumente übergeben wir den Namen der Tabelle, als ColumnHack den Wert null und als einzutragende Daten das vorbereitete ContentValues-Objekt. Als Rückgabewert erhalten wir die ID des erstellten Datensatzes zurück.

Nun lesen wir die eingetragenen Werte zur Kontrolle mit der Anweisung in Zeile 8 bis 10 direkt wieder aus. Als Argumente übergeben wir den Namen der Tabelle, den Spalten-Array (die Suchanfrage soll die Werte für alle Spalten zurückliefern) und den Such-String mit dem wir nach dem eben eingefügten Datensatz suchen. Die restlichen Argumente sind alle null.

Als Ergebnis auf die Suchanfrage erhalten wir ein Cursor-Objekt zurück, das die gefundenen Datensätze enthält. In unserem Fall besteht es aus genau einem Datensatz, dem eben eingefügten.

Mit der Anweisung in Zeile 12 bewegen wir den Cursor an die Position seines ersten Datensatzes. Anschließend rufen wir die cursorToShoppingMemo() Methode auf und wandeln dadurch den Datensatz des Cursor-Objekts in ein ShoppingMemo-Objekt um.

Das so erzeugte ShoppingMemo-Objekt geben wir an die aufrufende Methode zurück. Doch vorher schließen wir noch das Cursor-Objekt mit der Anweisung in Zeile 14.

Die zweite Methode cursorToShoppingMemo() haben wir bereits im ersten Kapitel ausführlich besprochen und gehen hier nicht noch einmal darauf ein.

Mit der dritten Methode getAllShoppingMemos() lesen wir alle vorhandenen Datensätze aus der Tabelle unserer SQLite Datenbank aus. Dazu erzeugen wir gleich zu Beginn der Methode in Zeile 34 eine Liste, die ShoppingMemo-Objekt in sich aufnehmen kann.

Anschließend starten wir eine Suchanfrage in Zeile 36 und 37. Diesmal übergeben wir als Argumente nur den Namen der Tabelle und den Spalten-Array. Alle anderen Argumente sind null, d.h. auch der Such-String ist null, wodurch alle in der Tabelle existierenden Datensätze als Ergebnis zurückgeliefert werden.

In den Zeilen 39 und 40 setzen wir das erhaltenen Cursor-Objekt an seine erste Position und deklarieren eine Variable vom Typ ShoppingMemo.

plhq_teaser_hbox_gelb_fotolia_RA Studio_46292813

Unser großes
Android Online-Kurs
Gesamtpaket



Weitere Infos

Mit der while-Schleife in den Zeilen 42 bis 47 lesen wir alle Datensätze der Suchanfrage aus, wandeln sie in ShoppingMemo-Objekte um und fügen sie der ShoppingMemo-Liste hinzu. Mit der Log-Meldung können wir später in der Konsole überprüfen, welche Datensätze sich in der Tabelle befinden.

In Zeile 49 schließen wir den Cursor wieder. Dies ist eine ganz wichtige Anweisung und darf nicht vergessen werden! Am Ende der Methode geben wir die erzeugte ShoppingMemo-Liste, die alle Datensätze der Tabelle enthält, an die aufrufende Methode zurück.

2.4 Der komplette Quellcode der ShoppingMemoDataSource-Klasse

Nun haben wir alle Änderungen an der ShoppingMemoDataSource-Klasse vorgenommen und das Erstellen von Datensätzen in die Tabelle der Android SQLite Datenbank vorbereitet. Zudem können wir die eingetragenen Daten auch wieder auslesen.

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

In Android Studio sollte die ShoppingMemoDataSource.java Klassendatei nun wie folgt aussehen:

An dieser Stelle endet der freie Inhalt dieser Lektion. Wir hoffen, sie hat dir bis hierher gefallen! Du kannst sie im geschützten Bereich von ProgrammierenLernenHQ fortsetzen, in welchem sich alle Lektionen unserer Android Online-Kurse befinden.

Unsere Android Kurse bestehen aus insgesamt 43 großen Lektionen und sind unterteilt in 13 frei zugängliche und 30 Premium-Lektionen. Die Premium-Lektionen befinden sich in dem geschützten Bereich und sind nur für Käufer unseres Android Online-Kurs Gesamtpaket zugänglich.

plhq_teaser_hbox_gelb_fotolia_RA Studio_46292813 An dieser Stelle endet der freie Inhalt dieser Lektion. Wir hoffen, sie hat dir bis hierher gefallen! Du kannst sie durch Kauf unseres Android Online-Kurs Gesamtpakets freischalten.

In unserem Android Online-Kurs Gesamtpaket befinden sich 43 große Lektionen, in denen wir dir schrittweise zeigen, wie voll funktionstüchtige Android Apps programmiert werden.

Diese Lektion ist Teil unseres Android Gesamtpakets. Insgesamt sind unsere Online-Kurse unterteilt in 13 frei zugängliche und 30 Premium-Lektionen.

Die Premium-Lektionen befinden sich in dem geschützten Bereich und sind nur für Käufer des Android Online-Kurs Gesamtpakets zugänglich.



Welche Inhalte befinden sich im Android Online-Kurs Gesamtpaket?

  • Das Gesamtpaket enthält alle Android Online-Kurse von ProgrammierenLernenHQ.
  • Im Paket enthalten ist unser großer Android Apps Programmieren Online-Kurs. Er ist unser Hauptkurs und besteht aus 35 großen Lektionen. Die Grundlagen der Android App Entwicklung praxisnah und verständlich zu lehren, ist das Hauptziel des Android Apps Programmieren Kurses.
  • Im Paket enthalten ist auch unser SQLite Datenbank App Programmieren Online-Kurs. Dieser Spezialkurs besteht aus 8 großen Lektionen und ist als weiterführender Kurs konzipiert worden. Der Kurs schließt an unseren Android Apps Programmieren Hauptkurs an und widmet sich dem speziellen Thema der SQLite Datenbanken.
  • Durch den Kauf erhältst du unbegrenzten Zugang zu allen Inhalten unseres Android Online-Kurs Gesamtpakets. Wir werden in Zukunft weitere Lektionen hinzufügen. Auch auf alle zukünftigen Lektionen erhältst du vollen Zugriff.

Wir hoffen, Dich bald als neuen Kursteilnehmer unserer Android Online-Kurse begrüßen zu dürfen!

Einmal kaufen und dadurch zeitlich unbegrenzten Zugriff auf alle Inhalte unseres Android Online-Kurs Gesamtpakets erhalten.



Hinweis: Der untere Quellcode ist Teil des geschützten Bereichs von ProgrammierenLernenHQ. Durch Freischalten unserer Android Online-Kurse erhältst du Zugriff auf alle geschützten Inhalte.
Erfahre mehr über unsere Android Online-Kurse.

android_sqlite_lektion4_blurry_a

Der obere Quellcode ist Teil des geschützten Bereichs von ProgrammierenLernenHQ. Durch Freischalten unserer Android Online-Kurse erhältst du Zugriff auf alle geschützten Inhalte.
Erfahre mehr über unsere Android Online-Kurse.

In der oberen Abbildung ist die überarbeitete ShoppingMemoDataSource.java Klassendatei dargestellt. Der bisherige Quellcode wurde an drei Stellen (Markierung A, B und C) erweitert.

Welche Bedeutung der jeweilige Code-Block besitzt, ist in der unteren Liste angegeben:

  1. A – Die benötigten Import-Anweisungen zum Sichtbarmachen der Klassen bzw. Interfaces ContentValues, Cursor, ArrayList und List.
  2. B – Die Variable columns enthält die Namen der drei Spalten unserer Tabelle, die für die Suchanfragen benötigt werden.
  3. C – Die Methoden createShoppingMemo(), cursorToShoppingMemo() und getAllShoppingMemos() zum Schreiben in die Datenbank, Umwandeln eines Cursor– in ein ShoppingMemo-Objekt und Auslesen aller Datenbankeinträge für die Ausgabe in dem ListView unserer Android App.

Mit diesen Änderungen im Quellcode der ShoppingMemoDataSource-Klasse haben wir unsere Datenquelle um zwei sehr nützliche Funktionen erweitert. Wir können jetzt mit ihrer Hilfe Daten in die SQLite Datenbank schreiben und alle vorhandenen Datensätze aus der Datenbank auslesen.

Diese neuen Funktionen werden wir im nächsten Abschnitt nutzen und erstmals Datensätze in unsere Datenbank schreiben. Anschließend werden wir alle vorhandenen Datensätze unserer Datenbank auf dem Android Gerät im ListView der MainActivity ausgeben.

3. Inhalt der SQLite Datenbank im ListView ausgeben

Nun werden wir von der MainActivity aus Daten in die SQLite Datenbank schreiben. Die eingetragenen Daten werden wir anschließend wieder aus der Datenbank auslesen. Für beide Operationen nutzen wir die neuen Funktionen unserer Datenquelle.

Um dies zu realisieren nehmen wir diese drei Änderungen am Quellcode der Klasse MainActivity vor:

  1. Einfügen der Import-Anweisungen – Zuerst importieren wir die benötigten Klassen und Interfaces.
  2. Überarbeiten der onCreate() Methode – Hier fügen wir die Anweisungen für das Schreiben in die Datenbank und das Auslesen aus der Datenbank ein, zusammen mit einigen Log-Meldungen.
  3. Definieren der showAllListEntries() Methode – Diese Methode liest alle Datensätze aus der Tabelle unserer SQLite Datenbank aus und gibt die Einträge in dem ListView der MainActivity auf dem Android Gerät aus. Sie nutzt dazu die neuen Funktionen unserer Datenquelle.

Hinweis: Wir werden jetzt die Arbeitsschritte der Reihe nach ausführen. Sollte etwas unklar sein, könnt ihr am Ende dieses Abschnitts den gesamten Quellcode der MainActivity-Klasse in Ruhe analysieren und direkt erkennen, an welcher Stelle welcher Code-Block eingefügt werden muss.

Nun beginnen wir mit dem ersten Arbeitsschritt.

3.1 Einfügen der Import-Anweisungen

Wir öffnen nun die Klassendatei MainActivity.java in dem Editor von Android Studio. Die Klassendatei befindet sich im Package-Ordner de.codeyourapp.shoppinglist unseres Projekts. Das Gerüst der Klasse haben wir bereits in der vorherigen Lektion des SQLite Tutorials angelegt.

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

MainActivity.java

import android.widget.ArrayAdapter;
import android.widget.ListView;
import java.util.List;

Die drei Klassen bzw. Interfaces machen wir mittels Import-Anweisungen innerhalb der Klasse MainActivity sichtbar, so dass wir sie ohne den Namen ihres Packages verwenden können.

Die Klasse ArrayAdapter benötigen wir für das Verbinden des ListViews mit der ShoppingMemo-Liste, die alle Einträge aus der SQLite Datenbank enthält. Die ListView-Klasse für den ListView und das List-Interface für die ShoppingMemo-Liste.

3.2 Überarbeiten der onCreate() Methode der MainActivity

Im zweiten Arbeitsschritt überarbeiten wir die onCreate() Methode unserer MainActivity-Klasse. Wir werden von der onCreate() Methode aus Daten in die Datenbank schreiben und wieder auslesen lassen.

Den markierten Quellcode fügen wir nun in die onCreate() Methode der MainActivity.java ein:

Hinweis: Der untere Quellcode ist Teil des geschützten Bereichs von ProgrammierenLernenHQ. Durch Freischalten unserer Android Online-Kurse erhältst du Zugriff auf alle geschützten Inhalte.
Erfahre mehr über unsere Android Online-Kurse.

MainActivity.java

android_sqlite_table_mainactivity_blurry

In Zeile 14 schreiben wir Daten in die Datenbank. Dazu nutzen wir die createShoppingMemo() Methode unserer Datenquelle und lassen durch sie einen Testeintrag in die Tabelle der SQLite Datenbank einfügen.

In den Zeilen 15 und 16 geben wir zwei Log-Meldungen an die Konsole aus, in denen wir über den erfolgten Eintrag und dessen Inhalt informiert wird.

Anschließend lesen wir in Zeile 19 den Testeintrag mit der Hilfsmethode showAllListEntries() wieder aus der Datenbank aus. Die Hilfsmethode werden wir im dritten Arbeitsschritt erstellen.

3.3 Definieren der showAllListEntries() Methode

Als letzten Arbeitsschritt definieren wir die Hilfsmethode showAllListEntries() in der MainActivity-Klasse. Diese Methode liest für uns alle vorhandenen Datensätze aus der Tabelle unserer SQLite Datenbank aus und speichert diese in einer Liste als ShoppingMemo-Objekte ab.

Die Liste übergeben wir an einen ArrayAdapter, der für uns die Verwaltungsarbeit übernimmt. Die ausgelesenen Einträge lassen wir jeweils in einem vordefinierten Standardlayout, dem simple_list_item_multiple_choice, anzeigen.

Damit unsere Datenbankeinträge auch auf dem Android Gerät angezeigt werden, binden wir den ArrayAdapter an den ListView der MainActivity. Was ein ArrayAdapter im Detail macht, erklären wir sehr detailliert in unserem großen Android Apps Programmieren Kurs im fünften Kursmodul.

Jetzt fügen wir den folgenden Quellcode in den Methodenbereich der MainActivity.java-Klasse direkt nach der onCreate() Methode ein:

MainActivity.java

private void showAllListEntries () {
    List<ShoppingMemo> shoppingMemoList = dataSource.getAllShoppingMemos();

    ArrayAdapter<ShoppingMemo> shoppingMemoArrayAdapter = new ArrayAdapter<> (
            this,
            android.R.layout.simple_list_item_multiple_choice,
            shoppingMemoList);

    ListView shoppingMemosListView = (ListView) findViewById(R.id.listview_shopping_memos);
    shoppingMemosListView.setAdapter(shoppingMemoArrayAdapter);
}

In Zeile 2 rufen wir über unsere Datenquelle die Methode getAllShoppingMemos() auf, die uns alle Datenbankeinträge als Liste zurück liefert. Die Einträge dieser Liste sind vom Typ ShoppingMemo, unserem Datenmodell.

Mit den Zeilen 4 bis 7 erzeugen wir den ArrayAdapter und weisen ihm als Context die Instanz der MainActivity, als Layout für die Einträge das vordefinierte Standardlayout simple_list_item_multiple_choice und als Liste das shoppingMemoList Objekt zu.

Anschließend suchen wir in Zeilen 9 und 10 nach dem ListView des MainActivity-Layouts und binden den ArrayAdapter an das ListView-Objekt, wodurch unsere SQLite Datenbankeinträge auf dem Android Gerät angezeigt werden.

3.4 Der komplette Quellcode der MainActivity-Klasse

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

Durch den eingefügten Quellcode wird einen Testeintrag erstellt und zwar jedes Mal wenn unsere Activity erzeugt wird. Also auch beim Drehen des Android Geräts. Zudem lassen wir alle angelegten Datensätze aus der Tabelle der SQLite Datenbank auslesen und diese im ListView anzeigen.

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

In Android Studio sollte die MainActivity.java Klassendatei nun wie folgt aussehen:

Hinweis: Der untere Quellcode ist Teil des geschützten Bereichs von ProgrammierenLernenHQ. Durch Freischalten unserer Android Online-Kurse erhältst du Zugriff auf alle geschützten Inhalte.
Erfahre mehr über unsere Android Online-Kurse.

android_sqlite_lektion4_blurry_b

Der obere Quellcode ist Teil des geschützten Bereichs von ProgrammierenLernenHQ. Durch Freischalten unserer Android Online-Kurse erhältst du Zugriff auf alle geschützten Inhalte.
Erfahre mehr über unsere Android Online-Kurse.

In der oberen Abbildung ist die überarbeitete MainActivity.java Klassendatei dargestellt. Der bisherige Quellcode wurde an drei Stellen (Markierung A, B und C) erweitert.

Welche Bedeutung der jeweilige Code-Block besitzt, ist in der unteren Liste angegeben:

  1. A – Die benötigten Import-Anweisungen zum Sichtbarmachen der Klassen bzw. Interfaces ArrayAdapter, ListView und List.
  2. B – Die in die onCreate() Methode eingefügten Anweisungen zum Schreiben eines Eintrags in die SQLite Datenbank und Aufrufen der showAllListEntries() Methode.
  3. C – Die showAllListEntries() Methode zum Auslesen aller Datensätze der Tabelle und Ausgeben dieser in dem ListView unserer Android App.

Mit diesen Änderungen im Quellcode der MainActivity-Klasse haben wir unsere SQLite App um zwei sehr nützliche Funktionen erweitert. Wir können jetzt Daten in die SQLite Datenbank unter Zuhilfenahme der Datenquelle schreiben und alle vorhandenen Datensätze aus der Datenbank auf dem Android Gerät ausgeben.

Im nächsten Abschnitt werden wir die neuen Funktionen unserer Android App testen und prüfen, ob die Daten korrekt in die Datenbank geschrieben werden.

4. Starten und Testen der Android SQLite App

Wir werden nun unserer Android App auf einem Android Virtual Device im Emulator ausführen lassen und die Log-Meldungen unserer Anwendung im Logcat Tool Window überprüfen. Auf diese Weise können wir das Verhalten unserer App direkt in Android Studio analysieren und überprüfen, ob die Testdaten korrekt in die Tabelle unserer SQLite Datenbank eingetragen werden. Zusätzlich prüfen wir auch, ob die Einträge korrekt im ListView der MainActivity auf dem Android Gerät angezeigt werden.

Hinweis: Wenn ihr Probleme beim Ausführen der App im Android Emulator oder auf einem Android Gerät haben solltet, könnt ihr unseren großen Android Apps Programmieren Kurs als Hilfe nutzen. Darin zeigen wir, wie eine Android App im Emulator oder auf einem physikalischen Android Gerät ausgeführt wird.

Unsere App starten wir dazu wie gewohnt über den Run > Run 'app' Menüeintrag, den wir über die obere Menüleiste erreichen.

Unsere SQLite App sollte jetzt auf dem Android Gerät gestartet worden sein. Die grafische Benutzeroberfläche der Anwendung hat sich auch diesmal nicht geändert, daher sieht auf dem Gerät alles genau so aus wie in der vorherigen Lektion.

Hinweis: Das Emulator-Fenster mit dem darin laufenden Android Virtual Device muss für die nächsten Arbeitsschritte geöffnet bleiben. Zudem muss in dem AVD unsere eigene App ausgeführt werden. Sollte dies nicht der Fall sein, muss die App erneut im Emulator gestartet werden.

Um die Log-Meldungen zu überprüfen, öffnen wir in Android Studio das Logcat Tool Window während unsere App auf dem AVD im Emulator ausgeführt wird.

Dazu führen wir die folgenden Schritte aus:

  1. Wir öffnen das Logcat Tool Window mit einem Klick auf den Logcat-Tab am unteren Bildschirmrand.
  2. Anschließend wählen wir Emulator Nexus_9 als AVD in der Drop-Down Liste aus.
  3. Nun wählen wir unsere App de.codeyourapp.shoppinglist in der Liste rechts daneben aus.
  4. Danach stellen wir die Prioritätsstufe auf Verbose ein.
  5. Und geben in das anschließende Suchfeld MainActivity|ShoppingMemo als Suchbegriff ein.
  6. Zuletzt wählen wir den Eintrag Show only selected application in Liste ganz rechts aus.
android_sqlite_access_logcat_start

Überprüfen der Log-Meldungen unserer App im Logcat Tool Window von Android Studio

Uns werden die folgenden Log-Meldungen ausgegeben:

01: MainActivity﹕ Inhalt der Testmemo: 5 x Birnen
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: ShoppingMemoDataSource﹕ Datenbank-Referenz erhalten. Pfad zur Datenbank: /data/user/0/de.codeyourapp.shoppinglist/databases/shopping_list.db
07: MainActivity﹕ Es wurde der folgende Eintrag in die Datenbank geschrieben:
08: MainActivity﹕ ID: 1, Inhalt: 2 x Testprodukt
09: MainActivity﹕ Folgende Einträge sind in der Datenbank vorhanden:
10: ShoppingMemoDataSource﹕ ID: 1, Inhalt: 2 x Testprodukt
11: MainActivity﹕ Die Datenquelle wird geschlossen.
12: ShoppingMemoDataSource﹕ Datenbank mit Hilfe des DbHelpers geschlossen.

Die sechs ersten Log-Meldungen haben wir bereits in der vorherigen Lektion überprüft, ebenso wie die letzten beiden Meldungen. Neu hinzugekommen sind die Meldungen 7 bis 10.

Die Meldung 8 informiert uns über die ID und den Inhalt des eben eingetragenen Datensatzes. Die ausgegebenen Werte entsprechen den Werten in der Tabelle unserer SQLite Datenbank, da wir sie nach dem Eintragen in die Tabelle sofort wieder ausgelesen und mit den ausgelesenen Werten das ShoppingMemo-Objekt erstellt haben.

Mit den Meldungen 9 und 10 geben wir den Inhalt unserer SQLite Datenbank aus. Momentan ist nur ein Datensatz in der Tabelle der Datenbank vorhanden, daher wird auch nur ein Eintrag zurückgeliefert. Dies werden wir nun ändern.

Wir erzeugen nun weitere Datenbankeinträge, indem wir die MainActivity zerstören und neu erstellen lassen. Dabei wird jedes Mal die onCreate() Methode der MainActivity-Klasse aufgerufen und somit jeweils ein Testeintrag in die SQLite Datenbank geschrieben.

Die MainActivity können wir durch Drehen des Android Devices zerstören und neu erstellen, das liegt an dem Activity Lifecycle vom Android System. Welche Zustände eine Activity in ihrem Leben durchläuft solltet ihr unbedingt hier: Der Activity und Fragment Lifecycle in Android nachlesen.

Wir könnten aber auch die SQLite App mittels Back-Button vollständig beenden und anschließend neu starten. Egal welchen Weg wir wählen, es wird dabei immer beim Erzeugen der MainActivity ein Eintrag in die SQLite Datenbank erstellt.

Nach mehrfachem Drehen des Android Geräts werden uns die folgenden Log-Meldungen ausgegeben:

android_sqlite_access_logcat_end

Es wurden 5 Einträge in die SQLite Datenbank geschrieben

Diesmal werden uns die folgenden Log-Meldungen ausgegeben:

01: MainActivity﹕ Inhalt der Testmemo: 5 x Birnen
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: ShoppingMemoDataSource﹕ Datenbank-Referenz erhalten. Pfad zur Datenbank: /data/user/0/de.codeyourapp.shoppinglist/databases/shopping_list.db
07: MainActivity﹕ Es wurde der folgende Eintrag in die Datenbank geschrieben:
08: MainActivity﹕ ID: 5, Inhalt: 2 x Testprodukt
09: MainActivity﹕ Folgende Einträge sind in der Datenbank vorhanden:
10: ShoppingMemoDataSource﹕ ID: 1, Inhalt: 2 x Testprodukt
11: ShoppingMemoDataSource﹕ ID: 2, Inhalt: 2 x Testprodukt
12: ShoppingMemoDataSource﹕ ID: 3, Inhalt: 2 x Testprodukt
13: ShoppingMemoDataSource﹕ ID: 4, Inhalt: 2 x Testprodukt
14: ShoppingMemoDataSource﹕ ID: 5, Inhalt: 2 x Testprodukt
15: MainActivity﹕ Die Datenquelle wird geschlossen.
16: ShoppingMemoDataSource﹕ Datenbank mit Hilfe des DbHelpers geschlossen.

Es hat sich nicht viel gegenüber dem vorherigen Output geändert. Neu hinzugekommen sind Log-Meldungen 11 bis 14, die uns über den Inhalt der Datenbank informieren.

Anhand der ausgegebenen Meldungen können wir feststellen, dass unsere App die Testeinträge korrekt in die Datenbank schreibt und wieder aus ihr ausliest. Auch die ID wird als laufende Nummer automatisch bei jedem neuen Datensatz um 1 erhöht, so wie es sein soll.

Die Log-Meldungen helfen uns dabei die Korrektheit unseres Quellcodes sicherzustellen, sie sind jedoch für unsere Anwender nicht sichtbar. Wir werden nun die grafische Oberfläche unserer SQLite App testen und überprüfen, welche Daten auf dem Display ausgegeben werden.

In der unteren Abbildung ist das User Interface unsere SQLite App auf dem Android Virtual Device im Emulator zu sehen:

android_sqlite_app_access

Unsere SQLite App zeigt den Inhalt der ihrer Datenbank an

Die Datensätze in der Tabelle unserer SQLite Datenbank werden im ListView der MainActivity angezeigt.

Durch Ändern der Bildschirmorientierung (Drehen des Android Geräts) lassen wir automatisch einen neuen Testeintrag in die Datenbank erstellen. Diese Funktion werden wir in der nächsten Lektion durch eine, für die Nutzer, sinnvolle Funktion ersetzen. Momentan dient sie uns aber sehr gut zu Testzwecken.

Die einzelnen Listeneinträge können zwar bereits angeklickt werden, reagieren jedoch noch nicht darauf. Auch der + Button reagiert noch nicht auf Benutzereingaben.

Dies werden wir in der nächsten Lektion ändern und das User Interface auf Benutzereingaben reagieren lassen, so dass es möglich ist eigene echte Einträge in die Datenbank der Einkaufslisten-App zu schreiben.

Wenn bei euch die gleichen Log-Meldungen ausgegeben werden und ihr die Einträge der Datenbank auch auf dem Display eures Android Geräts oder dem Android Emulator angezeigt bekommt, habt ihr alle Arbeitsschritte korrekt umgesetzt.

Eure App speichert dann die Daten korrekt in die Tabelle der SQLite Datenbank ab. In der nächsten Lektion des Android SQLite Tutorials können wir nun die grafische Benutzeroberfläche mit Funktionalität füllen.

Zusammenfassung

In dieser Lektion unseres Android SQLite Tutorials haben wir Datensätze in die Tabelle der SQLite Datenbank geschrieben. Die Datensätze haben wir anschließend wieder ausgelesen und im ListView der MainActivity ausgegeben. Um dies zu erreichen, haben wir die folgenden beiden Klassen unseres Android Projekts überarbeitet:

  • ShoppingMemoDataSource – Wir benutzen diese Klasse als Datenquelle, die eine Verbindung zur SQLite Datenbank aufrecht hält und für alle Lese- und Schreib-Zugriffe verantwortlich ist. In dieser Lektion haben wir ihr drei Methoden hinzugefügt, mit denen wir nun Daten in die Datenbank schreiben und aus ihr wieder auslesen können.
  • MainActivity – Mit unserer Hauptklasse steuern wir die Datenbankzugriffe und verwalten die Elemente der grafischen Benutzeroberfläche unserer SQLite App. In dieser Lektion haben wir von der MainActivity aus Daten in die SQLite Datenbank schreiben und aus ihr auslesen lassen, unter Zuhilfenahme unserer Datenquelle.

Abschließend haben wir die neuen Funktionen unserer Android SQLite App überprüft und dadurch sichergestellt, dass die Datensätze korrekt in die Datenbank geschrieben werden.

Wir sind nun bei der Entwicklung unserer Android SQLite App einen großen Schritt weiter gekommen. Unsere Einkaufslisten-App kann jetzt Daten in die Datenbank schreiben, diese auslesen und auf dem Display ausgeben. Bisher aber nur Testdaten.

Daher werden wir in der nächsten Lektion unseres SQLite Tutorials die Bedienelemente unserer Android App so überarbeiten, dass sie auf Eingaben der User reagieren. Dadurch wird unsere SQLite App in der Lage sein echte Daten in die Datenbank zu schreiben und somit erstmals sinnvoll nutzbar sein.



Comments 74

  1. Ein sehr hilfreiches Tutorium.

    Nur, wo kommt das Auswahlkästchen her?
    Auch mehrfaches Lesen des Tutoriums hat mich keinen Hinweis darauf finden lassen.

    1. Post
      Author

      Hallo Wole,

      danke für’s Lob!

      das Auswahlkästchen kommt aus der vordefinierten XML-Layout Datei android.R.layout.simple_list_item_multiple_choice die wir für die Zeilen unseres ListViews verwenden. Wir verbinden die Datenquelle mit dem ListView über den ArrayAdapter und geben dabei auch das für die ListView-Zeilen zu verwendende Layout vor.

      ArrayAdapter<ShoppingMemo> shoppingMemoArrayAdapter = new ArrayAdapter<> (
                  this,
                  android.R.layout.simple_list_item_multiple_choice,
                  shoppingMemoList);
      

      Viele Grüße,
      Chris

  2. Super Tutorial, jedoch, warum liegt du den Code der dafür da ist ein neues Product hinzuzufügen in onCreate() von mainActivity ? Dadurch wir immer wenn die App gestarted wird, ein neues Produkt der Datenbank hinzugefügt, so dass Duplikate auftrete, wäre es nicht besser, eine Check durchzuführen, ob gleich viele Elemente hinzugefügt werden sollen wie in der Datenbank drin sind und falls nein(App wird zum ersten mal geöffnet) dann die Datenbank beschreiben und sonst einfach die bestehenden Werte unverändert lässt.

    1. Post
      Author

      Hallo Florian,

      danke für dein Lob!

      Der Code in der onCreate() Methode dient in Teil 4 unseres Android SQLite Tutorials nur zu Testzwecken. Der Testcode wird bereits im nächsten Teil gelöscht, wenn die Callback-Methoden onPause() und onResume() erstellt werden. Dabei wird die onCreate() Methode bereinigt.

      Viele Grüße, Chris

  3. Sehr schöne Anleitung! Es gelingt auch gleich eine andere Tabelle zu erstellen (bei meinen wenigen SQLITE Kenntnissen aus Delphi).

    Ich habe 2 Anmerkungen:
    Bei Punkt 2.4 in Zeile 68 ist ein kleiner Fehler (den man aber schnell bemerkt):
    Statt
    ShoppingMemo shoppingMemo = new ShoppingMemo(product, quantity, id);
    muss es sein:
    ShoppingMemo shoppingMemo = new ShoppingMemo(id, product, quantity);
    [Reihung der Parameter nicht korrekt]

    Dann noch eine Anmerkung:
    Ich mag es nicht, wenn das Telefon die Datenbank irgendwo tief bei der App versteckt. Daher habe ich meiner App einen Pfad, den ich selbst bestimme, hinzugefügt, der jedes Mal beim Start aus einer Datei gelesen wird. Da hat es mich dann etwas Zeit gekostet herauszufinden, wie ich diesen Pfad als Parameter in die DbHelper (bei der Definition des DB_NAME) übergeben kann. Letztlich habe ich die Variable path in der Main Activity als static definiert und mittels MainActivity.path übergeben. Ich dachte schon ich scheitere da, weil in DBHelper, die Variable ja final ist. Funktioniert so aber! UNd ich habe etwas gelernt.
    Nochmals: VIELEN DANK!

    1. Post
      Author

      Hallo Cord,

      vielen Dank für’s Lob und deine beiden Hinweise!

      Hinweis 1: Ich habe Zeile 68 noch einmal genau überprüft. Es muss ShoppingMemo shoppingMemo = new ShoppingMemo(product, quantity, id); heißen, da der Konstruktor unseres Datenmodells ShoppingMemo die Parameter genau in dieser Reihenfolge erwartet: (produkt, quantity, id).

      Hinweis 2: Sehr interessant! Ich habe den Pfad zur Datenbank immer so belassen, wie er standardmäßig vom Android System vorgegeben wird.

      Viele Grüße, Chris

  4. Hallo,

    super Tutorials!
    Aber ich habe ein Problem: ich benötige als Suchkriterium eine übergebene String-Variable. Allerdings bekomme ich bei der Ausführung immer eine exception, syntax error, code 1.

    Wie ist es denn möglich, als Suchkriterium nicht die ID, sondern eine String-Variable zu verwenden?

  5. Danke! Habe selten so gut aufbereite Lernkurse gesehen, und das auch noch gratis…
    Weiter so.

    1. Post
      Author
  6. Zusatz: getAllShoppingMemos funktioniert. Also funktioniert wohl der insert-Befehl. Der Fehler tritt in createShoppingMemo auf -> insert Ok, query -> count 0.

  7. Hi. Auch von mir erstmal ein großes Kompliment für das ausführliche Tutorial. Alles super nachvollziehbar.

    Ich habe dennoch ein Problem mit dem Einfügen des ersten Test-Datensatzes:

    Der insert-Befehl liefert 1 zurück. Wenn ich danach aber den query abschicke und den cursor auswerte, sind keine Daten drin und getcount ist 0. Ich habe den query schon abgewandelt, so dass er alle Daten abfragen soll, dennoch bleibt es bei 0. Ich lasse die App unter Android 7.1.1 Nougat api 25 revision 3 emuliert laufen. Gibt es da Probleme?

    VG Martin

  8. Weiß zwar nicht, ob ich noch eine Antwort erhalten werde, aber folgendes Problem:
    Ich habe bis einschließlich dieses Teil 4 des Tutorials alles 1:1 in Android nachempfunden, allerdings stürzt die App bei mir immer ab. Die letzte korrekt ausgeführte Codezeile ist die „long insertId = database.insert(ShoppingMemoDbHelper.TABLE_SHOPPING_LIST, null, values);“ aus der ShoppingMemoDataSource.java. Dies habe ich mit mehreren normalen Log.d.-Nachrichten überprüfen können.
    Das heißt das Programm steigt beim erstellen des Cursor cursor (…) Objekts aus. Woran könnte das liegen? Ich habe alles genauso gemacht, wie hier in dem Tutorial beschrieben..
    Android Version ist: 2.3.3

    Vielen Dank für die Antworten..

  9. Hi!
    Danke für Deinen Tutorial! Ist sehr ausführlich und schön geschrieben. Ich finde es auch echt gut, dass Du Dir die Zeit genommen hast und alle Schritte mit Screenshots unterlegt hast!

    Eine kleine Ergänzung habe ich dennoch. Du schreibst
    „In Zeile 49 schließen wir den Cursor wieder. Dies ist eine ganz wichtige Anweisung und darf nicht vergessen werden!“

    Aus diesem Grund würde ich es immer im finally-Block machen.

  10. Erstmal ein lob für das gute Tutorial.

    Dann muss ich aber sagen das die App jedes mal bei mir abstürtzt sowohl beim Android-Studio internen Emulator als auch bei meinem Huawei P8 Lite. Es scheint in der ShoppingMemoDataSource.java an der databasequery (Z 50) zu liegen (beim debuggen stürtze es immer danach ab)

    Logcat liefert direkt davor:

    06-14 13:20:15.157 15747-15747/de.programmierenlernenhq.shoppinglisthq E/SQLiteLog: (1) no such table: shopping_list
    06-14 13:20:15.160 15747-15747/de.programmierenlernenhq.shoppinglisthq E/SQLiteDatabase: Error inserting quantity=2 product=Testprodukt
    android.database.sqlite.SQLiteException: no such table: shopping_list (code 1): , while compiling: INSERT INTO shopping_list(quantity,product) VALUES (?,?)
    at android.database.sqlite.SQLiteConnection.nativePrepareStatement(Native Method)
    at android.database.sqlite.SQLiteConnection.acquirePreparedStatement(SQLiteConnection.java:889)
    at android.database.sqlite.SQLiteConnection.prepare(SQLiteConnection.java:500)
    at android.database.sqlite.SQLiteSession.prepare(SQLiteSession.java:588)
    at android.database.sqlite.SQLiteProgram.(SQLiteProgram.java:58)
    at android.database.sqlite.SQLiteStatement.(SQLiteStatement.java:31)
    at android.database.sqlite.SQLiteDatabase.insertWithOnConflict(SQLiteDatabase.java:1472)
    at android.database.sqlite.SQLiteDatabase.insert(SQLiteDatabase.java:1343)
    at de.programmierenlernenhq.shoppinglisthq.ShoppingMemoDataSource.createShoppingMemo(ShoppingMemoDataSource.java:48)
    at de.programmierenlernenhq.shoppinglisthq.MainActivity.onCreate(MainActivity.java:33)
    at android.app.Activity.performCreate(Activity.java:6662)
    

    (zumindest beim emulator, mein handy gibt nicht immer alles zurück)

    Danke schonmal im voraus für jede hilfe.

    1. Post
      Author

      Hallo Julian,

      wie es aussieht, kann die Tabelle nicht gefunden werden. Wurde als Verweis aus die Tabelle die Konstante TABLE_SHOPPING_LIST aus der ShoppingMemoDbHelper Hilfsklasse verwendet?

      long insertId = database.insert(ShoppingMemoDbHelper.TABLE_SHOPPING_LIST, null, values);
      

      Viele Grüße, Chris

  11. Hi,

    ich möchte gerne in einer Activity die Werte der Tabelle hinzufügen und in einer anderen anzeigen lassen. Hab es schon probiert, indem ich die dataSource auf public setze und somit in der anderen Activity auf diese zugreife. Leider stürzt meine App dadurch immer App.

    Hat jemand eine Idee, wie ich sie anzeigen lassen kann?
    Ich habe alles komplett gemacht wie beschrieben.

    Viele Grüße
    Basti

  12. Hallo Chris,

    sehr hilfreiches Tutorial. Ich habe soweit alles für mein Projekt (seeehr klein 🙂 ) umgebaut, und möchte die DB nun mit exestierenden Daten aus einer CSV Datei füllen. Wie stelle ich das besten an? Wo muss ich den Code am besten einfügen?

    Danke im Voraus

    Silvio

  13. Hey Chris,

    Erstmal, ein wirklich klasse Tutorial! Mach weiter so großartige Arbeit 🙂

    Punkt zwei ist, dass bei mir in der ListView leider nicht der Produktname auftaucht 🙁

    Ich habe da immer einen sehr langen Text stehen, der wie folgt aussieht:
    ShoppingMemo@

    Generell stellt sich mir die Frage, woher die Liste weiß, was sie wie anzeigen soll und was nicht. Also wieso werden bei dir x ausgegeben, wo hattest du das definiert?

    Bestem Dank im voraus

    LayoZz

    1. Ich nehme alles zurück und behaupte das Gegenteil!

      Ich habe die Überschriebene toString-Funktion übersehen. Hab den Fehler also selbst behoben.
      Melissa hier in den Kommentaren hatte das selbe Problem. Ich Poste hier nochmal deine Antwort, damit andere sie nicht suchen müssen:

      Hallo Melissa,

      danke für Dein Lob!

      Es könnte an der fehlenden toString() Methode in Deiner Highscore-Klasse liegen. In der Object-Klasse ist die toString()-Methode standardmäßig implementiert. Da sich alle Klassen von der Object-Klasse ableiten, ist diese Methode daher auch bei Deiner Highscore-Klasse vorhanden. Du kannst die toString() Methode nach Deinen Anforderungen implementieren, dann sollte auch der ListView die übergebenen Elemente sinnvoll darstellen. Der ListView nutzt nämlich automatisch die toString() Methode der übergebenen Listen-Objekte bei der textuellen Darstellung.

      Ich hoffe, meine Ausführungen waren hilfreich und verständlich.

      Viele Grüße, Chris

      Damit ist mein Problem gelöst worden (merke: in Zukunft immer ALLE Kommentare lesen ^^)

      Mit bestem Gruß

      LayoZz

  14. Hallo Zusammen,

    erstmal vorab super Tutorial!

    Nun zu meinem Problem/Frage:

    Ich möchte einen von Hand gefüllten Array in einer Applikation durch eine Datenbank/Tabelle ersetzen. Ziel ist es also mit einer Zählvariablen genauso durch die Datenbank zu navigieren und die Werte auszulesen wie aus einem „normalen“ Array.

    final int anweisungsbilderReihe2[][]={
                {R.drawable.ag1_1_2},
                {0},
                {0},
                {0},
                {R.drawable.ag1_5_2},
                {0},
                {R.drawable.ag1_7_2},
                {R.drawable.ag1_8_2},
                {0},
        };
    -------------------------------------------
    agZeichnung1.setImageResource(anweisungsbilderReihe1[ag1_nr][0]);
    
    //ag1_nr ist die Laufvariable zur navigation.
    ------------------------------------------------------------------
    

    Wie schaffe ich es das mir von der Datenbank nur ein expliziter Wert ausgegeben wird(Kein Datensatz den ich einem Listview anzeigen muss)? Und wie navigiere ich dann?

    Ich hoffe mein Problem ist klar geworden und ich freue mich auf Rückmeldung!
    Danke

  15. Hallo zusammen,

    ich habe folgendes Problem: die Activity startet nicht – Fehlermeldung:

    java.lang.RuntimeException: Unable to start activity ComponentInfo{com.example.katja.hundeschulebennemann/com.example.katja.hundeschulebennemann.hundeschule}: java.lang.IllegalStateException: Couldn't read row 0, col -1 from CursorWindow.  Make sure the Cursor is initialized correctly before accessing data from it.
                          at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:3254)
    

    Ich weiß nicht, wo und was ich ändern muss oder was ich vergessen habe.
    Kann mir jemand helfen?

    Viele Grüße, Katja

    1. Post
      Author

      Hallo Katja,

      besteht das Problem noch oder hast du es mittlerweile lösen können?

      Viele Grüße, Chris

  16. Hallo,

    erst einmal vielen Dank für das gute Tutorial! Ich sitze gerade daran es umzusetzen und ich weiß nicht, in welche Klasse ich den Quelltext aus Teil 4 – 1.1 einsetzen muss. Außerdem wird die Methode put der Klasse ContentValues nicht erkannt. Wahrscheinlich eine simple Anfängerfrage, aber ich bin auch Anfänger.

    Vielen Dank schon einmal für die Antwort.

    sabbelschlaeppchen

    1. Okay, dieses Problem hat sich erledigt. Ich hatte noch nicht weitergelesen. 😉 Aber auf jeden Fall: Super Tutorial!

    2. Post
      Author
  17. Hallo,

    bin recht erfreut über das gesamte Tutorial. Es funktioniert auch alles, aber das ListView wird nicht angezeigt. Ich hatte als Test ein eigenes ListView implementiert, hier kann ich ein Array anzeigen, sobald ich aber versuche, nur den Adapter zu ändern, klappt es nicht mehr. Es müßte ja eigentlich das gleiche sein. Ich wollte gerne um den gesamten Quellcode bitten. Die in einem anderen Kommentar oben beschriebenen Zeilen mit dem FragmentManager finde ich hier nirgends in Zusammenhang mit diesem Thema. Es wäre für mich wirklich hilfreich, wenn Du den Quellcode für diese Teil 4 zum Download anbieten könntest. Vielen Dank! Ansonsten der Datenbankteil ist top, mit Programmierkenntnissen in anderen Sprachen, konnte ich das alles sofort auf meine eigenen Belange umsetzen, wirklich toll, aber der Adapter ärgert mich…

    1. Post
      Author

      Hallo Pia,

      es sollte eigentlich problemlos funktionieren. Ich habe dir eine E-Mail mit dem kompletten Projekt geschickt. Leider nicht Teil 4 sondern bis zu Teil 8. Ich hoffe, dass es dir weiterhilft.

      Viele Grüße, Chris

  18. Hi, ich hab ein Problem.
    Wenn ich die App ausführe bringt er mir immer die Meldung:

    android.database.sqlite.SQLiteException: no such table: shopping_list (code 1): , while compiling: SELECT _id, product, quantity FROM shopping_list WHERE _id=-1

    Android 6
    Sony Xperia Z2

    Hab schon alle Codebeispiele in mein Projket kopiert, geht auch nicht.
    Könntest du das komplette Projekt irgendwo hochladen?

    Schon mal vielen dank!

    1. Post
      Author

      Hallo Carsten,

      die Tabelle scheint nicht existent zu sein. Ich würde mir deinen Quellcode gerne mal genauer anschauen und suchen woran es liegt. Dafür benötige ich deine Projektdateien als Zip per E-Mail. Bitte vor dem Packen die beiden build Ordner löschen, die werden nicht benötigt und die Datei wird dadurch viel kleiner. Meine E-Mail Adresse findest du im Impressum.

      Viele Grüße, Chris

    2. Ich habe exakt das gleiche Problem. Konntest du eine Lösung finden?

  19. Zitat:
    „Nun wünschen wir euch viel Spaß bei Teil 5 unseres Android SQLite Datenbank Tutorials. Los geht’s!“

    Ist nur leider der vierte Teil, ich wollte es nur anmerken.
    Der Satz steht vor der ersten Lektion.

    Bitte

    1. Post
      Author
  20. Hallo,

    ich habe jetzt soweit alles „nachgebaut“ allerdings wird bei mir beim Drehen des Smartphones kein neuer Eintrag in die Datenbank geschrieben! Woran kann das liegen? Im Monitor im Android Studio kann ich auch sehen, dass da nichts passiert.

    Hat jemand eine Idee was das sein kann?

    Gruß,
    Zaskar

    1. Post
      Author

      Hallo Zaskar,

      schwierig zu sagen woran es liegt.

      Wenn Du möchtest, kannst Du mir Deine Projektdateien (den ganzen Android Studio Projektordner) als ZIP per E-Mail zusenden. Die E-Mail Adresse kannst Du im Impressum finden. Ich schaue dann mal, ob ich etwas herausfinden kann. Sollte die Zip-Datei zu groß sein, dann schicke nur die Quellcode-Dateien.

      Viele Grüße, Chris

  21. Eines der besten Tutorials, das ich je gesehen habe. Sehr gut erklärt, einfach verständlich und genau richtig ausführlich.
    Vielen Dank für’s zur Verfügung stellen, das hat mir wirklich sehr geholfen!

    1. Post
      Author
  22. Hab das Einfügen in ein Switch onclick eingefügt –

    04-01 18:08:26.249 1522-1522/? E/AndroidRuntime: FATAL EXCEPTION: main
    
    Process: de.tetzisoft.aqayc, PID: 1522
    java.lang.IllegalStateException: Could not execute method for android:onClick
    at android.support.v7.app.AppCompatViewInflater$DeclaredOnClickListener.onClick(AppCompatViewInflater.java:293)
    at android.view.View.performClick(View.java:5198)
    at android.view.View$PerformClick.run(View.java:21147)
    at android.os.Handler.handleCallback(Handler.java:739)
    at android.os.Handler.dispatchMessage(Handler.java:95)
    at android.os.Looper.loop(Looper.java:148)
    at android.app.ActivityThread.main(ActivityThread.java:5417)
    at java.lang.reflect.Method.invoke(Native Method)
    at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:726)
    at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:616)
    Caused by: java.lang.reflect.InvocationTargetException
    at java.lang.reflect.Method.invoke(Native Method)
    at android.support.v7.app.AppCompatViewInflater$DeclaredOnClickListener.onClick(AppCompatViewInflater.java:288)
    at android.view.View.performClick(View.java:5198) 
    at android.view.View$PerformClick.run(View.java:21147)
    

    Die Sache ist die, dass in der Datenbank _id immer null ist 🙁

    1. Post
      Author

      Hallo JimJupiter,

      ich bin aus dem Stacktrace leider nicht schlau geworden und kann die Fehlerursache leider auch nicht rekonstruieren.

      Vielleicht hat ein Leser eine Idee woran es liegen könnte? Vielleicht stimmt etwas mit dem SQL_CREATE String nicht?

      Viele Grüße, Chris

  23. Cursor wirft eine „CursorIndexOutOfBoundsException“ ???

    was nu? woran kann es liegen?

    1. Post
      Author

      Hallo JimJupiter,

      es sieht aus, als ob auf ein nicht existierendes Objekt zugegriffen wird. Kannst Du den gesamten Stacktrace (Fehlermeldung beim Programmabsturz) einmal posten, dann kann man die Absturzursache meist rekonstruieren.

      Viele Grüße, Chris

  24. Hallo Chris,

    erstmal vielen Dank für dieses tolle Tutorial. Hat mir wirklich sehr geholfen.
    Ich habe dennoch das Problem, dass ich gerne meine erstellten Einträge in einer anderen Activity übergeben möchte und dort anzeigen will. Leider hat bis jetzt nichts geklappt wie ich es versucht habe. Vielleicht könnte mir jemand helfen.

    Beste Grüße

    1. Post
      Author

      Hallo Yannick,

      danke für Dein Lob!

      Eine andere Activity kann mit Hilfe eines Intents gestartet werden. Der neuen Activity können beim Starten beliebige Inhalte übergeben werden, die diese dann selbst auslesen und weiterverarbeiten kann.

      Wir haben in folgendem Beitrag Activities und Intents ausführlich beschrieben. Darin zeigen wir auch wie eine Activity mittels expliziten Intent gestartet wird und ihr dabei die Daten des ListView-Eintrags übergeben werden.

      Ich hoffe das hilft Dir etwas weiter.

      Viele Grüße, Chris

    2. Hallo Chris,

      vielen Dank für den Hinweis. Leider konnte ich mein Problem trotzdem nicht lösen :(.
      Mir ist nicht ganz klar wie ich die Liste dem Intent hinzufügen kann….
      Mein Gedanke war, das ich beim Aufruf der ShowAllListEntries(); Methode, einen Intent erzeuge und dort die Liste übergebe. Leider konnte ich noch keinen richtigen Lösungsanstatz hinbekommen. Vielleicht hat du noch einen Tipp wie man die Liste dem Intent hinzufügt ?

      Besten Dank für deine Mühe.

    3. Post
      Author
  25. Hallo Chris,

    vielen Dank für dein ausführliches Tutorial. Es hat mir den Einstieg in die Arbeit mit Datenbanken sehr vereinfacht. Leider stehe ich vor dem Problem anstatt aller Spalten nur eine in dem Listview anzeigen zu lassen. Ich denke, dass es ziemlich einfach ist, aber ich komme einfach nicht drauf. Hier der Quellcode, den ich versucht habe:

    private String [] name = {
            NewPropMemoDbHelper.COLUMN_NAME_NEWPROPPLAN,
            NewPropMemoDbHelper.COLUMN_ID_NEWPROPPLAN
    
        };
    
        @Override
        protected void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            setContentView(R.layout.test);
    
            dataSource = new NewPropMemoDataSource(this);
    
            dataSource.open();
    
            Cursor cursor = database.query(NewPropMemoDbHelper.TABLE_NEWPROPPLAN_LIST, name, null, null, null, null, null);
    
            int idName = cursor.getColumnIndex(NewPropMemoDbHelper.COLUMN_NAME_NEWPROPPLAN);
            int idIndex = cursor.getColumnIndex(NewPropMemoDbHelper.COLUMN_ID_NEWPROPPLAN);
    
            String name = cursor.getString(idName);
            long id = cursor.getLong(idIndex);
    
            Log.d(LOG_TAG, "name: " + name + "&amp; id: " + id);
            cursor.close();
    
            dataSource.close();
    }
    

    Kannst du mir einen Tipp geben oder sagen, was ich falsch mache?

    Viele Grüße,
    David

    1. Post
      Author

      Hallo David,

      es wird wohl an dem String-Array name liegen, den Du in den Zeilen 1 bis 5 definierst. Und zwar, muss darin zuerst die Spalten-ID und anschließend der Spalten-NAME angegeben werden. Etwa so:

      private String[] name = {
          NewPropMemoDbHelper.COLUMN_ID_NEWPROPPLAN,
          NewPropMemoDbHelper.COLUMN_NAME_NEWPROPPLAN
      };
      

      Dann sollte es hoffentlich funktionieren. Falls der Hinweis das Problem nicht löst, kannst Du mir auch den Quellcode Deines Projekts als ZIP-Datei schicken und ich werde mal drüber schauen. Die E-Mail Adresse ist im Impressum angegeben.

      Viele Grüße und viel Erfolg beim Debugging, Chris

  26. Hallo,
    Tolles Tutorial!
    Stehe leider vor dem Problem, dass meine ListView es sehr seltsam ausgibt.
    Habe dieses Tutorial auf meine Highscore Liste angewendet, allerdings sieht meine Ausgabe pro Zeile dann zum Beispiel so aus: Highscore{id=9, name=“xx“, Lvl1=120, ….}
    Woran könnte es liegen?
    Lg

    1. Post
      Author

      Hallo Melissa,

      danke für Dein Lob!

      Es könnte an der fehlenden toString() Methode in Deiner Highscore-Klasse liegen. In der Object-Klasse ist die toString()-Methode standardmäßig implementiert. Da sich alle Klassen von der Object-Klasse ableiten, ist diese Methode daher auch bei Deiner Highscore-Klasse vorhanden. Du kannst die toString() Methode nach Deinen Anforderungen implementieren, dann sollte auch der ListView die übergebenen Elemente sinnvoll darstellen. Der ListView nutzt nämlich automatisch die toString() Methode der übergebenen Listen-Objekte bei der textuellen Darstellung.

      Ich hoffe, meine Ausführungen waren hilfreich und verständlich.

      Viele Grüße, Chris

  27. Hallo,
    Vielen Dank, dein Tutorial hat mir sehr beim Einstieg in Android Studio geholfen.
    Ich möchte allerdings in meiner DB boolean und Date verwenden.
    Das kann der Coursor nicht auslesen. gibt es da einen Trick, dass er das doch kann oder muss ich doch wieder mit Resultset arbeiten. ;(

    1. Post
      Author

      Hallo Barbara,

      danke für Dein Lob!

      Bei boolean kann man leicht mit einer Abfrage prüfen, ob der DB-Wert 0 oder 1 ist und ihn dann entsprechend umwandeln. Etwa so:

      int intBooleanValue = cursor.getInt(idBooleanValue);
      boolean value = (intBooleanValue != 0);
      

      Bei dem Date-Datentyp kann man mit folgendem Beispiel-Quellcode arbeiten:

      Date geburtsdatum;
      try { // Geburtsdatum kann null sein, was beim Zugriff
            // eine Exception werfen würde
          long geburtsdatum = cursor.getLong(idGeburtsdatum);
          geburtsdatum = new Date(geburtsdatum);
      }
      catch(Exception ex) {
          // Geburtsdatum ist nicht gesetzt
          geburtsdatum = null;
      }
      

      Viele Grüße, Chris

    2. Danke für die Antwort.
      Ich habe das genauso als Experiment programmiert. Muss es noch testen.
      Macht mir jetzt Hoffnung, dass das wirklich funktioniert. 🙂

  28. Hallo : )

    zuerst einmal Danke für dieses tolle Tutorial!

    Ich habe es auf meine Bedürfnisse umgeschrieben und möchte statt der Anzahl der Produkte eine Telefonnummer weitergeben. Jedoch bricht bei mir, jedes mal wenn ich die Daten speichern möchte, das App ab.

    Was habe ich falsch gemacht? Liegt es an zu vielen Zahlen, die mitgegeben werden ?

    Lg

    1. Post
      Author

      Hallo Simon,

      danke für das Lob!

      Die Anzahl des Produkts wird als Integer-Datentyp gespeichert. Es kann sein, dass die Telefonnummern eine zu große Integer-Zahl repräsentieren oder dass Sonderzeichen (Leertaste, Schrägstrich) in ihnen enthalten sind und diese natürlich nicht in einer Integer-Variable gespeichert werden können.

      Die größte Integer Zahl ist übrigens 2147483647. Siehe folgender Link: http://www.java2s.com/Tutorial/Java/0040__Data-Type/IntegerMAXMINVALUE.htm

      Viele Grüße, Chris

  29. Hallo und vielen Dank für das schöne Tutorial !
    Bei mir klappt auch alles soweit nach Anleitung.

    Allerdings stehe ich nun vor folgendem Hindernis.
    Ich habe eine Main_activity.class welche ein Fragment hat (Main_activity_fragment.class)
    In diesem Fragment befindet sich aktuell ein custom List view.
    Mit dem im Tutorial angezeigten Code für die Main_activity, welche bei mir ins Fragment muss, klappt das Befüllen des ListViews leider nicht. Jemand ne Idee?

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
    
        ShoppingMemo testMemo = new ShoppingMemo("Birnen", 5, 102);
        Log.d(LOG_TAG, "Inhalt der Testmemo: " + testMemo.toString());
    
        dataSource = new ShoppingMemoDataSource(this);
    
        Log.d(LOG_TAG, "Die Datenquelle wird geöffnet.");
        dataSource.open();
    
        ShoppingMemo shoppingMemo = dataSource.createShoppingMemo("Testprodukt", 2);
        Log.d(LOG_TAG, "Es wurde der folgende Eintrag in die Datenbank geschrieben:");
        Log.d(LOG_TAG, "ID: " + shoppingMemo.getId() + ", Inhalt: " + shoppingMemo.toString());
    
        Log.d(LOG_TAG, "Folgende Einträge sind in der Datenbank vorhanden:");
        showAllListEntries();
    
        Log.d(LOG_TAG, "Die Datenquelle wird geschlossen.");
        dataSource.close();
    }
    
    
    private void showAllListEntries () {
            List shoppingMemoList = dataSource.getAllShoppingMemos();
    
            ArrayAdapter shoppingMemoArrayAdapter = new ArrayAdapter (
                    this,
                    android.R.layout.simple_list_item_multiple_choice,
                    shoppingMemoList);
    
            ListView shoppingMemosListView = (ListView) findViewById(R.id.listview_shopping_memos);
            shoppingMemosListView.setAdapter(shoppingMemoArrayAdapter);
        }
    
  30. Hmm,
    heute habe ich das Programm neu gestartet und bekomme wieder diesen Fehler:

    no such table: shopping_list (code 1): , while compiling: SELECT _id, product, quantity FROM shopping_list WHERE _id=-1

    Hat jemand eine Idee woran das liegt?

    1. Post
      Author

      Hallo Sergej,

      du kannst dir mal die SQLite Datenbank ansehen und schauen wie die Tabelle auf dem Android Gerät tatsächlich erstellt wurde. Hier wird erklärt wie man die Datenbank betrachten kann:

      https://www.quora.com/How-do-I-see-database-tables-in-Android-Studio

      Vielleicht hat sich auch ein Tippfehler in deinen Befehle SQL_CREATE eingeschlichen und es fehlt ein Leerzeichen.

      Wenn du die Datenbank neu erzeugen möchtest, musst du vorher die App von deinem Android Gerät deinstallieren und anschließend die App neu aufspielen.

      Viele Grüße, Chris

  31. Beim Starten des Apps bekommt _id den Wert „-1“:
    java.lang.RuntimeException: Unable to start activity ComponentInfo{de.xxxxx.shoppinglist/de.xxxxxx.shoppinglist.MainActivity}: android.database.sqlite.SQLiteException: no such table: shopping_list (code 1): , while compiling: SELECT _id, product, quantity FROM shopping_list WHERE _id=-1

    1. Gefixt: in class ShoppingMemoDataSource schließe ich sicherheitshalber dbHelper for dem Öffnen ->

      public void open() {
              /* Workaround wegen folgenden Fehler:
                 'android.database.sqlite.sqliteexception no such table (code 1) while compiling...' */
              dbHelper.close();
      
              Log.d(LOG_TAG, "Eine Referenz auf die Datenbank wird jetzt angefragt.");
              database = dbHelper.getWritableDatabase();
              Log.d(LOG_TAG, "Datenbank-Referenz erhalten. Pfad zur Datenbank: " + database.getPath());
          }
      
    2. Post
      Author

      Hallo Sergej,

      danke für dein Feedback. Gut wenn es bei dir jetzt funktioniert.

      Viele Grüße, Chris

  32. Hallo Chris,

    danke sehr für diese Tutorial!
    Eine Frage Noch:
    Wenn ich MainActivity.java von AppCompatActivity ableite und dazu „import android.support.v7.app.AppCompatActivity;“ importiere, beschweret sich AndroidStudio und bitet an „Find JAR on Web“. Wenn ich das auswähle, dann kriege ich eine Meldung „no libraries found for …“
    Weist du zufällig woran das liegen kann?

    Gruß
    Sergej

  33. Pingback: Android SQLite Tutorial - Teil 1: SQLite Projekt anlegen

  34. Sehr schöne Tutorials!
    Danke – dass Du Dir die Mühe machst, Android-Einsteigern wie mir Grundlagen und Zusammenhänge so detailliert zu erklären – ein ganz großes Lob!

    1. Post
      Author

      Hallo Kerona,

      es freut mich sehr, wenn die Tutorials verständlich und hilfreich sind. Danke für das Lob!

      Viele Grüße, Chris

  35. Hallo Chris,

    ein wirklich tolles und hilfreiches Tutorial!
    Ich bin seit etwa 4 Jahren eine Lotus Notes Programmierer und wollte nun mal anfangen mir anzuschauen, wie man Android Apps programmiert, da ich daran großes Interesse habe.
    Deine Tutorials sind mir dabei eine große Hilfe gut in dieses Thema einsteigen zu können.
    Ich freue mich schon auf deine weiteren Anleitungen!

    Viele Grüße

    Dennis

    PS: Gibt es einen Newsletter um benachrichtigt zu werden sobald es etwas neues gibt und weißt du schon wann du etwa mit diesem Tutorial durch bist?

    1. Post
      Author

      Hallo Dennis,

      danke für das Lob! Ja, Android ist ein sehr spannendes Thema und der Einstieg lohnt sich.

      Einen Newsletter gibt es momentan nicht. Für dieses Tutorial erstelle ich gerade Teil 5 und weitere Teile befinden sich noch in der Planungsphase. Der fünfte Teil wird wahrscheinlich innerhalb der nächsten zwei Wochen erscheinen.

      Viele Grüße, Chris

  36. Hallo Chris,

    vielen Dank für deine großartigen Tutorials!
    Super gestaltet, übersichtlich und einfach zu verstehen. So machen die ersten Schritte in der Android-Programmierung wirklich Spaß.

    Ich freue mich schon auf Teil 5! 🙂

    Gruß Marcel

    1. Post
      Author

      Hallo Marcel,

      vielen Dank für die lobenden Worte! Teil fünf wird gerade erstellt.

      Viele Grüße, Chris

  37. Pingback: Android SQLite Tutorial - Teil 2: SQLite Datenbank integrieren

Schreibe einen Kommentar

Deine E-Mail-Adresse wird nicht veröffentlicht.