Wozu sind die noch mal gut? Ah ja, wenn man auf eine SQLite Datenbank aus einer App zugreift, kann bei einem direkten Zugriff nur die App auf die Datenbank zugreifen. Wird hingegen ein ContentProvider benutzt, können auch andere Anwendungen auf die Datenbank zugreifen. Als Beispiel müssen die Kontakte herhalten – Diese werden von diversen Apps benutzt.
Damit der Contentprovider funktioniert sind einige Vorgaben zu beachten:
- Die eigene Contentprovider Klasse muss von ContentProvider abgeleitet werden. In der abgeleiteten Klasse müssen die Methoden onCreate, query, insert, update, delete und getType überschrieben werden. Sie werden quasi auf die Datenbank Methoden umgeleitet
- Statt in der eigenen App direkt auf die Datenbank zuzugreifen, wird jetzt auf den ContentProvider zugegriffen.
- Der Contentprovider muss in der Manifest Datei mit dem Tag <Provider … bekanntgemacht werden.
Um überhaupt auf Daten zugreifen zu können, benötigt man eine URI zu eben diesen Daten. Die dabei verwendeten Uri’s erinnern mich start an das Erzeugen einer REST Schnittstelle. Um alle Daten der Tabelle products abzurufen, gibt man z.B.
content://de.stubbe_cs.database.provider.MyContentProvider/products
ein. Um an einen speziellen Rekord zu gelangen gibt man content://de.stubbe_cs.database.provider.MyContentProvider/products/6
ein, wobei die 6 die ID des Rekords bezeichnet.
Zum Bearbeiten der Uri’s kann man sehr gut die Klasse UriMatcher verwenden.:
private static final String AUTHORITY = "de.stubbe_cs.database.provider.MyContentProvider"; private static final String PRODUCTS_TABLE = "products"; // Typ der URI. 1: ganze Tabelle, 2: Record public static final int PRODUCTS = 1; public static final int PRODUCTS_ID = 2; private static final UriMatcher sURIMatcher = new UriMatcher(UriMatcher.NO_MATCH); static { sURIMatcher.addURI(AUTHORITY, PRODUCTS_TABLE, PRODUCTS); sURIMatcher.addURI(AUTHORITY, PRODUCTS_TABLE + "/#", PRODUCTS_ID); } ... ... @Override public int delete(Uri uri, String selection, String[] selectionArgs) { // Typ der uri int uriType = sURIMatcher.match(uri);
Es wird ein Objekt der Klasse UriMatcher erzeugt und es werden Muster für Uri’s hinterlegt. Das erste Muster soll aus dem String AUTHORITY und dem String PRODUCTS_TABLE zusammengesetzt sein. Der Typ dieses Musters wird auf PRODUCTS festgelegt. Wird jetzt z.B. die
Uricontent://de.stubbe_cs.database.provider.MyContentProvider/products
gefunden, gibt sUriMatcher.match(uri) eine 1 zurück, was dem Typ PRODUCTS entspricht. Mit
uri.getLastPathSegment()
erhält man den String PRODUCTS_TABLE (hier also products).