Content Provider est un composant Android qui fournit une interface unifiée pour l'accès aux données entre applications. Il abstrait le stockage physique (SQLite, fichiers, sources réseau) et permet l'échange sécurisé d'informations via ContentResolver. Selon Android Developer Guide, 2026, Content Provider est l'un des quatre composants principaux d'une application Android, avec Activity, Service et BroadcastReceiver. Sa tâche est de rendre les données disponibles à d'autres applications avec un contrôle des autorisations de lecture et d'écriture.
Points clés
Content Provider est un composant Android qui gère l'accès à un magasin de données centralisé et le fournit à d'autres applications via une interface contractuelle unifiée. Il cache les détails d'implémentation du stockage : les données peuvent être stockées dans SQLite, sur le système de fichiers, dans le cloud ou être le résultat d'une requête réseau.
Android inclut des Content Providers intégrés pour les données système — ContactsContract, MediaStore, CalendarContract, CallLog. Les applications tierces peuvent également créer leurs propres fournisseurs pour un échange sécurisé de données. Chaque fournisseur est enregistré dans AndroidManifest.xml avec une authority — une chaîne unique qui forme la première partie de l'URI.
Content Provider fonctionne selon un modèle client-serveur. Le fournisseur agit comme un serveur qui implémente six méthodes obligatoires : query, insert, update, delete, getType et onCreate. Le client (une autre application) accède au fournisseur via ContentResolver, qui traduit les appels en méthodes correspondantes du fournisseur via le mécanisme IPC d'Android.
Chaque Content Provider est identifié par une URI du schéma content://. Par exemple, content://com.example.app.provider/items. La première partie authority (com.example.app.provider) est liée à la classe du fournisseur dans le manifeste. Le chemin /items pointe vers une table, tandis que /items/5 pointe vers un enregistrement spécifique avec ID=5.
Lorsqu'une application appelle ContentResolver.query(URI), Android vérifie les autorisations du package appelant, trouve le fournisseur par son authority et démarre son processus s'il n'est pas déjà en cours d'exécution. Le fournisseur exécute la requête et retourne un Cursor — un objet qui contient le résultat et permet au client d'itérer sur les enregistrements.
La classe ContentProvider nécessite l'implémentation de six méthodes abstraites. Chaque méthode accepte une URI et retourne un résultat correspondant au type d'opération. Le système appelle ces méthodes depuis n'importe quel processus, elles doivent donc être thread-safe et ne pas bloquer l'exécution longtemps.
La méthode query accepte une URI, un tableau de colonnes projection, une chaîne selection avec arguments et un ordre de tri. Elle retourne un Cursor avec les données. Dans l'implémentation, vous devez analyser l'URI avec UriMatcher et exécuter la requête SQL correspondante dans la base de données.
Ces méthodes modifient les données dans le magasin. insert reçoit ContentValues — des paires clé-valeur — et retourne l'URI du nouvel enregistrement. update et delete acceptent une selection pour filtrer les enregistrements et retournent le nombre de lignes affectées. Après modification des données, le fournisseur doit notifier via ContentResolver.notifyChange.
| Méthode | Objectif | Retour |
|---|---|---|
| query | Obtenir des données par URI | Cursor ou null |
| insert | Ajouter un nouvel enregistrement | URI du nouvel enregistrement |
| update | Mettre à jour des enregistrements existants | int (nb de lignes) |
| delete | Supprimer des enregistrements | int (nb de lignes) |
| getType | Type MIME pour l'URI | String |
| onCreate | Initialisation du fournisseur | boolean |
ContentResolver est un point d'accès unique pour travailler avec tous les Content Providers du système. L'application cliente n'appelle jamais directement les méthodes du fournisseur — seulement via ContentResolver, qu'Android obtient depuis le contexte. Les opérations CRUD dans ContentResolver ont les mêmes noms que dans le fournisseur mais acceptent des URI au lieu de références directes.
Pour analyser les URI entrantes à l'intérieur du fournisseur, on utilise UriMatcher. Il permet de mapper une URI à un code numérique — par exemple, l'URI content://authority/items donne le code 1, et content://authority/items/# donne le code 2. Cela élimine le besoin d'analyse manuelle de la chaîne URI dans chaque méthode.
// Utilisation de ContentResolver pour accéder aux contacts
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("Contacts", "Nom : $name")
}
}
Le Cursor doit toujours être fermé après utilisation — dans l'exemple ci-dessus, la fonction use (extension Kotlin) le fait. Si le Cursor n'est pas fermé, une fuite de mémoire se produit car il maintient une référence aux données dans le pool Binder. Pour les scénarios UI, utilisez CursorLoader ou Room avec LiveData/Flow.
La création de votre propre Content Provider commence par l'extension de la classe ContentProvider. Le fournisseur travaille avec une base de données SQLite via SQLiteOpenHelper et utilise UriMatcher pour déterminer le type de requête. Considérez une implémentation minimale pour gérer une liste de notes.
Le fournisseur est enregistré dans AndroidManifest.xml à l'intérieur de la balise application. L'attribut authorities définit un identifiant unique, et exported détermine si d'autres applications peuvent accéder au fournisseur. Sans exported=true, le fournisseur n'est accessible qu'au sein de votre application.
// Exemple de Content Provider pour les notes
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 omis par souci de concision
}
Après avoir créé la classe du fournisseur, elle doit être enregistrée dans le manifeste avec les attributs android:authorities et android:exported (true si le fournisseur est public). Le système crée une instance du fournisseur au premier accès — cela se produit dans le thread UI, donc onCreate doit s'exécuter rapidement.
Content Provider permet de gérer l'accès aux données à deux niveaux : autorisations de lecture et autorisations d'écriture. Elles sont définies dans le manifeste avec les attributs android:readPermission et android:writePermission. Si l'application cliente ne dispose pas de l'autorisation correspondante, le système rejette l'appel avec une SecurityException.
Android prend en charge les autorisations temporaires via les drapeaux FLAG_GRANT_READ_URI_PERMISSION et FLAG_GRANT_WRITE_URI_PERMISSION. Ceci est utile lorsqu'une application transmet une URI de fichier à une autre application via Intent — le destinataire obtient l'accès uniquement à cette URI spécifique pour une durée limitée. Le système révoque l'autorisation temporaire après la fin de l'application destinataire.
Pour les fournisseurs système, Android exige la spécification d'autorisations spécifiques dans le manifeste de l'application. Par exemple, accéder aux contacts nécessite READ_CONTACTS, et accéder au calendrier nécessite READ_CALENDAR. À partir d'Android 6, ces autorisations sont demandées à l'exécution, pas lors de l'installation.
Foire aux questions
Content Provider est un composant Android qui fournit une interface standard pour l'échange de données entre applications via ContentResolver. Il abstrait la méthode de stockage (SQLite, fichiers, réseau) et garantit un accès sécurisé aux données avec contrôle des autorisations de lecture et d'écriture.
Authority est une chaîne d'identification unique du fournisseur spécifiée dans AndroidManifest.xml. Elle forme la première partie de l'URI content://authority/path et est utilisée par le système pour acheminer les appels ContentResolver vers le bon fournisseur. L'authority doit être unique parmi toutes les applications sur l'appareil.
UriMatcher mappe les URI à des codes numériques. Vous ajoutez des motifs via addURI, puis appelez match pour obtenir le code d'une URI entrante. Cela permet aux méthodes query, insert, update et delete de déterminer quelle table ou enregistrement est demandé et d'effectuer l'opération correspondante dans la base de données.
Oui, le Cursor doit toujours être fermé après utilisation. Si le Cursor n'est pas fermé, une fuite de mémoire se produit car il maintient une référence Binder aux données du fournisseur. En Kotlin, utilisez la fonction use pour la fermeture automatique, et en Java — try-with-resources ou cursor.close() dans un bloc finally.
Content Provider est un composant pour l'accès aux données entre applications, tandis que SQLiteDatabase est un mécanisme de stockage interne pour une seule application. Content Provider fournit une interface URI et un contrôle des autorisations, tandis que SQLiteDatabase travaille directement avec la base de données sans mécanismes de sécurité au niveau du système d'exploitation.
Résumé
Nous développerons une application mobile clé en main
IT Sectr crée des applications iOS et Android pour les startups et les entreprises depuis 2017. Nous vous conseillerons et vous proposerons la meilleure solution.
Lisez aussi