Content Provider: co to je, architektura komponenty a princip fungování

Autor: IT Sectr Publikováno: 2026-06-17 Doba čtení: 8 min

Content Provider — je komponenta Androidu, která poskytuje jednotné rozhraní pro přístup k datům mezi aplikacemi. Abstrahuje fyzické úložiště (SQLite, soubory, síťové zdroje) a zajišťuje bezpečnou výměnu informací prostřednictvím ContentResolveru. Podle Android Developer Guide, 2026 je Content Provider jednou ze čtyř základních komponent aplikace pro Android vedle Activity, Service a BroadcastReceiver. Jeho úkolem je zpřístupnit data jiným aplikacím s kontrolou oprávnění pro čtení a zápis.

Hlavní body

  • Content Provider — standardní komponenta Androidu pro výměnu dat mezi aplikacemi prostřednictvím rozhraní ContentResolver.
  • URI (content://) identifikuje tabulku nebo záznam a používá se pro všechny operace CRUD s poskytovatelem.
  • UriMatcher — pomocná třída, která parsuje příchozí URI a určuje, která tabulka nebo řádek byl požadován.
  • Oprávnění pro čtení a zápis se nastavují v manifestu a vyžadují se od uživatele při instalaci.
  • CursorLoader nebo Room s Content Provider zajišťují asynchronní načítání dat od poskytovatele bez blokování vlákna UI.

Co je Content Provider?

Content Provider — je komponenta Androidu, která spravuje přístup k centralizovanému úložišti dat a poskytuje je jiným aplikacím prostřednictvím jednotného kontraktního rozhraní. Skrývá detaily implementace úložiště: data mohou být uložena v SQLite, v souborovém systému, v cloudu nebo být výsledkem síťového požadavku.

Android zahrnuje vestavěné Content Provider pro systémová data — ContactsContract, MediaStore, CalendarContract, CallLog. Aplikace třetích stran mohou také vytvářet vlastní poskytovatele pro bezpečnou výměnu dat. Každý poskytovatel je registrován v AndroidManifest.xml s uvedením authority — jedinečného řetězce, který tvoří první část URI.

Jak funguje Content Provider

Content Provider funguje podle modelu klient-server. Poskytovatel vystupuje jako server, který implementuje šest povinných metod: query, insert, update, delete, getType a onCreate. Klient (jiná aplikace) přistupuje k poskytovateli prostřednictvím ContentResolveru, který předává volání odpovídajícím metodám poskytovatele přes mechanismus IPC Androidu.

URI a authority

Každý Content Provider je identifikován URI schématu content://. Například content://com.example.app.provider/items. První část authority (com.example.app.provider) je vázána na třídu poskytovatele v manifestu. Cesta /items ukazuje na tabulku a /items/5 — na konkrétní záznam s ID=5.

Proces volání

Když aplikace zavolá ContentResolver.query(URI), Android zkontroluje oprávnění volajícího balíčku, najde poskytovatele podle authority a spustí jeho proces, pokud ještě není spuštěn. Poskytovatel provede dotaz a vrátí Cursor — objekt obsahující výsledek, který umožňuje klientovi iterovat přes záznamy.

Hlavní metody Content Provider

Třída ContentProvider vyžaduje implementaci šesti abstraktních metod. Každá metoda přijímá URI a vrací výsledek odpovídající typu operace. Systém volá tyto metody z libovolného procesu, takže musí být thread-safe a nesmí blokovat provádění na dlouhou dobu.

Metoda query

Metoda query přijímá URI, pole sloupců projection, řetězec selection s argumenty a pořadí řazení. Vrací Cursor s daty. V implementaci je třeba rozebrat URI pomocí UriMatcher a provést odpovídající SQL dotaz do databáze.

Metody insert, update, delete

Tyto metody mění data v úložišti. insert přijímá ContentValues — páry klíč-hodnota — a vrací URI nového záznamu. update a delete přijímají selection pro filtrování záznamů a vracejí počet ovlivněných řádků. Po změně dat musí poskytovatel oznámit tuto skutečnost prostřednictvím ContentResolver.notifyChange.

MetodaÚčelNávratová hodnota
queryZískání dat podle URICursor nebo null
insertPřidání nového záznamuURI nového záznamu
updateAktualizace existujících záznamůint (počet řádků)
deleteSmazání záznamůint (počet řádků)
getTypeMIME typ pro URIString
onCreateInicializace poskytovateleboolean

ContentResolver a URI v Androidu

ContentResolver — je jednotný přístupový bod pro práci se všemi Content Provider v systému. Klientská aplikace nikdy nevolá metody poskytovatele přímo — pouze prostřednictvím ContentResolveru, který Android získává z kontextu. CRUD operace v ContentResolveru mají stejná jména jako u poskytovatele, ale přijímají URI místo přímých referencí.

UriMatcher

Pro parsování příchozích URI uvnitř poskytovatele se používá UriMatcher. Umožňuje přiřadit URI k číselnému kódu — například URI content://authority/items dává kód 1 a content://authority/items/# — kód 2. Tím odpadá nutnost ručního parsování řetězce URI v každé metodě.

kotlin
// Použití ContentResolver pro přístup ke kontaktům
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("Kontakty", "Jméno: $name")
    }
}

Cursor je třeba po použití zavřít — v příkladu výše to dělá use (rozšiřující funkce Kotlinu). Pokud Cursor není uzavřen, dojde k úniku paměti, protože drží referenci na data v Binder poolu. Pro UI scénáře používejte CursorLoader nebo Room s LiveData/Flow.

