3. Persistenz und Datenbanken

Werbung
3. Persistenz und Datenbanken
Lernziele
3. Persistenz und Datenbanken
Themen/Lernziele:
• Einstellungen
• Dateien lesen und schreiben
• Datenbanken mit SQLite
• Allgemeine Schnittstelle zu Datenquellen: Content Provider
Mobile Informationssysteme I — Hochschule Bonn-Rhein-Sieg, Sommersemester 2012
189
3. Persistenz und Datenbanken
Lernziele
Android Technologien zur persistenten Speicherung
• Shared Preferences: Schlüssel/Wert-Paare
• Files: Schreiben und lesen von Dateien mit der Java-API, Speicherung
intern oder auf Speicherkarte
• SQLite Datenbanken: Jede Anwendung kann ihre eigene SQLite Datenbank verwalten
• Content Provider: Allgemeine Schnittstelle für den Datenzugriff und die
Manipulation über Anwendungsgrenzen hinweg
Mobile Informationssysteme I — Hochschule Bonn-Rhein-Sieg, Sommersemester 2012
190
3. Persistenz und Datenbanken
Shared Preferences
Speicherung von Schlüssel/Wert-Paaren
Prinzipiell zwei Techniken:
• SharedPreferences: persistente Speicherung der Paare, Zugriff innerhalb des selben Kontextes
• Bundle: Speicherung von Paaren zur Sicherung von Activity-Zuständen
Mobile Informationssysteme I — Hochschule Bonn-Rhein-Sieg, Sommersemester 2012
191
3. Persistenz und Datenbanken
Shared Preferences
Shared Preferences
• Klasse SharedPreferences
• Zugriff über den Kontext mit der Methode getSharedPreferences()
• Parameter: Name für eine Sammlung von Schlüssel/Wert-Paaren, Modus
• Beispiel:
SharedPreferences myPrefs = getSharedPreferences("myPrefs",
Activity.MODE_PRIVATE);
Mobile Informationssysteme I — Hochschule Bonn-Rhein-Sieg, Sommersemester 2012
192
3. Persistenz und Datenbanken
Shared Preferences
• Physische Speicherung in:
/data/data/package /shared prefs/myPrefs.xml
• Lesender Zugriff auf die Paare: getXXX(), wobei XXX für einen Datentyp
steht.
• Beispiele:
boolean
float
int
String
boolPref = myPrefs.getBoolean("booleanPref", false);
lastFloat = myPrefs.getFloat("lastFloat", 0f);
gameLevel = myPrefs.getInt("gameLevel", 1);
email = myPrefs.getString("email", "[email protected]");
• 1. Parameter: Schlüssel, 2. Parameter: Default-Wert
Mobile Informationssysteme I — Hochschule Bonn-Rhein-Sieg, Sommersemester 2012
193
3. Persistenz und Datenbanken
Shared Preferences
Änderungen von Shared Preferences
• Mittels SharedPreferences.Editor
• Editor mit Methode edit() erzeugen:
SharedPreferences.Editor editor = myPrefs.edit();
• Zur Speicherung: putXXX()
• 1. Parameter: Schlüssel, 2. Parameter: neuer Wert
Mobile Informationssysteme I — Hochschule Bonn-Rhein-Sieg, Sommersemester 2012
194
3. Persistenz und Datenbanken
Shared Preferences
• Beispiel:
editor.putBoolean("booleanPref", true);
editor.putFloat("lastFloat", 1f);
editor.putInt("gameLevel", 2);
editor.putString("email", "[email protected]");
• Zur Sicherung der Änderungen: commit()
editor.commit();
Mobile Informationssysteme I — Hochschule Bonn-Rhein-Sieg, Sommersemester 2012
195
3. Persistenz und Datenbanken
Shared Preferences
Shared Preferences für Einstellungs-Dialoge
• Layout-Klasse für Einstellungs-Dialog: PreferenceScreen
• Views für Einstellungen: z.B. CheckBoxPreference, ListPreference
• Allgemeine Attribute:
– android:key: Der Schlüssel
– android:title: Titel für die Einstellung (groß)
– android:summary: Erläuterung für die Einstellung (klein, unterhalb
von Titel)
– android:defaultValue: voreingestellter Wert
Mobile Informationssysteme I — Hochschule Bonn-Rhein-Sieg, Sommersemester 2012
196
3. Persistenz und Datenbanken
Shared Preferences
• Zusätzliche Attribute für ListPreference:
– android:entries: Array (String) der anzuzeigenden Listeneinträge
(Texte, sprachspezifisch)
– android:entryValues: Array mit den Werten zu den Einträgen (sprachunabhängig)
– android:dialogTitle: Titel zur Auswahlliste
Mobile Informationssysteme I — Hochschule Bonn-Rhein-Sieg, Sommersemester 2012
197
3. Persistenz und Datenbanken
Shared Preferences
<?xml version="1.0" encoding="UTF-8"?>
<PreferenceScreen xmlns:android="http://schemas.android.com/apk/res/andro
<CheckBoxPreference
android:key="entrydialog"
android:title="@string/set_entrydiag_title"
android:summary="@string/set_entrydiag_summary"
android:defaultValue="true"/>
<ListPreference
android:key="cursorform"
android:title="@string/set_cursor_title"
android:summary="@string/set_cursor_summary"
android:entries="@array/cursor_forms"
android:entryValues="@array/cursor_form_values"
android:defaultValue="block"
android:dialogTitle="@string/set_cursor_dialog_title"/>
<ListPreference
Mobile Informationssysteme I — Hochschule Bonn-Rhein-Sieg, Sommersemester 2012
198
3. Persistenz und Datenbanken
Shared Preferences
android:key="defsqform"
android:title="@string/set_defsquare_title"
android:summary="@string/set_defsquare_summary"
android:entries="@array/defsquare_forms"
android:entryValues="@array/defsquare_form_values"
android:defaultValue="block"
android:dialogTitle="@string/set_defsquare_dialog_title"/>
</PreferenceScreen>
Mobile Informationssysteme I — Hochschule Bonn-Rhein-Sieg, Sommersemester 2012
199
3. Persistenz und Datenbanken
Mobile Informationssysteme I — Hochschule Bonn-Rhein-Sieg, Sommersemester 2012
Shared Preferences
200
3. Persistenz und Datenbanken
Shared Preferences
Activity für Einstellungs-Dialoge
• PreferenceActivity als Unterklasse von Activity
• Üblicherweise bildet man wiederum Unterklasse von PreferenceActivity
• Import des Einstellungs-Layout in onCreate() mittels
addPreferencesFromResource()
• Gute Vorgehensweise: Für jede Einstellung eine Klassenmethode für die
Abfrage anbieten, evtl. auch für Änderung
• Zugriff auf SharedPreferences mit Hilfe des PreferenceManager
Mobile Informationssysteme I — Hochschule Bonn-Rhein-Sieg, Sommersemester 2012
201
3. Persistenz und Datenbanken
Shared Preferences
• Beispiel lesen:
public static boolean getEntryDialog(Context context) {
return PreferenceManager.getDefaultSharedPreferences(context).
getBoolean(ENTRY_DIALOG_KEY, ENTRY_DIALOG_DEFAULT);
}
• Beispiel schreiben:
public static void putEntryDialog(Context context, boolean value) {
SharedPreferences.Editor editor = PreferenceManager.
getDefaultSharedPreferences(context).edit();
editor.putBoolean(ENTRY_DIALOG_KEY, value);
editor.commit();
}
Mobile Informationssysteme I — Hochschule Bonn-Rhein-Sieg, Sommersemester 2012
202
3. Persistenz und Datenbanken
Shared Preferences
• Zum Starten der PreferenceActivity:
public void onShowSettings() {
startActivity(new Intent(this,SettingsLayout.class));
}
SettingsLayout ist hier von PreferenceActivity abgeleitet.
• Nicht vergessen: Manifest erweitern!
<activity android:name=".SettingsLayout" android:label="Settings">
</activity>
Mobile Informationssysteme I — Hochschule Bonn-Rhein-Sieg, Sommersemester 2012
203
3. Persistenz und Datenbanken
Lesen und Schreiben von Dateien
Statische Dateien als Ressourcen
• Dateien in Verzeichnis res/raw/ ablegen, z.B. res/raw/meineDatei
• Es wird automatisch erzeugt: R.raw.meineDatei
• Zugriff über Resources und die Methode openRawResource():
Resources res = getResources();
InputStream meineDatei = res.openRawResource(R.raw.meineDatei);
• nur lesender Zugriff
• mit Streams die üblichen Operation aus java.io möglich
Mobile Informationssysteme I — Hochschule Bonn-Rhein-Sieg, Sommersemester 2012
204
3. Persistenz und Datenbanken
Lesen und Schreiben von Dateien
Aufbau/Zugriff Dateisystem
• Anwendungsverzeichnis:
/data/data/package /
• In das Anwendungsverzeichnis darf nur die Anwendung selbst schreiben!
• Spezielle API-Methoden aus android.content.Context erforderlich
• Verschiedene Unterverzeichnisse möglich
• Alternative: SD-Karte
Mobile Informationssysteme I — Hochschule Bonn-Rhein-Sieg, Sommersemester 2012
205
3. Persistenz und Datenbanken
Lesen und Schreiben von Dateien
• SD-Karte erreichbar via /sdcard
• Nutzung der gewöhnlichen java.io Methoden
Mobile Informationssysteme I — Hochschule Bonn-Rhein-Sieg, Sommersemester 2012
206
3. Persistenz und Datenbanken
Lesen und Schreiben von Dateien
Zugriff auf Dateien im Anwendungsverzeichnis
• FileOutputStream oder FileInputStream erzeugen mit Instanzmethoden openFileOutput() oder openFileInput() (Paket
android.content.Context)
• Beispiel:
FileOutputStream fos = openFileOutput("myFile.txt", MODE_PRIVATE);
FileInputStream fis = openFileInput("myOtherFile.txt");
• Pfadnamen darf / nicht enhalten! Ansonsten Exception
• Bei openFileOutput() wird Datei automatisch neu angelegt oder überschrieben.
Mobile Informationssysteme I — Hochschule Bonn-Rhein-Sieg, Sommersemester 2012
207
3. Persistenz und Datenbanken
Lesen und Schreiben von Dateien
• Anhängen statt Überschreiben: Context.MODE APPEND beim zweiten
Parameter
• Physische Ablage in Verzeichnis /data/data/package /lib
• Bei MODE PRIVATE kein Sharing zwischen Anwendungen
• Alternativen: Flags MODE WORLD READABLE, MODE WORLD WRITEABLE,
verknüpfbar
Mobile Informationssysteme I — Hochschule Bonn-Rhein-Sieg, Sommersemester 2012
208
3. Persistenz und Datenbanken
Lesen und Schreiben von Dateien
Datei-Management: Anwendungsverzeichnis
siehe android.content.Context, Beispiele:
• fileList() liefert ein String-Array mit Dateinamen zur Anwendung
• deleteFile(): Löschen von Dateien
• getFilesDir(): Liefert den Pfad, in dem die Dateien der Anwendung
abgelegt werden, als Instanz von java.io.File
• getDir(): Liefert ein Unterverzeichnis zum Anwendungsverzeichnis als
Instanz von java.io.File
Mobile Informationssysteme I — Hochschule Bonn-Rhein-Sieg, Sommersemester 2012
209
3. Persistenz und Datenbanken
Lesen und Schreiben von Dateien
Datei in öffentlichem Unterverzeichnis anlegen
File pubVerz = getDir("Personal" | MODE_WORLD_READABLE
| MODE_WORLD_WRITEABLE);
File akte = new File(pubVerz, "akte.txt");
FileOutputStream out = new FileOutputStream(akte);
...
• Berechtigungen des Verzeichnisses gelten nicht für die Datei!
• Ablage in /data/data/package /app Personal
Mobile Informationssysteme I — Hochschule Bonn-Rhein-Sieg, Sommersemester 2012
210
3. Persistenz und Datenbanken
Lesen und Schreiben von Dateien
Dateien aus Unterverzeichnis lesen
File pubVerz = getDir("Personal" | MODE_WORLD_READABLE
| MODE_WORLD_WRITEABLE);
File akte = new File(pubVerz, "akte.txt");
FileInputStream out = new FileInputStream(akte);
...
Mobile Informationssysteme I — Hochschule Bonn-Rhein-Sieg, Sommersemester 2012
211
3. Persistenz und Datenbanken
Lesen und Schreiben von Dateien
Dateien aus Anwendungsverzeichnis/Unterverzeichnis
löschen
• Dateien, die mit openFileOutput() erzeugt wurden, werden mit
deleteFile() gelöscht.
• Alle anderen Dateien wirden mit der Methode delete() der Klasse
java.io.File gelöscht.
Mobile Informationssysteme I — Hochschule Bonn-Rhein-Sieg, Sommersemester 2012
212
3. Persistenz und Datenbanken
Lesen und Schreiben von Dateien
Zugriff auf die SD-Karte
• Eintrag der notwendigen Permission im Manifest:
<uses-permission
android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
• Für Zugriff gewöhnliche Methoden aus Paket java.io.
• Nützliche Methoden aus Paket android.os:
– getExternalStorageDirectory() liefert das Wurzelverzeichnis der
SD-Karte als Instanz von java.io.File
– getExternalStorageState() liefert Informationen zur Verfügbarkeit
Mobile Informationssysteme I — Hochschule Bonn-Rhein-Sieg, Sommersemester 2012
213
3. Persistenz und Datenbanken
Datenbanken mit SQLite
Datenbanken mit SQLite
• Open Source
• weitgehend konform zum Standard SQL-92
• leichtgewichtig
• Einbindung über C-Bibliothek
• Weitere Informationen: www.sqlite.org
Mobile Informationssysteme I — Hochschule Bonn-Rhein-Sieg, Sommersemester 2012
214
3. Persistenz und Datenbanken
Datenbanken mit SQLite
Manifest Typing
In manifest typing, the datatype is a property of the value itself, not
of the column in which the value is stored. SQLite thus allows the
user to store any value of any datatype into any column regardless of
the declared type of that column.
☞ Die Angabe der Datentypen bei create table sind nur ein Hinweis an
die Datenbank, sie müssen nicht eingehalten werden.
Mobile Informationssysteme I — Hochschule Bonn-Rhein-Sieg, Sommersemester 2012
215
3. Persistenz und Datenbanken
Datenbanken mit SQLite
Keine Unterstützung von ...
• Java Database Connectivity (JDBC)
• referentielle Integrität (foreign key)
• bestimmte Join-Arten wie right outer join und full outer join
• bestimmte Arten von alter table Anweisungen
Mobile Informationssysteme I — Hochschule Bonn-Rhein-Sieg, Sommersemester 2012
216
3. Persistenz und Datenbanken
Datenbanken mit SQLite
Anlegen/Öffnen einer Datenbank
• üblicherweise mittels
SQLiteOpenHelper
einer
Instanz
einer
Unterklasse
von
• Konstruktorparameter von SQLiteOpenHelper:
–
–
–
–
Context, z.B. die Activity
Name der Datenbank
Instanz einer Cursor-Factory, wenn nicht notwendig == null
Versionsnummer der Datenbank
Mobile Informationssysteme I — Hochschule Bonn-Rhein-Sieg, Sommersemester 2012
217
3. Persistenz und Datenbanken
Datenbanken mit SQLite
• In Unterklasse überschreibt man die folgenden Methoden von
SQLiteOpenHelper:
– public void onCreate(SQLiteDatabase db)
Wird aufgerufen, wenn die Datenbank bisher nicht existiert. Enthält
typischerweise Anweisungen zum Erzeugen der Datenbank-Relationen.
– public void onUpgrade(SQLiteDatabase db, int oldVersion, int
newVersion)
Wird aufgerufen, wenn beim Öffnen der Datenbank eine höhere Versionsnummer angegeben wird, als beim letzten Öffnen. Enthält Anweisungen zum Upgrade der Datenbank auf newVersion.
Mobile Informationssysteme I — Hochschule Bonn-Rhein-Sieg, Sommersemester 2012
218
3. Persistenz und Datenbanken
Datenbanken mit SQLite
• Methoden von SQLiteOpenHelper zum Anlegen/Öffnen einer Datenbank:
– public SQLiteDatabase getWriteableDatabase()
Create and/or open a database that will be used for reading and
writing.
– public SQLiteDatabase getReadableDatabase()
Create and/or open a database.
• Ohne Nutzung von SQLiteOpenHelper: Mittels der Methode
public SQLiteDatabase openOrCreateDatabase(String name, int
mode, SQLiteDatabase.CursorFactory factory)
auf Context-Objekt
Mobile Informationssysteme I — Hochschule Bonn-Rhein-Sieg, Sommersemester 2012
219
3. Persistenz und Datenbanken
Datenbanken mit SQLite
Methoden für SQLiteDatabase
Einige Methoden zur Verwaltung und Transaktionssteuerung:
• void close()
• void beginTransaction()
• void endTransaction()
• int getVersion()
• boolean isOpen()
Mobile Informationssysteme I — Hochschule Bonn-Rhein-Sieg, Sommersemester 2012
220
3. Persistenz und Datenbanken
Datenbanken mit SQLite
DDL-Anweisungen
• SQL-Anweisungen, die keine Anfragen sind, können stets mittels
public void execSQL(String sql)
ausgeführt werden.
• z. B. create table, insert, etc.
• Keine Unterstützung mehrerer Anweisungen!
• Ungültige SQL-Anweisungen lösen eine SQLException aus.
Mobile Informationssysteme I — Hochschule Bonn-Rhein-Sieg, Sommersemester 2012
221
3. Persistenz und Datenbanken
Datenbanken mit SQLite
Anfragen
Möglichkeiten zur Durchführung von Anfragen:
• Raw Queries
• Regular Queries
• mit Hilfe eines SQLiteQueryBuilder
Mobile Informationssysteme I — Hochschule Bonn-Rhein-Sieg, Sommersemester 2012
222
3. Persistenz und Datenbanken
Datenbanken mit SQLite
Raw Queries
• public Cursor rawQuery (String sql, String[] selectionArgs)
• SQL-Anfrage: sql
• falls sql Anfrage vollständig qualifiziert, dann ist selectionArgs ==
null
• sql kann in WHERE-Klausel “?” als Platzhalter für Parameter enthalten
dann Übergabe der Parameterwerte mit Hilfe von selectionArgs
Mobile Informationssysteme I — Hochschule Bonn-Rhein-Sieg, Sommersemester 2012
223
3. Persistenz und Datenbanken
Datenbanken mit SQLite
Regular Queries
public Cursor query (boolean distinct,
String table, String[] columns,
String selection, String[] selectionArgs,
String groupBy, String having,
String orderBy, String limit)
• distinct: Duplikatelimination oder nicht
• table: Relationenname
• columns: Spaltennamen für die Projektion
• selection: Tupelbedingung, kann “?” als Platzhalter enthalten
Mobile Informationssysteme I — Hochschule Bonn-Rhein-Sieg, Sommersemester 2012
224
3. Persistenz und Datenbanken
Datenbanken mit SQLite
• selectionArgs: Parameter für die Platzhalter in selection
• groupBy: Spaltennamen für die Gruppierung
• having: Gruppenbedingung
• orderBy: Festlegung der Reihenfolge der Tupel
• limit: Maximale Anzahl an Tupeln, die die Anfrage liefern soll
Mobile Informationssysteme I — Hochschule Bonn-Rhein-Sieg, Sommersemester 2012
225
3. Persistenz und Datenbanken
Datenbanken mit SQLite
Cursor
• Query liefert eine Cursor-Instanz
• Ein Cursor ist ein Fenster auf das Ergebnis einer Anfrage: jeweils ein
Tupel ist das aktuelle Tupel
• Cursor stellt Methoden zur Navigation innerhalb des Ergebnisses bereit
• Weiterhin Methoden für den Zugriff auf die Werte des aktuellen Tupels
Mobile Informationssysteme I — Hochschule Bonn-Rhein-Sieg, Sommersemester 2012
226
3. Persistenz und Datenbanken
Datenbanken mit SQLite
Cursormethoden
• public boolean moveToFirst()
Setzt den Cursor auf das erste Tupel der Ergebnismenge.
• public boolean moveToNext()
Setzt den Cursor auf das nächste Tupel der Ergebnismenge.
• public boolean moveToPrevious()
Setzt den Cursor auf das vorhergehende Tupel der Ergebnismenge.
• public int getCount()
Liefert die Anzahl der Tupel in der Ergebnismenge.
Mobile Informationssysteme I — Hochschule Bonn-Rhein-Sieg, Sommersemester 2012
227
3. Persistenz und Datenbanken
Datenbanken mit SQLite
• public int getColumnIndex(String colName)
Liefert den Spaltenindex zu einem Spaltennamen.
• public String getColumnName(int colIndex)
Liefert den Spaltennamen zu einem Spaltenindex.
• public String[] getColumnNames()
Liefert ein Feld der Spaltennamen.
• Für die Ermittlung der Werte stehen Getter-Methoden in Abhängigkeit
vom Datentyp zur Verfügung:
public Datentyp getDatentyp (int spaltenIndex)
Datentypen: int, long, short, double, float, String
Mobile Informationssysteme I — Hochschule Bonn-Rhein-Sieg, Sommersemester 2012
228
3. Persistenz und Datenbanken
Datenbanken mit SQLite
• public void close()
Schließen des Cursors.
• Mit Hilfe der Methoden deactivate() und requery() kann ein Cursor
vorübergehend deaktiviert und anschließend wieder aktualisiert werden.
Mobile Informationssysteme I — Hochschule Bonn-Rhein-Sieg, Sommersemester 2012
229
3. Persistenz und Datenbanken
Datenbanken mit SQLite
DML-Anweisungen
• DML: Data Manipulation Language
• Insert, Update, Delete
• Immer möglich mittels execSQL()
• Nachteil: Komplette SQL-Anweisung muss als String aufgebaut werden.
• Alternative: ContentValues
Mobile Informationssysteme I — Hochschule Bonn-Rhein-Sieg, Sommersemester 2012
230
3. Persistenz und Datenbanken
Datenbanken mit SQLite
ContentValues
• Dient eigentlich zur Speicherung von Werten, die ein ContentResolver
verarbeiten kann.
• Auch für SQLite-Datenbanken einsetzbar.
• Schema zum Einfügen eines neuen Tupels:
ContentValues tupel = new ContentValues();
tupel.put(Spalten-Name , Wert );
...
db.insert(Tabellen-Name , null, tupel);
Mobile Informationssysteme I — Hochschule Bonn-Rhein-Sieg, Sommersemester 2012
231
3. Persistenz und Datenbanken
Datenbanken mit SQLite
• Update mit Hilfe von:
db.update(Tabellen-Name, tupel, where, null)
where: Selektionsbedingung analog zur WHERE-Klausel, um die zu ändernden Tupel zu bestimmen.
• Delete analog mit:
db.delete(Tabellen-Name, where, null)
Mobile Informationssysteme I — Hochschule Bonn-Rhein-Sieg, Sommersemester 2012
232
Herunterladen