Content Provider — är en Android-komponent som tillhandahåller ett enhetligt gränssnitt för åtkomst till data mellan applikationer. Den abstraherar fysisk lagring (SQLite, filer, nätverkskällor) och säkerställer säker informationsutbyte via ContentResolver. Enligt Android Developer Guide, 2026 är Content Provider en av de fyra grundläggande komponenterna i en Android-applikation tillsammans med Activity, Service och BroadcastReceiver. Dess uppgift är att göra data tillgänglig för andra applikationer med kontroll över läs- och skrivbehörigheter.
Huvudpunkter
Content Provider — är en Android-komponent som hanterar åtkomst till en centraliserad datalagring och tillhandahåller den till andra applikationer via ett enhetligt kontraktsgränssnitt. Den döljer implementeringsdetaljerna för lagring: data kan lagras i SQLite, på filsystemet, i molnet eller vara resultatet av en nätverksbegäran.
Android innehåller inbyggda Content Providers för systemdata — ContactsContract, MediaStore, CalendarContract, CallLog. Tredjepartsapplikationer kan också skapa egna leverantörer för säkert datautbyte. Varje leverantör registreras i AndroidManifest.xml med angivande av authority — en unik sträng som utgör den första delen av URI:n.
Content Provider fungerar enligt klient-server-modellen. Leverantören agerar som en server som implementerar sex obligatoriska metoder: query, insert, update, delete, getType och onCreate. Klienten (en annan applikation) kommer åt leverantören via ContentResolver som vidarebefordrar anropen till leverantörens motsvarande metoder genom Android IPC-mekanism.
Varje Content Provider identifieras av en URI av schemat content://. Till exempel content://com.example.app.provider/items. Den första delen authority (com.example.app.provider) är bunden till leverantörens klass i manifestet. Sökvägen /items pekar på en tabell och /items/5 — på en specifik post med ID=5.
När en applikation anropar ContentResolver.query(URI), kontrollerar Android den anropande paketets behörigheter, hittar leverantören via authority och startar dess process om den inte redan är igång. Leverantören utför frågan och returnerar en Cursor — ett objekt som innehåller resultatet och låter klienten iterera genom poster.
Klassen ContentProvider kräver implementering av sex abstrakta metoder. Varje metod tar emot en URI och returnerar ett resultat som motsvarar operationstypen. Systemet anropar dessa metoder från vilken process som helst, så de måste vara trådsäkra och inte blockera exekveringen under lång tid.
Metoden query tar emot en URI, en array av kolumner (projection), en selection-sträng med argument och sorteringsordning. Den returnerar en Cursor med data. I implementeringen måste URI:n tolkas med UriMatcher och motsvarande SQL-fråga utföras mot databasen.
Dessa metoder ändrar data i lagringen. insert tar emot ContentValues — nyckel-värdepar — och returnerar URI:n för den nya posten. update och delete tar emot selection för att filtrera poster och returnerar antalet påverkade rader. Efter att ha ändrat data måste leverantören meddela detta via ContentResolver.notifyChange.
| Metod | Syfte | Returnerar |
|---|---|---|
| query | Hämta data via URI | Cursor eller null |
| insert | Lägg till ny post | URI för ny post |
| update | Uppdatera befintliga poster | int (antal rader) |
| delete | Ta bort poster | int (antal rader) |
| getType | MIME-typ för URI | String |
| onCreate | Initiera leverantören | boolean |
ContentResolver — är en enhetlig åtkomstpunkt för att arbeta med alla Content Providers i systemet. Klientapplikationen anropar aldrig leverantörens metoder direkt — bara via ContentResolver, som Android får från kontexten. CRUD-operationer i ContentResolver har samma namn som hos leverantören men tar emot URI istället för direkta referenser.
För tolkning av inkommande URI:er inuti leverantören används UriMatcher. Det gör det möjligt att matcha en URI till en numerisk kod — till exempel ger URI content://authority/items kod 1 och content://authority/items/# — kod 2. Detta eliminerar behovet av manuell tolkning av URI-strängen i varje metod.
// Använda ContentResolver för att komma åt kontakter
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("Kontakter", "Namn: $name")
}
}
Cursor måste stängas efter användning — i exemplet ovan gör use (Kotlin-tilläggsfunktionen) detta. Om Cursor inte stängs uppstår en minnesläcka eftersom den håller en referens till data i Binder-poolen. För UI-scenarier, använd CursorLoader eller Room med LiveData/Flow.
Att skapa en egen Content Provider börjar med att ärva från klassen ContentProvider. Leverantören arbetar med SQLite-databasen via SQLiteOpenHelper och använder UriMatcher för att bestämma frågetypen. Låt oss titta på en minimal implementering för att hantera en anteckningslista.
Leverantören registreras i AndroidManifest.xml inuti application-taggen. Attributet authorities anger en unik identifierare och exported avgör om andra applikationer kan komma åt leverantören. Utan exported=true är leverantören endast tillgänglig inom din egen applikation.
// Exempel på Content Provider för anteckningar
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 utelämnade för korthetens skull
}
Efter att klassen skapats måste leverantören registreras i manifestet med attributen android:authorities och android:exported (true om leverantören är offentlig). Systemet skapar en instans av leverantören vid första åtkomst — detta sker i UI-tråden, så onCreate måste köras snabbt.
Content Provider gör det möjligt att hantera åtkomst till data på två nivåer: läsbehörigheter och skrivbehörigheter. De anges i manifestet med attributen android:readPermission och android:writePermission. Om klientapplikationen inte har motsvarande behörighet kommer systemet att avvisa anropet med SecurityException.
Android stöder tillfälliga behörigheter via flaggorna FLAG_GRANT_READ_URI_PERMISSION och FLAG_GRANT_WRITE_URI_PERMISSION. Detta är användbart när en applikation skickar URI:n för en fil till en annan applikation via Intent — mottagaren får endast åtkomst till den specifika URI:n under begränsad tid. Systemet återkallar den tillfälliga behörigheten efter att den mottagande applikationen slutförts.
För systemleverantörer kräver Android att specifika behörigheter anges i applikationsmanifestet. Till exempel för åtkomst till kontakter krävs READ_CONTACTS, för kalendern — READ_CALENDAR. Från och med Android 6 begärs dessa behörigheter under körning, inte vid installation.
Vanliga frågor
Content Provider — är en Android-komponent som tillhandahåller ett standardgränssnitt för datautbyte mellan applikationer via ContentResolver. Den abstraherar lagringsmetoden (SQLite, filer, nätverk) och säkerställer säker dataåtkomst med kontroll över läs- och skrivbehörigheter.
Authority — är en unik identifieringssträng för leverantören som anges i AndroidManifest.xml. Den utgör den första delen av URI content://authority/path och används av systemet för att dirigera ContentResolver-anrop till rätt leverantör. Authority måste vara unik bland alla applikationer på enheten.
UriMatcher matchar URI:er med numeriska koder. Du lägger till mönster via addURI och anropar sedan match för att få koden för en inkommande URI. Detta gör det möjligt i metoderna query, insert, update, delete att avgöra vilken tabell eller post som efterfrågats och utföra motsvarande operation på databasen.
Ja, Cursor måste stängas efter användning. Om Cursor inte stängs uppstår en minnesläcka eftersom den håller en Binder-referens till leverantörens data. I Kotlin, använd funktionen use för automatisk stängning, och i Java — try-with-resources eller anrop av cursor.close() i finally-blocket.
Content Provider — är en komponent för dataåtkomst mellan applikationer, medan SQLiteDatabase är en intern lagring för en enskild applikation. Content Provider tillhandahåller URI-gränssnitt och behörighetskontroll, medan SQLiteDatabase arbetar direkt med databasen utan säkerhetsmekanismer på operativsystemsnivå.
Sammanfattning
Vi utvecklar en mobil applikation nyckelfärdigt
IT Sectr skapar iOS- och Android-applikationer för startups och företag sedan 2017. Vi ger dig råd och föreslår den bästa lösningen.
Läs också