Příklad Content Provider v Kotlinu

Vytvoření vlastního Content Provider začíná děděním z třídy ContentProvider. Poskytovatel pracuje s databází SQLite prostřednictvím SQLiteOpenHelper a používá UriMatcher k určení typu dotazu. Podívejme se na minimální implementaci pro správu seznamu poznámek.

Registrace v manifestu

Poskytovatel se registruje v AndroidManifest.xml uvnitř tagu application. Atribut authorities nastavuje jedinečný identifikátor a exported určuje, zda jiné aplikace mohou k poskytovateli přistupovat. Bez exported=true je poskytovatel přístupný pouze v rámci vaší aplikace.

kotlin
// Příklad Content Provider pro poznámky
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 vynechány pro stručnost
}

Po vytvoření třídy je třeba poskytovatele zaregistrovat v manifestu s atributy android:authorities a android:exported (true, pokud je poskytovatel veřejný). Systém vytváří instanci poskytovatele při prvním přístupu — to se děje ve vlákně UI, takže onCreate by se měl provádět rychle.

Ochrana dat pomocí oprávnění

Content Provider umožňuje řídit přístup k datům na dvou úrovních: oprávnění pro čtení a oprávnění pro zápis. Ty se nastavují v manifestu atributy android:readPermission a android:writePermission. Pokud klientská aplikace nemá příslušné oprávnění, systém odmítne volání s výjimkou SecurityException.

Oprávnění na úrovni URI

Android podporuje dočasná oprávnění prostřednictvím příznaků FLAG_GRANT_READ_URI_PERMISSION a FLAG_GRANT_WRITE_URI_PERMISSION. To je užitečné, když aplikace předává URI souboru jiné aplikaci prostřednictvím Intent — příjemce získá přístup pouze ke konkrétnímu URI na omezenou dobu. Systém odvolá dočasné oprávnění po dokončení přijímající aplikace.

Pro systémové poskytovatele Android vyžaduje uvedení konkrétních oprávnění v manifestu aplikace. Například pro přístup ke kontaktům je potřeba READ_CONTACTS, pro kalendář — READ_CALENDAR. Od Androidu 6 jsou tato oprávnění vyžadována za běhu, nikoli při instalaci.

Často kladené otázky

Co je Content Provider v Androidu?

Content Provider — je komponenta Androidu, která poskytuje standardní rozhraní pro výměnu dat mezi aplikacemi prostřednictvím ContentResolveru. Abstrahuje způsob ukládání (SQLite, soubory, síť) a zajišťuje bezpečný přístup k datům s kontrolou oprávnění pro čtení a zápis.

Co je authority v Content Provider?

Authority — je jedinečný identifikační řetězec poskytovatele uvedený v AndroidManifest.xml. Tvoří první část URI content://authority/path a systém jej používá pro směrování volání ContentResolveru k příslušnému poskytovateli. Authority musí být jedinečná mezi všemi aplikacemi v zařízení.

Jak funguje UriMatcher v Content Provider?

UriMatcher přiřazuje URI k číselným kódům. Přidáte vzory pomocí addURI a poté zavoláte match pro získání kódu pro příchozí URI. To umožňuje v metodách query, insert, update, delete určit, která tabulka nebo záznam byl požadován, a provést odpovídající operaci s databází.

Je třeba zavřít Cursor po práci s ContentResolver?

Ano, Cursor je třeba po použití zavřít. Pokud Cursor není uzavřen, dojde k úniku paměti, protože drží Binder referenci na data poskytovatele. V Kotlinu použijte funkci use pro automatické zavírání, v Javě — try-with-resources nebo volání cursor.close() v finally bloku.

Čím se liší Content Provider od SQLiteDatabase?

Content Provider — je komponenta pro meziaplikační přístup k datům, zatímco SQLiteDatabase je interní úložiště jedné aplikace. Content Provider poskytuje URI rozhraní a kontrolu oprávnění, zatímco SQLiteDatabase pracuje přímo s databází bez bezpečnostních mechanismů na úrovni operačního systému.

Shrnutí

  • Content Provider — je standardní komponenta Androidu pro bezpečnou výměnu dat mezi aplikacemi prostřednictvím jednotného rozhraní ContentResolver.
  • URI schématu content://authority/path/id identifikuje poskytovatele, tabulku a konkrétní záznam — každý segment má přesný účel.
  • UriMatcher zjednodušuje parsování příchozích URI uvnitř poskytovatele, čímž odpadá ruční parsování řetězců v každé CRUD metodě.
  • Poskytovatel se registruje v AndroidManifest.xml s atributy authorities a exported — to je systémový mechanismus, bez kterého poskytovatel nebude fungovat.
  • ContentValues se předávají do insert a update jako sada párů klíč-hodnota a Cursor je vrácen z query pro iteraci výsledků.
  • Oprávnění readPermission a writePermission v manifestu řídí přístup k datům a FLAG_GRANT_URI_PERMISSION poskytuje dočasný přístup ke konkrétnímu URI.
  • Pro asynchronní načítání dat z Content Provider použijte CursorLoader, Room s ContentProvider nebo LoaderManager — zabráníte tím blokování vlákna UI.

Vyvineme mobilní aplikaci na klíč

IT Sectr vytváří aplikace pro iOS a Android pro startupy a podniky od roku 2017. Poradíme vám a navrhneme nejlepší řešení.

Prodiskutovat projekt

Přečtěte si také