3. Persistenz und Datenbanken - www2.inf.h

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
Entwicklung mobiler Anwendungen — Europäische Fachhochschule Brühl/Neuss, 3. Quartal 2014
202
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
Entwicklung mobiler Anwendungen — Europäische Fachhochschule Brühl/Neuss, 3. Quartal 2014
203
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
Entwicklung mobiler Anwendungen — Europäische Fachhochschule Brühl/Neuss, 3. Quartal 2014
204
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);
Entwicklung mobiler Anwendungen — Europäische Fachhochschule Brühl/Neuss, 3. Quartal 2014
205
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
Entwicklung mobiler Anwendungen — Europäische Fachhochschule Brühl/Neuss, 3. Quartal 2014
206
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
Entwicklung mobiler Anwendungen — Europäische Fachhochschule Brühl/Neuss, 3. Quartal 2014
207
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();
Entwicklung mobiler Anwendungen — Europäische Fachhochschule Brühl/Neuss, 3. Quartal 2014
208
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
Entwicklung mobiler Anwendungen — Europäische Fachhochschule Brühl/Neuss, 3. Quartal 2014
209
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
Entwicklung mobiler Anwendungen — Europäische Fachhochschule Brühl/Neuss, 3. Quartal 2014
210
3. Persistenz und Datenbanken
Shared Preferences
<?xml version="1.0" encoding="UTF-8"?>
<PreferenceScreen xmlns:android="http://schemas.android.com/apk/res/
<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
Entwicklung mobiler Anwendungen — Europäische Fachhochschule Brühl/Neuss, 3. Quartal 2014
211
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>
Entwicklung mobiler Anwendungen — Europäische Fachhochschule Brühl/Neuss, 3. Quartal 2014
212
3. Persistenz und Datenbanken
Entwicklung mobiler Anwendungen — Europäische Fachhochschule Brühl/Neuss, 3. Quartal 2014
Shared Preferences
213
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
Entwicklung mobiler Anwendungen — Europäische Fachhochschule Brühl/Neuss, 3. Quartal 2014
214
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();
}
Entwicklung mobiler Anwendungen — Europäische Fachhochschule Brühl/Neuss, 3. Quartal 2014
215
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>
Entwicklung mobiler Anwendungen — Europäische Fachhochschule Brühl/Neuss, 3. Quartal 2014
216
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
Entwicklung mobiler Anwendungen — Europäische Fachhochschule Brühl/Neuss, 3. Quartal 2014
217
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
Entwicklung mobiler Anwendungen — Europäische Fachhochschule Brühl/Neuss, 3. Quartal 2014
218
3. Persistenz und Datenbanken
Lesen und Schreiben von Dateien
• SD-Karte erreichbar via /sdcard
• Nutzung der gewöhnlichen java.io Methoden
Entwicklung mobiler Anwendungen — Europäische Fachhochschule Brühl/Neuss, 3. Quartal 2014
219
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.
Entwicklung mobiler Anwendungen — Europäische Fachhochschule Brühl/Neuss, 3. Quartal 2014
220
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
Entwicklung mobiler Anwendungen — Europäische Fachhochschule Brühl/Neuss, 3. Quartal 2014
221
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
Entwicklung mobiler Anwendungen — Europäische Fachhochschule Brühl/Neuss, 3. Quartal 2014
222
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
Entwicklung mobiler Anwendungen — Europäische Fachhochschule Brühl/Neuss, 3. Quartal 2014
223
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);
...
Entwicklung mobiler Anwendungen — Europäische Fachhochschule Brühl/Neuss, 3. Quartal 2014
224
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.
Entwicklung mobiler Anwendungen — Europäische Fachhochschule Brühl/Neuss, 3. Quartal 2014
225
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
Entwicklung mobiler Anwendungen — Europäische Fachhochschule Brühl/Neuss, 3. Quartal 2014
226
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
Entwicklung mobiler Anwendungen — Europäische Fachhochschule Brühl/Neuss, 3. Quartal 2014
227
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.
Entwicklung mobiler Anwendungen — Europäische Fachhochschule Brühl/Neuss, 3. Quartal 2014
228
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
Entwicklung mobiler Anwendungen — Europäische Fachhochschule Brühl/Neuss, 3. Quartal 2014
229
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
Entwicklung mobiler Anwendungen — Europäische Fachhochschule Brühl/Neuss, 3. Quartal 2014
230
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.
Entwicklung mobiler Anwendungen — Europäische Fachhochschule Brühl/Neuss, 3. Quartal 2014
231
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
Entwicklung mobiler Anwendungen — Europäische Fachhochschule Brühl/Neuss, 3. Quartal 2014
232
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()
Entwicklung mobiler Anwendungen — Europäische Fachhochschule Brühl/Neuss, 3. Quartal 2014
233
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.
Entwicklung mobiler Anwendungen — Europäische Fachhochschule Brühl/Neuss, 3. Quartal 2014
234
3. Persistenz und Datenbanken
Datenbanken mit SQLite
Anfragen
Möglichkeiten zur Durchführung von Anfragen:
• Raw Queries
• Regular Queries
• mit Hilfe eines SQLiteQueryBuilder
Entwicklung mobiler Anwendungen — Europäische Fachhochschule Brühl/Neuss, 3. Quartal 2014
235
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
Entwicklung mobiler Anwendungen — Europäische Fachhochschule Brühl/Neuss, 3. Quartal 2014
236
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
Entwicklung mobiler Anwendungen — Europäische Fachhochschule Brühl/Neuss, 3. Quartal 2014
237
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
Entwicklung mobiler Anwendungen — Europäische Fachhochschule Brühl/Neuss, 3. Quartal 2014
238
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
Entwicklung mobiler Anwendungen — Europäische Fachhochschule Brühl/Neuss, 3. Quartal 2014
239
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.
Entwicklung mobiler Anwendungen — Europäische Fachhochschule Brühl/Neuss, 3. Quartal 2014
240
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
Entwicklung mobiler Anwendungen — Europäische Fachhochschule Brühl/Neuss, 3. Quartal 2014
241
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.
Entwicklung mobiler Anwendungen — Europäische Fachhochschule Brühl/Neuss, 3. Quartal 2014
242
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
Entwicklung mobiler Anwendungen — Europäische Fachhochschule Brühl/Neuss, 3. Quartal 2014
243
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);
Entwicklung mobiler Anwendungen — Europäische Fachhochschule Brühl/Neuss, 3. Quartal 2014
244
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)
Entwicklung mobiler Anwendungen — Europäische Fachhochschule Brühl/Neuss, 3. Quartal 2014
245
Herunterladen