Mobile App Development -­‐ Content Provider -­‐ Inhalt • Was sind Content Provider • Content Provider nutzen • Content Provider implementieren Mobile App Development Content Provider Mobile App Development Content Provider • Einige Apps besitzen Daten, die u. U. auch für andere Apps interessant sein können MyApp Mobile App Development ? Other App Content Provider • Einige Apps besitzen Daten, die u. U. auch für andere Apps interessant sein können • Wie können die Daten anderen Apps zur Verfügung gestellt werden? MyApp Mobile App Development ? Other App Content Provider • Content Provider ermöglichen die Nutzung und Bereitstellung von Daten von/für andere Apps • Sie bilden eine Abstraktionsschicht als einheitliche Sicht auf Daten • Die Nutzung der Daten ist unabhängig von der internen Repräsentation Mobile App Development Content Provider • Die angebotenen Daten haben einen Tabellen-artigen Aufbau • Beispiel: Wörterbuch Quelle: h3p://developer.android.com/guide/topics/providers/content-­‐provider-­‐basics.html Mobile App Development Content Provider • Der Zugriff auf die Daten erfolgt über Datenbanken-ähnliche Schnittstellen • • • • query(): Abrufen von Daten insert(): Einfügen von Daten update(): Aktualisieren von Daten delete(): Löschen von Daten Mobile App Development Content Provider • Content Provider werden über URIs angesprochen • Diese geben neben dem Schema den symbolischen Namen der CPs und den Pfad zur eigentlichen Tabelle an • Aufbau content://authority/path/id Mobile App Development Content Provider • Aufbau: content://authority/path/id • content: Content Provider Schema • authority: symbolischer Name des Content Providers • path: Der Pfad zur Tabelle (ein CP kann mehrere Tabelle anbieten) • id: id eines Datensatzes Mobile App Development Content Provider • Beispiel: Wörterbuch Content Provider • content://user_dictionarry UserDic:onary Mobile App Development Content Provider • Beispiel: Wörterbuch Content Provider • content://user_dictionarry/words UserDic:onary Words Mobile App Development Content Provider • Beispiel: Wörterbuch Content Provider • content://user_dictionarry/words/2 UserDic:onary Words 1 2 3 4 Mobile App Development Content Provider • Beispiel: Browser Content Provider • content://browser Browser Mobile App Development Content Provider • Beispiel: Browser Content Provider • content://browser/searches • content://browser/bookmarks Browser searches Mobile App Development bookmarks 1 1 2 2 3 3 4 4 Content Provider • Beispiel: Browser Content Provider • content://browser/searches/3 • content://browser/bookmarks/2 Browser searches Mobile App Development bookmarks 1 1 2 2 3 3 4 4 Content Provider nutzen Mobile App Development Content Provider nutzen • Um Daten von einem Content Provider abzufragen oder zu manipulieren, müssen entsprechende Berechtigungen im Manifest eingetragen werden • Beispiel: Auslesen der Anrufhistorie <uses-permission android:name= "android.permission.READ_CALL_LOG"/> Mobile App Development Content Provider nutzen • ContentResolver bilden die Client-Seite zum Server-seitigen ContentProvider • Sie dienen der Abfrage und Manipulation von Daten • Mittels query()-Methode auf dem ContentResolver können Daten abgefragt werden Mobile App Development Content Provider nutzen • Die query()-Methode ist einer SQL-Query sehr ähnlich • Die Parameter umfassen: • ProjekNon: • gibt an, welche Tabellenspalten abgefragt werden sollen • entspricht SELECT Col1, Col2 FROM ... Mobile App Development Content Provider nutzen • Die Parameter umfassen: • SelekNon • Einschränkung der Ergebnismenge • entspricht der WHERE-­‐Bedingung eines SELECT Statements • SelekNons-­‐Parameter • dienen der Parametrisierung der SelekNon • z. B.: SELECT ... FROM ... WHERE Spalte = ? Mobile App Development Content Provider nutzen • Die Parameter umfassen: • SorNerung • gibt an, wie die Ergebnismenge sorNert werden soll • entspricht dem ORDER BY Statement einer SQL-­‐Abfrage Mobile App Development Content Provider nutzen • Beispiel: Wörterbuch auslesen • Das benutzerdefinierte Wörterbuch wird über den Content Provider UserDicNonary bereitgestellt • Um es zu lesen wird die BerechNgung android.permission.READ_USER_DICTIONARY benöNgt Mobile App Development Content Provider nutzen • Beispiel: Wörterbuch auslesen private void readDictionary(Context context) { // Referenz auf eine ContentResolver Instanz abrufen ContentResolver cr = context.getContentResolver(); // URI zur Words-Tabelle im Wörterbuch: // content://user_dictionary/words Uri uri = UserDictionary.Words.CONTENT_URI; // Projektion: gibt an, welche Tabellen Spalten abgerufen werden String[] projection = new String[]{Words.WORD, Words.FREQUENCY}; // Wörter unter Angabe von URI und Projektion abfragen Cursor cursor = cr.query(Words.CONTENT_URI, projection, null, null, null); // Cursor verarbeiten ... } Mobile App Development Content Provider nutzen • Beispiel: Wörterbuch auslesen private void readDictionary(Context context) { ContentResolver cr = context.getContentResolver(); Uri uri = UserDictionary.Words.CONTENT_URI; String[] projection = new String[]{Words.WORD, Words.FREQUENCY}; Cursor cursor = cr.query(Words.CONTENT_URI, projection, null, null, null); // Verarbeitung des Cursors erfolgt wie bei Datenbanken if (cursor.moveToFirst()) { int wordIdx = cursor.getColumnIndex(Words.WORD); int freqIdx = cursor.getColumnIndex(Words.FREQUENCY); do { } Log.d(LOG, cursor.getString(wordIdx) + " (" + cursor.getInt(freqIdx) + ")"); } while (cursor.moveToNext()); cursor.close(); // Cursor schließen } Mobile App Development Content Provider nutzen • Beispiel: Wörterbuch auslesen (mit Selektion) private void readDictionary(Context context) { // Referenz auf eine ContentResolver Instanz abrufen ContentResolver cr = context.getContentResolver(); // URI zur Words-Tabelle im Wörterbuch Uri uri = UserDict ionary.Words.CONTENT_URI; // Projektion: gibt an, welche Tabellen Spalten abgerufen werden String[] projection = new String[]{Words._ID, Words.WORD, Words.FREQUENCY}; String selection = Words.WORD + " LIKE ?"; // Wörter, beginnend mit 'A' String[] selArgs = new String[]{"A%"}; // Selektionsparameter String sortOrder = Words.WORD + " DESC"; // absteigende Sortierung // Query ausführen Cursor cursor = cr.query(Words.CONTENT_URI, projection, selection, selArgs, sortOrder); // Cursor verarbeiten } Mobile App Development Content Provider nutzen • Beispiel: Wörterbuch auslesen (festgelegte ID) private void readFromDictionary(Context context, int id) { // Referenz auf eine ContentResolver Instanz abrufen ContentResolver cr = context.getContentResolver(); // URI zu bestimmtem Datensatz im Wörterbuch Uri uri = ContentUris.withAppendedId( UserDictionary.Words.CONTENT_URI, id); // content://user_dictionary/words/<id> Log.d(LOG, "read uri: " + uri); // Anfrage ausführen: Cursor enthält nur einen Datensatz, // das Wort mit der angegebenen ID Cursor cursor = cr.query(uri, null, null, null, null); } Mobile App Development Content Provider nutzen • Beispiel: Anruflisten auslesen • Die Anruflisten werden durch den Content Provider CallLog bereitgestellt • Um Anruflisten lesen zu können, muss die BerechNgung android.permission.READ_CALL_LOG vorhanden sein Mobile App Development Content Provider nutzen • Beispiel: Anruflisten auslesen private void readCallLog(Context context) { // ContentResolver Instanz abrufen ContentResolver cr = context.getContentResolver(); // Projektion mit Anruftyp, Name und Nummer erstellen String[] projection = new String[]{CallLog.Calls.TYPE, CallLog.Calls.CACHED_NAME, CallLog.Calls.NUMBER}; // Selektion für Anruftyp INCOMMING String selection = CallLog.Calls.TYPE + "=" + CallLog.Calls.INCOMING_TYPE; // URI zum Call log Uri uri = Uri.parse("content://call_log/calls"); // Query an ContentProvider senden Cursor cursor = cr.query(uri, projection, selection, null, null); // ... Cursor verarbeiten ... } Mobile App Development Content Provider nutzen • Daten einfügen • Das Einfügen von Daten wird mi3els insert()-­‐ Methode realisiert • Sie erhält ein ContentValues Objekt, in das die Werte für die verschiedenen Spalten eingetragen werden • Rückgabewert ist der URI zum eingefügten Datensatz Mobile App Development Content Provider nutzen • Beispiel: Wörterbuch Daten einfügen private void writeToDictionary(Context context) { // Referenz auf eine ContentResolver Instanz abrufen ContentResolver cr = context.getContentResolver(); // ContentValues Objekt erstellen ContentValues vals = new ContentValues(); // neuees Wort eintragen vals.put(Words.WORD, "neuesWort"); // Worthäufigkeit eintragen vals.put(Words.FREQUENCY, 100); // Land und Sprache setzten vals.put(Words.LOCALE, Locale.getDefault().toString()); // neuen Datensatz einfügen Uri result = cr.insert(UserDictionary.Words.CONTENT_URI, vals); Log.d(LOG, "uri: " + result); // liefert: content://user_dictionary/words/<id> } Mobile App Development Content Provider nutzen • Daten einfügen (bulk insert) private void bulkWriteToDictionary(Context context, String[] words) { // Referenz auf eine ContentResolver Instanz abrufen ContentResolver cr = context.getContentResolver(); // Array für ContentValues Objekt erstellen ContentValues[] cValues = new ContentValues[words.length]; // ContentValues Objekte erstellen for (int i = 0; i < words.length; i++) { ContentValues vals = new ContentValues(); vals.put(Words.WORD, words[i]); cValues[i] = vals; } // ContentValues Objekte einfügen cr.bulkInsert(UserDictionary.Words.CONTENT_URI, cValues); } Mobile App Development Content Provider nutzen • Daten aktualisieren • Content Provider Einträge können mit der update()-­‐Methode aktualisiert werden • Sie erhält ein ContentValues-­‐Objekt mit den neuen Werten und analog zu einem SQL Update eine SelekNon Mobile App Development Content Provider nutzen • Daten aktualisieren private void updateDictionary(Context context) { // Referenz auf eine ContentResolver Instanz abrufen ContentResolver cr = context.getContentResolver(); // ContentValues Objekt erstellen ContentValues values = new ContentValues(); values.put(UserDictionary.Words.WORD, "neuesWort"); values.put(UserDictionary.Words.FREQUENCY, 100); values.putNull(UserDictionary.Words.LOCALE); // Selektion für die zu aktualisierenden Objekte erstellen String selection = UserDictionary.Words.LOCALE + " LIKE ?"; String[] selectionArgs = new String[]{"en_%"}; // Einträge aktualisieren cr.update(UserDictionary.Words.CONTENT_URI, values, selection, selectionArgs); } Mobile App Development Content Provider nutzen • Daten löschen • Datensätze werden mit der delete()-­‐Methode gelöscht • Sie erhält eine SelekNon, für die Datensätze die gelöscht werden sollen Mobile App Development Content Provider nutzen • Daten löschen private void deleteDictionary(Context context) { // Referenz auf eine ContentResolver Instanz abrufen ContentResolver cr = context.getContentResolver(); // Selektion für die Datensätze erstellen, die gelöscht werden sollen String selection = UserDictionary.Words.WORD + " LIKE ? AND " + UserDictionary.Words.LOCALE + " LIKE ?"; String[] selectionArgs = new String[]{"a%", "de_%"}; // Datensätze löschen cr.delete(UserDictionary.Words.CONTENT_URI, selection, selectionArgs); } Mobile App Development Content Provider implemen:eren Mobile App Development Content Provider implemen:eren • Content Provider müssen analog zu Activities, Services und BCRs im Manifest eingetragen werden • Hier werden neben dem Namen des Content Providers u. U. Berechtigungen eingetragen, die der Nutzer des Content Providers benötigt Mobile App Development Content Provider implemen:eren • Manifest Eintrag <application ...> <provider android:name= "de.htwds.mada.cp.TodoContentProvider” android:authorities="de.htwds.mada.todo" android:enabled="true" android:exported="true” android:permission= "de.htwds.mada.MY_PERMISSION"> </provider> </application> Mobile App Development Content Provider implemen:eren • Content Provider authority • gibt den Android-­‐internen Namen des Content Providers an • Als authority-­‐Basis sollte der App Package Name verwendet werden, um Konflikte mit anderen Providern zu vermeiden • Beispiel authority: content://de.htwds.mada.todoprovider Mobile App Development Content Provider implemen:eren • Content Provider URIs • Für jede Tabelle, die der CP anbietet muss ein URI definiert werden • Der URI wird auf Basis der Authority erstellt • Beispiel: content://de.htwds.mada.todoprovider/todo content://de.htwds.mada.todoprovider/priority Mobile App Development Content Provider implemen:eren • Die Implementierung eines Content Providers leitet von der Klasse ContentProvider ab • Es müssen die Methoden query(), insert(), update(), delete() und getType() implementiert werden Mobile App Development Content Provider implemen:eren • Jede der Methode bekommt ein URI übergeben, womit der CP entscheidet, was zu tun ist • Beispiel public Cursor query(Uri uri, ...) { String authority = "content://de.htwds.mada.todo"; if (uri.toString().equals(authority + "/todo")) { // alle Todos zurückgeben } else if (uri.toString() .matches(authority + "/todo/*")) { // id aus URI parsen und Datensatz zurückgeben } } Mobile App Development Content Provider implemen:eren • Das Parsen von URIs mittel String Matching kann sehr umständlich werden • Verschachtelte if-else Blöcke sind nicht mehr gut zu lesen • Abhilfe schaffen die Utility-Klassen URIMatcher und ContentUris Mobile App Development Content Provider implemen:eren • Die Klasse URIMatcher ordnet URI Mustern Integer zu, die in switch-case Statements verwendet werden können • Platzhalter: * und # • Beispiel String authority = "de.htwds.mada.todo"; UriMatcher matcher = new UriMatcher(0); matcher.addURI(authority, "todo", 1); matcher.addURI(authority, "todo/#", 2); matcher.addURI(authority, "priority", 3); matcher.addURI(authority, "category/#", 4); Mobile App Development Content Provider implemen:eren String authority = "de.htwds.mada.todo"; UriMatcher matcher = new UriMatcher(UriMatcher.NO_MATCH); matcher.addURI(authority, "todo", 1); matcher.addURI(authority, "todo/#", 2); matcher.addURI(authority, "priority", 3); matcher.addURI(authority, "category/#", 4); URI Muster Code conent://de.htwds.mada.todo/todo 1 conent://de.htwds.mada.todo/todo/# 2 conent://de.htwds.mada.todo/priority 3 conent://de.htwds.mada.todo/priority/# 4 Mobile App Development Content Provider implemen:eren URI Muster Code conent://de.htwds.mada.todo/todo 1 conent://de.htwds.mada.todo/todo/# 2 conent://de.htwds.mada.todo/priority 3 conent://de.htwds.mada.todo/priority/# 4 public Cursor query(Uri uri, ...) { int uriCode = matcher.match(uri); switch (uriCode) { case 1: { /* alle Todos zurückgeben */ } case 2: { /* Todo mit ID zurückgeben */ } case 3: { /* alle Priorities zurückgeben */ } case 4: { /* Priorities mit ID zurückgeben */ } } Mobile App Development Content Provider implemen:eren • Mit der Klasse ContentUris können IDs aus URIs geparst werden • Dies wird verwendet, um Datensätze mit einer bestimmten ID zurückzugeben public Cursor query(Uri uri, ...) { int uriCode = matcher.match(uri); switch (uriCode) { case 2: { /* Todo mit ID zurückgeben */ long id = ContentUris.parseId(uri); // Datensatz mit ID <id> zurückgeben } } Mobile App Development Content Provider implemen:eren • Aus Übersichtlichkeitsgründen wurden in den addUri()-Methoden und in den case Statements Integer Literale verwendet • Normalerweise würde man für diese Integer Konstanten verwenden!! Mobile App Development Content Provider implemen:eren • Im Folgenden wird die Implementierung eines Content Providers für Todo Objekte erläutert • Es wird davon ausgegangen, dass eine Todo-Datenbank mit einer Tabelle Todo existiert • Ein entsprechender DbHelper zum Zugriff auf die Datenbank wird vorausgesetzt Mobile App Development Content Provider implemen:eren • Todo DbHelper public class DbHelper extends OrmLiteSqliteOpenHelper { public static final String DATABASE_NAME = "todos.db"; public static final int DATABASE_VERSION = 1; // Spaltennamen public static final public static final public static final public static final String String String String COL_ID = "_id"; COL_TITLE = "title"; COL_DESCR = "description"; COL_DUEDATE = "duedate"; public DbHelper(Context context) { super(context, DATABASE_NAME, null, DATABASE_VERSION); } // ... } Mobile App Development Content Provider implemen:eren • Implementierung public class TodoContentProvider extends ContentProvider { public static final String SCHEME = "content://"; public static final String AUTHORITY = "de.htwds.mada.todo"; private static final UriMatcher sUriMatcher = new UriMatcher( UriMatcher.NO_MATCH); public Cursor query(Uri uri, String[] projection, String selection, String[] selectionArgs, String sortOrder) { } public Uri insert(Uri uri, ContentValues values) { } public int update(Uri uri, ContentValues values, String selection, String[] selectionArgs) { } public int delete(Uri uri, String selection, String[] selectionArgs) { } } Mobile App Development Content Provider implemen:eren • Todo Contract Klasse • ImplemenNerung als innere Klasse im Content Provider • Die Contract Klasse enthält eine CONTENT_URI, mit der die Todo Tabelle referenziert wird • wird von BaseColumns abgeleitet und hat somit die Spalte _ID Mobile App Development Content Provider implemen:eren • Todo Contract Klasse • Die Contract Klasse enthält Konstanten für die verschiedenen Spaltennamen • Im Todo Beispiel werden die CP Todo Spalten 1:1 auf die Datenbankspalten abgebildet (dies muss nicht zwingend der Fall sein!) Mobile App Development Content Provider implemen:eren • Todo Contract Klasse public class TodoContentProvider extends ContentProvider { public static final String SCHEME = "content://"; public static final String AUTHORITY = "de.htwds.mada.todo"; private static final UriMatcher sUriMatcher = new UriMatcher( UriMatcher.NO_MATCH); /* Contract Klasse für die Todo Tabelle */ public static final class Todos implements BaseColumns { public static final String PATH = "todos"; // content://de.htwds.mada.todo/todos public static final Uri CONTENT_URI = Uri.parse(SCHEME + AUTHORITY + "/" + PATH); // Todo Spalten public static final String TITLE = DbHelper.COL_TITLE; public static final String DESCRIPTION = DbHelper.COL_DESCR; public static final String DUEDATE = DbHelper.COL_DUEDATE; } } Mobile App Development Content Provider implemen:eren • URI Muster erstellen • Es wird ein URI Muster erstellt, das alle Todos referenziert • Ein zweites URI Muster dient der Referenzierung eines Todos mit einer besNmmten ID • Beide URIs werden mi3els UriMatcher eingetragen und auf konstante Integer abgebildet Mobile App Development Content Provider implemen:eren public class TodoContentProvider extends ContentProvider { public static final String SCHEME = "content://"; public static final String AUTHORITY = "de.htwds.mada.todo"; private static final UriMatcher sUriMatcher = new UriMatcher( UriMatcher.NO_MATCH); /* Contract Klasse für die Todo Tabelle */ public static final class Todos implements BaseColumns { public static final String PATH = "todos"; // ... } private static final int TODOS = 100; private static final int TODOS_ID = 101; static { // content://de.htwds.mada.todo/todos sUriMatcher.addURI(AUTHORITY, Todos.PATH, TODOS); // content://de.htwds.mada.todo/todos/# sUriMatcher.addURI(AUTHORITY, Todos.PATH + "/#", TODOS_ID); } } Mobile App Development Content Provider implemen:eren • query()-Methode implementieren • Die query()-­‐Methode bekommt neben dem URI verschiedene Parameter, die schon von Datenbanken bekannt sind: ProjekNon, SelekNon und SorNerung • Anhand des URI wird mit dem UriMatcher entschieden, was zurückgegeben wird Mobile App Development Content Provider implemen:eren • query()-Methode implementieren public Cursor query(Uri uri, String[] projection, String selection, String[] selectionArgs, String sortOrder) { // gibt den Integer zurück, der für das URI Muster hinterlegt wurde int uriCode = sUriMatcher.match(uri); switch (uriCode) { case TODOS: // alle Todos abfragen return queryAllTodos(projection, selection, selectionArgs, sortOrder); case TODOS_ID: // bestimmtes Todo abfragen long todoId = ContentUris.parseId(uri); return queryTodo(todoId, projection, selection, selectionArgs, sortOrder); default: return null; } } } Mobile App Development Content Provider implemen:eren • queryAllTodos()-Methode private Cursor queryAllTodos(String[] projection, String selection, String[] selectionArgs, String sortOrder) { Cursor cursor = null; SQLiteDatabase db = null; try { // Da in der Contract Klasse alle Spalten 1:1 auf die DB Spalten // abgebildet wurden, können Projektion, Selektion, uws. hier // direkt in die DB Anfrage übernommen werden db = mDbHelper.getReadableDatabase(); cursor = db.query(DbHelper.TABLE_NAME, projection, selection, selectionArgs, null, null, sortOrder); } catch (Exception ex) { Log.e(LOG, "error querying database", ex); } return cursor; } Mobile App Development Content Provider implemen:eren • queryTodo(id, ...)-Methode private Cursor queryTodo(long id, String[] projection, String selection, String[] selectionArgs, String sortOrder) { Cursor cursor = null; SQLiteDatabase db = mDbHelper.getReadableDatabase(); try { // Selektions String erstellen String selString = DbHelper.COL_ID + "=" + id; if (! selection.isEmpty()) { selString += " AND " + selection; } // auch hier können Projektion usw. wieder direkt übernommen werden cursor = db.query(DbHelper.TABLE_NAME, projection, selString, selectionArgs, null, null, sortOrder); } catch (Exception ex) { Log.e(LOG, "error querying database", ex); } return cursor; } Mobile App Development Content Provider implemen:eren • insert()-Methode implementieren • Verwendung, um neue Datensätze einzufügen • erhält als Parameter den Tabellen URI und ein ContentValues Objekt • gibt den URI zum eingefügten Datensatz mit angehängter ID zurück Mobile App Development Content Provider implemen:eren • insert()-Methode implementieren public Uri insert(Uri uri, ContentValues values) { // URI Muster auswerten int uriCode = sUriMatcher.match(uri); switch (uriCode) { case TODOS: { // Methode aufrufen, die das neue Todo in die Datenbank // einfügt und die ID zurückgibt long id = insertTodo(values); // URI für neues Todo erstellen und zurückgeben // content://de.htwds.mada/todos/<id> return ContentUris.appendId(uri.buildUpon(), id).build(); } default: { return null; } } } Mobile App Development Content Provider implemen:eren • update()-Methode implementieren • Verwendung, um Datensätze zu aktualisieren • erhält ein ContentValues Objekt mit den zu aktualisierenden Daten und eine SelekNon • gibt die Anzahl betroffener Datensätze zurück Mobile App Development Content Provider implemen:eren • update()-Methode implementieren public int update(Uri uri, ContentValues values, String selection, String[] selectionArgs) { // URI Muster auswerten int uriCode = sUriMatcher.match(uri); switch (uriCode) { case TODOS: { // mit updateTodo werden die Datensätze in der Datenbank // aktualisiert int affected = updateTodo(values, selection, selectionArgs); // Anzahl betroffener Datensätze zurückgeben return affected; } default: { return 0; } } } Mobile App Development Content Provider implemen:eren • delete()-Methode implementieren • Verwendung, um Datensätze zu löschen • erhält eine SelekNon für die zu löschenden Datensätze • gibt die Anzahl gelöschter Datensätze zurück Mobile App Development Content Provider implemen:eren • delete()-Methode implementieren public int delete(Uri uri, String selection, String[] selectionArgs) { // URI Muster auswerten int uriCode = sUriMatcher.match(uri); switch (uriCode) { case TODOS: { // deleteTodo löscht die Datensätz in der Datenbank int affected = deleteTodo(selection, selectionArgs); // Anzahl betroffener Datensätze zurückgeben return affected; } default: { return 0; } } } Mobile App Development Content Provider implemen:eren • getType()-Methode implementieren • wird vom Client verwendet, um abzufragen, welcher MIME Type sich hinter einem besNmmten URI verbirgt • URIs die auf Tabellen zeigen • vnd.android.cursor.dir/vnd.de.htwds.mada.provider.todo • URIs die auf einzelne Zeilen zeigen • vnd.android.cursor.item/vnd.de.htwds.mada.provider.todo Mobile App Development Content Provider implemen:eren • getType()-Methode implementieren public class TodoContentProvider extends ContentProvider { /* Contract Klasse für die Todo Tabelle */ public static final class Todos implements BaseColumns { // ... // Erweiterung der Contract Klasse um MIME Type Konstanten public static final String CONTENT_TYPE = "vnd.android.cursor.dir/vnd.de.htwds.mada.todo"; public static final String CONTENT_ITEM_TYPE = "vnd.android.cursor.item/vnd.de.htwds.mada.todo"; } public String getType(Uri uri) { // URI Muster auswerten int uriCode = sUriMatcher.match(uri); // entsprechend dem URI MIME type zurückgeben switch (uriCode) { case TODOS: return Todos.CONTENT_TYPE; case TODOS_ID: return Todos.CONTENT_ITEM_TYPE; default: return null; } } } Mobile App Development Content Provider implemen:eren • Wie kann ein Provider mehrere Tabellen zur Verfügung stellen? Mobile App Development Content Provider implemen:eren • Wie kann ein Provider mehrere Tabellen zur Verfügung stellen? • Für jede Tabelle wird ein Contract Klasse mit den entsprechenden Spaltennamen angelegt • Es wird für jede Tabelle ein eigener URI bereitgestellt • Für die URIs werden Einträge im UriMatcher erstellt, um in den Methoden query(), insert(), ... die passende OperaNon auswählen zu können Mobile App Development Content Provider implemen:eren • Hinweis • Es muss kein 1:1 Mapping von CP Spalten auf Datenbankspalten vorliegen • Ein Content Provider kann z. B. auch Daten aus verschiedenen Datenbanktabellen zusammenfassen und als neue Tabelle anbieten Mobile App Development Übung Mobile App Development Übung Übung 07 -­‐ Todo Die Todo App aus Übung 06 soll um einen Content Provider erweitert werden. Der Content Provider soll die Tabelle Todo und Priority zur Verfügung stellen. Wie in der Vorlesung dargestellt, soll für beide Tabellen eine Contract Klasse erstellt werden, die die Namen der Tabellenspalten als Konstanten enthält. Für die Spaltennamen der Contract Klassen werden folgende Vorgaben gemacht: Todo: _id, title, description, datetime, priority_id Priority: _id, name Weiterhin soll die Todo Tabelle unter dem URI content://de.htwds.mada.todo/todos und die Priority Tabelle unter dem URI content://de.htwds.mada.todo/priorities erreichbar sein. Außerdem sollen die Todos und Priorities unter Angabe einer ID im URI einzeln abrufbar sein. Hinweis: Es ist wichtig, dass die Benennung der Spaltennamen und URIs, wie oben angegeben, eingehalten wird, da die App mit einer weiteren App in der Übungsabnahme getestet werden könnte. Mobile App Development