Content Provider — tətbiqlər arasında məlumatlara giriş üçün vahid interfeys təmin edən Android komponentidir. O, fiziki saxlama (SQLite, fayllar, şəbəkə mənbələri) abstraksiyasını həyata keçirir və ContentResolver vasitəsilə təhlükəsiz məlumat mübadiləsini təmin edir. Android Developer Guide, 2026-ya görə, Content Provider Activity, Service və BroadcastReceiver ilə yanaşı Android tətbiqinin dörd əsas komponentindən biridir. Onun vəzifəsi — məlumatları digər tətbiqlər üçün oxu və yazma icazələri ilə əlçatan etməkdir.
Əsas məqamlar
Content Provider — mərkəzləşdirilmiş məlumat anbarına girişi idarə edən və digər tətbiqlərə vahid kontrakt interfeysi vasitəsilə təqdim edən Android komponentidir. O, saxlama təfərrüatlarını gizlədir: məlumatlar SQLite, fayl sistemində, buludda saxlanıla və ya şəbəkə sorğusunun nəticəsi ola bilər.
Android sistem məlumatları üçün daxili Content Provider-ləri ehtiva edir — ContactsContract, MediaStore, CalendarContract, CallLog. Üçüncü tərəf tətbiqləri də təhlükəsiz məlumat mübadiləsi üçün öz provayderlərini yarada bilər. Hər bir provayder AndroidManifest.xml-də authority — URI-nin birinci hissəsini təşkil edən unikal sətir göstərilməklə qeydiyyata alınır.
Content Provider klient-server modeli üzrə işləyir. Provayder altı məcburi metodu həyata keçirən server rolunu oynayır: query, insert, update, delete, getType və onCreate. Klient (digər tətbiq) provayderə ContentResolver vasitəsilə müraciət edir, o da çağırışları Android-in IPC mexanizmi ilə provayderin müvafiq metodlarına ötürür.
Hər bir Content Provider URI sxemi content:// ilə identifikasiya olunur. Məsələn, content://com.example.app.provider/items. Birinci hissə authority (com.example.app.provider) manifestdə provayder sinfinə bağlanır. /items yolu cədvəli, /items/5 isə ID=5 olan konkret qeydi göstərir.
Tətbiq ContentResolver.query(URI) çağırdıqda, Android çağıran paketin icazələrini yoxlayır, authority görə provayderi tapır və hələ işə düşməyibsə, onun prosesini başladır. Provayder sorğunu icra edir və Cursor — nəticəni ehtiva edən və klientə qeydlər üzrə iterasiya etməyə imkan verən obyekti qaytarır.
ContentProvider sinfi altı abstrakt metodun tətbiqini tələb edir. Hər bir metod URI qəbul edir və əməliyyat növünə uyğun nəticə qaytarır. Sistem bu metodları istənilən prosesdən çağırır, ona görə də onlar thread-safe olmalı və uzun müddət icranı bloklamamalıdır.
query metodu URI, sütunlar massivi projection, arqumentlərlə selection sətri və sıralama qaydasını qəbul edir. Məlumatlarla Cursor qaytarır. Tətbiqdə URI-ni UriMatcher ilə təhlil etmək və verilənlər bazasına müvafiq SQL sorğusunu yerinə yetirmək lazımdır.
Bu metodlar anbarda məlumatları dəyişdirir. insert ContentValues — açar-dəyər cütlərini qəbul edir və yeni qeydin URI-sini qaytarır. update və delete qeydləri filtrləmək üçün selection qəbul edir və təsirlənmiş sətirlərin sayını qaytarır. Məlumatları dəyişdikdən sonra provayder bu barədə ContentResolver.notifyChange vasitəsilə xəbərdar etməlidir.
| Metod | Məqsəd | Qaytarma |
|---|---|---|
| query | URI üzrə məlumatların alınması | Cursor və ya null |
| insert | Yeni qeydin əlavə edilməsi | Yeni qeydin URI-si |
| update | Mövcud qeydlərin yenilənməsi | int (sətirlərin sayı) |
| delete | Qeydlərin silinməsi | int (sətirlərin sayı) |
| getType | URI üçün MIME növü | String |
| onCreate | Provayderin inisializasiyası | boolean |
ContentResolver — sistemdəki bütün Content Provider-lərlə iş üçün vahid giriş nöqtəsidir. Klient tətbiq heç vaxt provayder metodlarını birbaşa çağırmır — yalnız ContentResolver vasitəsilə, Android bunu kontekstdən əldə edir. ContentResolver-də CRUD əməliyyatları provayderdəki kimi eyni adlara malikdir, lakin birbaşa istinadlar əvəzinə URI qəbul edir.
Provayder daxilində daxil olan URI-ləri təhlil etmək üçün UriMatcher istifadə olunur. O, URI-ni ədədi kodla uyğunlaşdırmağa imkan verir — məsələn, content://authority/items URI-si kod 1, content://authority/items/# isə kod 2 verir. Bu, hər bir metoddə URI sətirinin əl ilə təhlil edilməsinə ehtiyacı aradan qaldırır.
// Kontaktlara giriş üçün ContentResolver-dən istifadə
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("Kontaktlar", "Ad: $name")
}
}
Cursor istifadə edildikdən sonra mütləq bağlanmalıdır — yuxarıdakı nümunədə bunu use (Kotlin-ə genişləndirmə funksiyası) edir. Cursor bağlanmazsa, yaddaş sızması baş verəcək, çünki o, Binder hovuzunda məlumatlara istinad saxlayır. UI ssenariləri üçün CursorLoader və ya Room-u LiveData/Flow ilə istifadə edin.
Öz Content Provider-inizi yaratmaq ContentProvider sinfindən miras almaqla başlayır. Provayder SQLiteOpenHelper vasitəsilə SQLite bazası ilə işləyir və sorğu növünü müəyyən etmək üçün UriMatcher-dən istifadə edir. Qeydlər siyahısını idarə etmək üçün minimal tətbiqi nəzərdən keçirək.
Provayder AndroidManifest.xml-də application teqinin daxilində qeydiyyata alınır. authorities atributu unikal identifikatoru təyin edir, exported isə digər tətbiqlərin provayderə müraciət edə biləcəyini müəyyənləşdirir. exported=true olmadan provayder yalnız sizin tətbiqiniz daxilində əlçatandır.
// Qeydlər üçün Content Provider nümunəsi
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 qısalıq üçün buraxılıb
}
Sinif yaradıldıqdan sonra provayder android:authorities və android:exported (provayder ictimidirsə true) atributları ilə manifestdə qeydiyyata alınmalıdır. Sistem provayderin nümunəsini ona ilk müraciət zamanı yaradır — bu, UI axınında baş verir, ona görə də onCreate tez icra olunmalıdır.
Content Provider məlumatlara girişi iki səviyyədə idarə etməyə imkan verir: oxu icazələri və yazma icazələri. Onlar manifestdə android:readPermission və android:writePermission atributları ilə təyin edilir. Əgər klient tətbiqin müvafiq icazəsi yoxdursa, sistem zəngi SecurityException ilə rədd edəcək.
Android FLAG_GRANT_READ_URI_PERMISSION və FLAG_GRANT_WRITE_URI_PERMISSION bayraqları vasitəsilə müvəqqəti icazələri dəstəkləyir. Bu, tətbiq faylın URI-sini Intent vasitəsilə başqa tətbiqə ötürdükdə faydalıdır — alıcı yalnız konkret URI-yə məhdud müddət ərzində giriş əldə edir. Sistem müvəqqəti icazəni qəbul edən tətbiqin işi bitdikdən sonra ləğv edir.
Sistem provayderləri üçün Android tətbiq manifestində konkret icazələrin göstərilməsini tələb edir. Məsələn, kontaktlara giriş üçün READ_CONTACTS, təqvim üçün READ_CALENDAR tələb olunur. Android 6-dan başlayaraq bu icazələr quraşdırma zamanı deyil, icra zamanı tələb olunur.
Tez-tez verilən suallar
Content Provider — ContentResolver vasitəsilə tətbiqlər arasında məlumat mübadiləsi üçün standart interfeys təmin edən Android komponentidir. O, saxlama üsulunu (SQLite, fayllar, şəbəkə) abstraksiya edir və oxu/yazma icazələrinin nəzarəti ilə təhlükəsiz məlumat girişini təmin edir.
Authority — AndroidManifest.xml-də göstərilən provayderin unikal identifikator sətridir. O, content://authority/path URI-nin birinci hissəsini təşkil edir və sistem tərəfindən ContentResolver çağırışlarını müvafiq provayderə yönləndirmək üçün istifadə olunur. Authority cihazdakı bütün tətbiqlər arasında unikal olmalıdır.
UriMatcher URI-ləri ədədi kodlarla uyğunlaşdırır. Siz addURI vasitəsilə şablonlar əlavə edir, sonra daxil olan URI üçün kod almaq üçün match çağırırsınız. Bu, query, insert, update, delete metodlarında hansı cədvəl və ya qeydin tələb olunduğunu müəyyən etməyə və verilənlər bazasında müvafiq əməliyyatı yerinə yetirməyə imkan verir.
Bəli, Cursor istifadə edildikdən sonra mütləq bağlanmalıdır. Cursor bağlanmazsa, yaddaş sızması baş verəcək, çünki o, provayder məlumatlarına Binder istinadını saxlayır. Kotlin-də avtomatik bağlama üçün use funksiyasından, Java-da isə try-with-resources və ya finally blokunda cursor.close() çağırışından istifadə edin.
Content Provider — tətbiqlərarası məlumat girişi üçün komponentdir, halbuki SQLiteDatabase bir tətbiqin daxili anbarıdır. Content Provider URI interfeysi və icazə nəzarəti təmin edir, SQLiteDatabase isə OS səviyyəsində təhlükəsizlik mexanizmləri olmadan birbaşa baza ilə işləyir.
Nəticə
Açar təslim mobil tətbiq hazırlayacağıq
IT Sectr 2017-ci ildən startaplar və bizneslər üçün iOS və Android tətbiqləri yaradır. Sizə məsləhət verəcəyik və ən yaxşı həlli təklif edəcəyik.
Həm də oxuyun