Content Provider ist eine Android-Komponente, die eine einheitliche Schnittstelle für den Datenzugriff zwischen Anwendungen bereitstellt. Sie abstrahiert den physischen Speicher (SQLite, Dateien, Netzwerkquellen) und ermöglicht den sicheren Informationsaustausch über ContentResolver. Laut Android Developer Guide, 2026 ist Content Provider eine der vier Hauptkomponenten einer Android-Anwendung, neben Activity, Service und BroadcastReceiver. Seine Aufgabe ist es, Daten mit Kontrolle über Lese- und Schreibberechtigungen für andere Anwendungen verfügbar zu machen.
Wichtige Punkte
Content Provider ist eine Android-Komponente, die den Zugriff auf einen zentralisierten Datenspeicher verwaltet und ihn über eine einheitliche Vertragsschnittstelle anderen Anwendungen bereitstellt. Sie verbirgt Implementierungsdetails des Speichers: Daten können in SQLite, im Dateisystem, in der Cloud gespeichert sein oder das Ergebnis einer Netzwerkanfrage sein.
Android enthält integrierte Content Provider für Systemdaten — ContactsContract, MediaStore, CalendarContract, CallLog. Drittanbieter-Anwendungen können ebenfalls eigene Anbieter für den sicheren Datenaustausch erstellen. Jeder Anbieter wird in AndroidManifest.xml mit einer authority registriert — einer eindeutigen Zeichenfolge, die den ersten Teil der URI bildet.
Content Provider arbeitet nach dem Client-Server-Modell. Der Anbieter fungiert als Server, der sechs erforderliche Methoden implementiert: query, insert, update, delete, getType und onCreate. Der Client (eine andere Anwendung) greift über ContentResolver auf den Anbieter zu, der Aufrufe über den Android-IPC-Mechanismus in die entsprechenden Methoden des Anbieters übersetzt.
Jeder Content Provider wird durch eine URI des Schemas content:// identifiziert. Zum Beispiel content://com.example.app.provider/items. Der erste Teil authority (com.example.app.provider) ist im Manifest an die Anbieterklasse gebunden. Der Pfad /items zeigt auf eine Tabelle, während /items/5 auf einen bestimmten Datensatz mit ID=5 zeigt.
Wenn eine Anwendung ContentResolver.query(URI) aufruft, überprüft Android die Berechtigungen des aufrufenden Pakets, findet den Anbieter anhand der authority und startet dessen Prozess, falls er noch nicht läuft. Der Anbieter führt die Abfrage aus und gibt einen Cursor zurück — ein Objekt, das das Ergebnis enthält und dem Client ermöglicht, über Datensätze zu iterieren.
Die ContentProvider-Klasse erfordert die Implementierung von sechs abstrakten Methoden. Jede Methode akzeptiert eine URI und gibt ein dem Operationstyp entsprechendes Ergebnis zurück. Das System ruft diese Methoden aus beliebigen Prozessen auf, daher müssen sie threadsicher sein und die Ausführung nicht lange blockieren.
Die query-Methode akzeptiert eine URI, ein Projection-Array von Spalten, einen Selection-String mit Argumenten und eine Sortierreihenfolge. Sie gibt einen Cursor mit Daten zurück. In der Implementierung müssen Sie die URI mit UriMatcher analysieren und die entsprechende SQL-Abfrage in der Datenbank ausführen.
Diese Methoden ändern Daten im Speicher. insert empfängt ContentValues — Schlüssel-Wert-Paare — und gibt die URI des neuen Datensatzes zurück. update und delete akzeptieren eine Selection zum Filtern von Datensätzen und geben die Anzahl der betroffenen Zeilen zurück. Nach Datenänderungen muss der Anbieter darüber über ContentResolver.notifyChange benachrichtigen.
| Methode | Zweck | Rückgabe |
|---|---|---|
| query | Daten per URI abrufen | Cursor oder null |
| insert | Neuen Datensatz hinzufügen | URI des neuen Datensatzes |
| update | Vorhandene Datensätze aktualisieren | int (Zeilenanzahl) |
| delete | Datensätze löschen | int (Zeilenanzahl) |
| getType | MIME-Typ für URI | String |
| onCreate | Anbieterinitialisierung | boolean |
ContentResolver ist ein zentraler Zugangspunkt für die Arbeit mit allen Content Providern im System. Die Client-Anwendung ruft Anbietermethoden niemals direkt auf — nur über ContentResolver, den Android aus dem Kontext erhält. CRUD-Operationen in ContentResolver haben dieselben Namen wie im Anbieter, akzeptieren aber URIs anstelle direkter Referenzen.
Zur Analyse eingehender URIs innerhalb des Anbieters wird UriMatcher verwendet. Er ermöglicht die Zuordnung einer URI zu einem numerischen Code — zum Beispiel ergibt URI content://authority/items Code 1 und content://authority/items/# Code 2. Dies macht manuelles Parsen des URI-Strings in jeder Methode überflüssig.
// ContentResolver verwenden, um auf Kontakte zuzugreifen
val uri = ContactsContract.Contacts.CONTENT_URI
val cursor = contentResolver.query(
uri,
arrayOf(ContactsContract.Contacts.DISPLAY_NAME),
null, null, null
)
cursor?.use {
while (it.moveToNext()) {
val name = it.getString(it.getColumnIndexOrThrow(
ContactsContract.Contacts.DISPLAY_NAME
))
Log.d("Kontakte", "Name: $name")
}
}
Der Cursor muss nach der Verwendung immer geschlossen werden — im obigen Beispiel erledigt dies die use-Funktion (Kotlin-Erweiterung). Wenn der Cursor nicht geschlossen wird, kommt es zu einem Speicherleck, da er eine Referenz auf Daten im Binder-Pool hält. Verwenden Sie für UI-Szenarien CursorLoader oder Room mit LiveData/Flow.
Die Erstellung eines eigenen Content Provider beginnt mit der Erweiterung der ContentProvider-Klasse. Der Anbieter arbeitet über SQLiteOpenHelper mit einer SQLite-Datenbank und verwendet UriMatcher zur Bestimmung des Abfragetyps. Betrachten Sie eine minimale Implementierung zur Verwaltung einer Notizliste.
Der Anbieter wird in AndroidManifest.xml innerhalb des application-Tags registriert. Das Attribut authorities legt eine eindeutige Kennung fest, und exported bestimmt, ob andere Anwendungen auf den Anbieter zugreifen können. Ohne exported=true ist der Anbieter nur innerhalb Ihrer Anwendung zugänglich.
// Beispiel-Content Provider für Notizen
class NotesProvider : ContentProvider() {
companion object {
const val AUTHORITY = "com.example.app.notes"
const val NOTES_PATH = "notes"
const val NOTES_URI = "content://$AUTHORITY/$NOTES_PATH"
const val NOTES_ID = "content://$AUTHORITY/$NOTES_PATH/#"
private val uriMatcher = UriMatcher(UriMatcher.NO_MATCH).apply {
addURI(AUTHORITY, NOTES_PATH, 1)
addURI(AUTHORITY, "$NOTES_PATH/#", 2)
}
}
override fun query(uri: Uri, projection: Array<String>?,
selection: String?, args: Array<String>?, sort: String?): Cursor? {
return when (uriMatcher.match(uri)) {
1 -> dbHelper.readableDatabase.query(TABLE_NOTES,
projection, selection, args, null, null, sort)
2 -> dbHelper.readableDatabase.query(TABLE_NOTES,
projection, "_id=?", arrayOf(uri.lastPathSegment), null, null, null)
else -> throw IllegalArgumentException("Unknown URI: $uri")
}
}
override fun insert(uri: Uri, values: ContentValues?): Uri? {
val id = dbHelper.writableDatabase.insert(TABLE_NOTES, null, values)
context?.contentResolver?.notifyChange(uri, null)
return ContentUris.withAppendedId(uri, id)
}
override fun delete(uri: Uri, selection: String?, args: Array<String>?): Int {
val count = dbHelper.writableDatabase.delete(TABLE_NOTES, selection, args)
context?.contentResolver?.notifyChange(uri, null)
return count
}
// getType, update, onCreate der Kürze halber weggelassen
}
Nach der Erstellung der Anbieterklasse muss sie im Manifest mit den Attributen android:authorities und android:exported (true, wenn der Anbieter öffentlich ist) registriert werden. Das System erstellt beim ersten Zugriff eine Instanz des Anbieters — dies geschieht im UI-Thread, daher muss onCreate schnell ausgeführt werden.
Content Provider ermöglicht die Verwaltung des Datenzugriffs auf zwei Ebenen: Leseberechtigungen und Schreibberechtigungen. Sie werden im Manifest mit den Attributen android:readPermission und android:writePermission festgelegt. Wenn die Client-Anwendung nicht über die entsprechende Berechtigung verfügt, lehnt das System den Aufruf mit einer SecurityException ab.
Android unterstützt temporäre Berechtigungen durch die Flags FLAG_GRANT_READ_URI_PERMISSION und FLAG_GRANT_WRITE_URI_PERMISSION. Dies ist nützlich, wenn eine Anwendung einer anderen Anwendung eine Datei-URI per Intent übergibt — der Empfänger erhält nur für eine begrenzte Zeit Zugriff auf diese spezifische URI. Das System widerruft die temporäre Berechtigung nach Beendigung der empfangenden Anwendung.
Für Systemanbieter erfordert Android die Angabe spezifischer Berechtigungen im Anwendungsmanifest. Zum Beispiel erfordert der Zugriff auf Kontakte READ_CONTACTS und der Zugriff auf den Kalender READ_CALENDAR. Ab Android 6 werden diese Berechtigungen zur Laufzeit und nicht bei der Installation angefordert.
Häufig gestellte Fragen
Content Provider ist eine Android-Komponente, die eine Standardschnittstelle für den Datenaustausch zwischen Anwendungen über ContentResolver bereitstellt. Sie abstrahiert die Speichermethode (SQLite, Dateien, Netzwerk) und gewährleistet sicheren Datenzugriff mit Kontrolle über Lese- und Schreibberechtigungen.
Authority ist eine eindeutige Anbieterkennungszeichenfolge, die in AndroidManifest.xml angegeben wird. Sie bildet den ersten Teil der URI content://authority/path und wird vom System verwendet, um ContentResolver-Aufrufe an den richtigen Anbieter weiterzuleiten. Die authority muss geräteweit unter allen Anwendungen eindeutig sein.
UriMatcher ordnet URIs numerischen Codes zu. Sie fügen Muster über addURI hinzu und rufen dann match auf, um den Code für eine eingehende URI zu erhalten. Dadurch können die Methoden query, insert, update und delete bestimmen, welche Tabelle oder welcher Datensatz angefordert wird, und die entsprechende Datenbankoperation ausführen.
Ja, der Cursor muss nach der Verwendung immer geschlossen werden. Wenn der Cursor nicht geschlossen wird, kommt es zu einem Speicherleck, da er eine Binder-Referenz auf die Daten des Anbieters hält. Verwenden Sie in Kotlin die use-Funktion zum automatischen Schließen und in Java try-with-resources oder cursor.close() in einem finally-Block.
Content Provider ist eine Komponente für den anwendungsübergreifenden Datenzugriff, während SQLiteDatabase ein interner Speichermechanismus für eine einzelne Anwendung ist. Content Provider bietet eine URI-Schnittstelle und Berechtigungskontrolle, während SQLiteDatabase direkt mit der Datenbank ohne Sicherheitsmechanismen auf Betriebssystemebene arbeitet.
Zusammenfassung
Wir entwickeln eine mobile Applikation schlüsselfertig
IT Sectr entwickelt seit 2017 iOS- und Android-Apps für Startups und Unternehmen. Wir beraten Sie und schlagen die beste Lösung vor.
Lesen Sie auch