Einlesen der vollständigen Ball-Liste in die SQLite Datenbank
Die vollständige Ball-Liste verwalte ich bisher in einer Excel-Datei.
Frage 1: Wie bekomme ich die Excel-Daten in die Android-Applikation?
Die Antwort ist einfach: Die Excel-Daten werden in eine ASCII-Datei exportiert und als Resource (in Android als Assets bezeichnet) ins Projekt kopiert.
Zur Speicherung der strukturierten Ball-Daten in einer ASCII-Datei wähle ich ein JSON-Datenformat. JSON erlaubt genau wie XML die Definition einer eigenen Datenstruktur, benötigt dafür aber deutlich weniger Platz, da die schließenden Tags wegfallen. Außerdem ist JSON ein gängiges Datei-Format und kann von Android gut verarbeitet werden (wie wir später noch sehen werden).
Die JSON-Daten lassen sich mit Excel gut generieren. Auf Details dazu will ich jetzt hier nicht näher eingehen, wen das interessiert, der möge sich bitte melden. Als kleiner Tipp: die Excel-Funktion
VERKETTEN
hilft. Die ASCII-Datei
ballliste.json
sieht wie folgt aus:[{hrst: "3D", name: "BOF BM 2007 Catherine Massem", gr: "k", l: "l", s: "7", h: "", gw: "41"}, {hrst: "3D", name: "BOF BMM 2008 GSP Malonne", gr: "k", l: "l", s: "15", h: "", gw: "42"}, {hrst: "3D", name: "BOF DkJM 2005 Oliver Rex Wiile", gr: "k", l: "l", s: "1", h: "", gw: "40"}, ... {hrst: "", name: "T4", gr: "k", l: "r", s: "79", h: "", gw: "30"}]
Jedes Ball-Element besteht aus einer komma-separierten Liste von Name-Wert-Paaren und wird begrenzt von geschweiften Klammern. Die eckigen Klammern am Anfang und Ende definieren die Liste der einzelnen Ball-Elemente, ebenfalls komma-separiert.
Die JSON-Datei lege ich im Verzeichnis
/assets
in meinem Android-Projekt ab.Frage 2: Wie lese ich die ASCII-Datei ein?
Das Einlesen von Dateien erfolgt in Android weitestgehend analog zu Java - genauso umständlich.
Den Zugriff auf die Asset-Datei erhalte ich über den Android Context, also über meine Activity. Über die Methode
getAssets()
bekomme ich den AssetManager
. Dieser stellt mir wiederum die Methode open(String fileName)
zur Verfügung, über die ich Asset-Dateien, also Dateien die im Verzeichnis /assets
abgelegt sind, öffnen kann. Ich erhalte als Ergebnis einen InputStream
.Um die Datei einigermaßen komfortabel einlesen zu können, kapsele ich den
InputStream
in einen InputStreamReader
und diesen wiederum in einen BufferedReader
. So kann ich den Inhalt der Datei zeilenweise einlesen und in einem StringBuffer
sammeln.private String readJSONBallliste(Context context) { StringBuffer content = new StringBuffer(); try { BufferedReader reader = new BufferedReader( new InputStreamReader( context.getAssets().open("ballliste.json"))); String nextLine = reader.readLine(); while (nextLine != null) { content.append(nextLine).append("\n"); nextLine = reader.readLine(); } } catch (IOException e) { Log.e(LOG_TAG, "Fehler beim Lesen der JSON-Datei", e); } return content.toString(); }
Frage 3: Wie parse ich die JSON-Daten?
Das parsen der JSON-Daten ist in Android relativ einfach. Android bringt dafür die notwendigen Klassen im Package
org.json
bereits mit.Bei meinem JSON-String handelt es sich um eine Liste von Objekten. Daher verwende ich ein
JSONArray
welches ich mit dem JSON-String initialisiere. Das JSONArray
stellt die üblichen Methoden eines Arrays bzw. einer Liste bereit, die ich verwenden kann um durch die Liste zu iterieren. Leider implementiert das JSONArray
kein Iterator
oder Iterable
Interface, so dass ich den altmodischen Weg gehen muss.JSONArray jsonArray = new JSONArray( readJSONBallliste(context)); for (int i = 0; i < jsonArray.length(); i++) { JSONObject nextBall = (JSONObject) jsonArray.getJSONObject(i); Log.d(LOG_TAG, nextBall.getString("hrst") + " - " + nextBall.getString("name")); ... }Über die Methode
getJSONObject(int index)
lassen sich die einzelnen Ball-Elemente aus dem JSONArray
auslesen. Das JSONObject
stellt eine Reihe von Methoden zur Verfügung um zu einem Attribut-Namen den entsprechenden Wert abzufragen.
Schreiben der JSON-Daten in die SQLite Datenbank
Jetzt muss ich nur noch die Daten aus den JSONObject
en verarbeiten indem ich sie in die Datenbank schreibe. Die vollständige Methode dazu sieht wie folgt aus:
private void createData(SQLiteDatabase db) { Log.d(LOG_TAG, "Create Data..."); String insert = "INSERT INTO " + TABLE_BAELLE + " ( " + KEY_BALL_ID + ", " + KEY_BALL_FULL_NAME + " ) VALUES ( ?, ? );"; try { JSONArray jsonArray = new JSONArray( readJSONBallliste(context)); for (int i = 0; i < jsonArray.length(); i++) { JSONObject nextBall = (JSONObject) jsonArray.getJSONObject(i); Log.d(LOG_TAG, nextBall.getString("hrst") + " - " + nextBall.getString("name")); db.execSQL(insert, new String[] { String.valueOf(i), nextBall.getString("name") }); } } catch (JSONException e) { Log.e(LOG_TAG, "Fehler beim parsen der JSON-Daten", e); } }Ich rufe die Methode beim initialen Anlegen der Datenbank auf, also in der
onCreate(SQLiteDatabase db)
Methode meines BallDbAdapter
s. Dem muss ich beim Initialisieren aus der Activity noch die Activity als Context mitgeben, damit ich Zugriff auf den AssetManager
habe.
Nach dem starten meiner App wird die Ball-Liste in die Datenbank geschrieben und die Liste mit den Ball-Namen wird angezeigt.
