Android Content Provider

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.:

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

erhält man den String PRODUCTS_TABLE (hier also products).

SQLite unter Android mit Speicherung auf der SD Karte

Ich habe mich mit dem SQLite – Beispiel aus dem Buch “Android Studio Development“ von Neil Smyth beschäftigt. Zunächst habe ich das Beispiel ans Laufen gebracht, was aber mithilfe des Buches sehr einfach ist. Dann habe ich versucht mir auf meinem Smartphone die Datenbank anzusehen. Das klappte aber leider nicht, da dazu die Berechtigung fehlt. Also das Beispiel auf das virtuelle Smartphone gebracht. Jetzt hat man die Möglichkeit über eine Konsole (bei mir unter Windows 7) mit

adb -e shell

auf das virtuelle Smartphone zuzugreifen. Dort hat man dann auch die nötigen Rechte. Im Verzeichnis

/data/data/de.stubbe_cs.database/databases

befindet sich die Datenbank des Beispielprojektes. Man kann sie sich ansehen, indem man in die Konsole sqlite3 eingibt. Das startet ein SQLite Tool. Dort kann man wiederum .open ./<dbname> und dann .tables eingeben. Als Ergebnis werden dann die Tabellennamen der Datenbank angezeigt. Mit .schema erhält man auch Infos über die Felder in den Tabellen.

Da es scheinbar nur schwer möglich ist, die Datenbank auf einem Smartphone zu inspizieren, habe ich mir überlegt, die Datenbank auf der SD Karte meines Smartphones auszulagern. Dazu müssen allerdings einige Änderungen vorgenommen werden.

Dabei wurde in den Datenbankname der Pfad auf die SD Karte mit eingefügt und in den Konstruktor wurde  die Methode

SQLiteDatabase.openOrCreateDatabase

eingefügt. Dann muss noch in der Manifest Datei die Berechtigung zum Schreiben auf externe Medien gesetzt werden:

Das passiert hier in Zeile 5 mit dem usespermission Tag.

Nach dem Start der App wurde die Datenbank auf die SD Karte ausgelagert. Aber wie überprüft man das? Im Emulator gab es zunächst Probleme. Wo steckt man die SD Karte rein? Das erledigte sich aber, denn beim Start der Datenbankanwendnung hat der Emulator angeboten, eine virtuelle SD Karte anzulegen. Ich habe die interne Variante gewählt und die virtuelle SD Karte formatiert. Dann klappte es immer noch nicht, da in den Einstellungen der App es keine Berechtigung für den Zugriff auf die SD Karte gab. Nachdem diese Probleme gelöst waren, konnte die App im Emulator gestartet werden. Das die Datenbank jetzt auf der SD Karte ist, kann man wierderum über die Konsole überprüfen. In der Shell wechselt man in das Verzeichnis /sdcard und findet dort dann (mit ls) die Datenbank Dateien.

Auf dem Smartphone klappte das genauso. Um die Datenbank in Ruhe inspizieren zu können, habe ich sie per FTP auf meinen PC gezogen und mit dem SQLite Browser untersucht.

Interessanter Weise wird mein Smartphone via USB Treiber in das Dateisystem meines Windows 7 PCs eingebunden. Die Datenbankdateien unter /sdcard sind dort allerdings nicht zu sehen !