İçerik sağlayıcı, merkezi bir veri deposuna erişimi yönetir. Bir
    sağlayıcısını bir veya daha fazla sınıf olarak düzenleyebilir ve
    manifest dosyasını açın. Sınıflarınızdan birinde şu alt sınıf uygulanıyor:
    ContentProvider, yani sağlayıcınız ile
    başka uygulamalar da var.
İçerik sağlayıcıların amacı, diğer kullanıcıların da en az uygulamanızda, kullanıcının başka uygulamaları kullanarak sağlayıcınız tarafından yönetilen verileri sorgulayabilir ve değiştirebilirsiniz.
Bu sayfa, içerik sağlayıcı ve liste oluşturmaya ilişkin temel süreci içerir API'lerden genel olarak bahsetmek istiyorum.
Yapı oluşturmaya başlamadan önce
Sağlayıcı oluşturmaya başlamadan önce aşağıdakileri göz önünde bulundurun:
- 
        İçerik sağlayıcıya ihtiyacınız olup olmadığına karar verin. İçerik üretmeniz ve
        aşağıdaki özelliklerden birini veya daha fazlasını sunmak isterseniz:
        - Karmaşık verileri veya dosyaları diğer uygulamalara sunmak istiyorsanız.
- Kullanıcıların uygulamanızdaki karmaşık verileri diğer uygulamalara kopyalamasına izin vermek istiyorsunuz.
- Arama çerçevesini kullanarak özel arama önerileri sunmak istiyorsunuz.
- Uygulama verilerinizi widget'lara göstermek istiyorsunuz.
- AbstractThreadedSyncAdapteröğesini uygulamak istiyorsanız,- CursorAdapterveya- CursorLoadersınıflar.
 Veritabanlarını veya diğer veri tabanlarını kullanmak için bir sağlayıcıya kullanım tamamen kendi uygulamanızdan gerçekleştiriliyorsa kalıcı depolama alanı Bu nedenle, yukarıda listelenen özelliklerden hiçbirine ihtiyacınız yok. Bunun yerine şurada açıklanan depolama sistemlerinden birini kullanmalısınız: Veri ve dosya depolamaya genel bakış. 
- Henüz yapmadıysanız İçerik sağlayıcılar ve bunların işleyiş şekli hakkında daha fazla bilgi edinmek için İçerik Sağlayıcı ile ilgili temel bilgiler bölümüne göz atın.
Ardından, sağlayıcınızı oluşturmak için aşağıdaki adımları uygulayın:
- 
        Verileriniz için ham depolama alanını tasarlayın. İçerik sağlayıcı, verileri iki şekilde sunar:
        - Dosya verileri
- . Örneğin, fotoğraf, ses veya video olabilir. Dosyaları uygulamanızın gizli boşluk oluşturur. Başka bir uygulamadan gelen dosya isteğine yanıt olarak, sağlayıcı, dosya için bir herkese açık kullanıcı adı sunabilir.
- "Yapılandırılmış" veri
- . Normalde bir veritabanına, diziye veya benzer bir yapıya giden verilerdir. Verileri, satır ve sütun tablolarıyla uyumlu bir formda depolayın. Bir satır envanterdeki bir kişi veya öğe gibi bir varlığı temsil eder. Bir sütun, varlıkla ilgili bazı veriler (ör. kişinin adı veya ürünün fiyatı). Bir projede bir SQLite veritabanında bulunmasını gerektirir, ancak kalıcı depolama alanıdır. Şurada kullanılabilen depolama alanı türleri hakkında daha fazla bilgi edinin: Android sistemi için: Veri depolamayı tasarlayın bölümüne bakın.
 
- 
        ContentProvidersınıfının somut bir uygulamasını tanımlama ve yöntemlerine göz atacağız. Bu sınıf, verilerinizle diğer Android sistemi. Bu sınıf hakkında daha fazla bilgi için bkz. ContentProvider sınıfını uygulama bölümünü inceleyin.
- Sağlayıcının yetki dizesini, içerik URI'lerini ve sütun adlarını tanımlayın. Şunu istiyorsanız: amaca hizmet eden, ayrıca intent işlemlerini, ekstra verileri ve ve işaretler. Ayrıca verilerinize erişmek için tıklayın. Tüm bu değerleri bir tablodaki sabit değerler olarak ayrı sözleşme sınıfı oluşturabilirsiniz. Daha sonra, bu sınıfı diğer geliştiricilere sunabilirsiniz. Daha fazla hakkında daha fazla bilgi için İçerik URI'leri tasarlama bölümü. Amaçlar hakkında daha fazla bilgi için şuraya bakın: Amaçlar ve veri erişimi bölümü.
- 
        Örnek veri veya uygulama gibi diğer isteğe bağlı parçaları ekleyin
        Şu veriler arasında veri senkronize edebilen: AbstractThreadedSyncAdaptersağlayıcı ve bulut tabanlı verilerdir.
Veri depolamayı tasarlayın
İçerik sağlayıcı, verilerin yapılandırılmış bir biçimde kaydedilmesi için kullanılan arayüzdür. Oluşturmadan önce arayüzde, verilerin nasıl depolanacağına karar verir. Verileri, Google Etiket Yöneticisi'ni kullanarak ve ardından arayüzü, verileri gerektiği gibi okuyup yazacak şekilde tasarlar.
Android'de kullanılabilen veri depolama teknolojilerinden bazıları şunlardır:
- Yapılandırılmış verilerle çalışıyorsanız Google Analytics 4'teki gibi ilişkisel olmayan bir anahtar/değer veri deposu LevelDB. Çalışıyorsanız yapılandırılmamış verilerle (ör. ses, resim veya video medyası) kullanabilirsiniz. verileri dosya olarak kaydeder. Çeşitli depolama türlerini bir arada kullanabilir ve kullanabilirsiniz. tek bir içerik sağlayıcı kullanmayı deneyebilirsiniz.
- 
        Android sistemi, oda kalıcılık kitaplığıyla etkileşimde bulunabilir.
        Android'in kendi sağlayıcılarının kullandığı SQLite veritabanı API'sine erişim sağlar
        depolamak için de kullanabilirsiniz. Bu komutu kullanarak veritabanı oluşturmak için
        alt sınıfını örneklendirir,
        
        RoomDatabase, aşağıda açıklandığı gibi Odayı kullanarak verileri yerel bir veritabanına kaydedin.Deponuzu uygulamak için veritabanı kullanmanız gerekmez. Sağlayıcı harici olarak, ilişkisel bir veritabanına benzer şekilde bir tablo grubu olarak görünür ancak bu, sağlayıcının dahili uygulaması için bir gereklilik değildir. 
- Android'de dosya verilerini depolamak için çeşitli dosya odaklı API'ler bulunur. Dosya depolama alanı hakkında daha fazla bilgi edinmek için Veri ve dosya depolamaya genel bakış. Eğer müzik veya video gibi medyayla ilgili veriler sunan bir sağlayıcı tasarlarken, tablo verilerini ve dosyaları birleştiren bir sağlayıcıya sahip olmanız gerekir.
- Nadir durumlarda, birden fazla içerik sağlayıcıdan yararlanmak için tek bir uygulamada kullanılabilir. Örneğin, widget'la veri paylaşmak için ve diğer kullanıcılarla paylaşmak için farklı bir veri kümesi sunmanız, izin verir.
- 
        Ağ tabanlı verilerle çalışmak için java.netveandroid.net. Ağ tabanlı verileri yerel verilerle senkronize edebilirsiniz daha sonra verileri tablo veya dosyalar halinde sunabilirsiniz.
Not: Deponuzda olduğu için depoyu yeni bir sürümle işaretlemeniz sayı. Ayrıca, uygulamanızın sürüm numarasını da yeni içerik sağlayıcıyı uygular. Bu değişiklik, sistemin bir uygulamayı yeniden yüklemeyi denediğinde sistemin çökmesine neden uygulamama e-posta göndeririz.
Veri tasarımıyla ilgili dikkat edilmesi gereken noktalar
Aşağıda sağlayıcınızın veri yapısını tasarlamaya yönelik bazı ipuçları verilmiştir:
- 
        Tablo verilerinde her zaman "birincil anahtar" olmalıdır her bir imza için
        kullanabilirsiniz. Satırı ilgili
        satırlarını ("yabancı anahtar" olarak kullanarak) seçin. Her ne kadar
        BaseColumns._IDkullanmak en iyisidir. çünkü sağlayıcı sorgusunun sonuçlarınıListView, alınan sütunlardan birinin adının olmasını gerektiriyor_ID.
- 
        Bit eşlem resimleri veya diğer çok büyük dosya odaklı verileri sağlamak isterseniz,
        depolayıp doğrudan bir dosyada saklamak yerine dolaylı olarak sağlamak
        tablosunu oluşturalım. Bunu yaparsanız sağlayıcınızın kullanıcılarına bir
        ContentResolverdosya yöntemini kullanarak verilere erişebilirsiniz.
- 
        Boyut olarak değişiklik gösteren veya
        yapılabiliyor. Örneğin, her bir anahtar kelime için bir BLOB sütunu
        protokol arabelleği veya
        JSON yapısı.
        BLOB'u, şemadan bağımsız bir tablo uygulamak için de kullanabilirsiniz. İçinde bir birincil anahtar sütunu, MIME türü sütun ve bir ya da daha fazla daha genel sütunları BLOB olarak değiştirin. BLOB sütunlarındaki verilerin anlamı MIME türü sütunundaki değere göre. Bu, farklı satır türlerini şurada depolamanıza olanak tanır: aynı tablodur. Kişi Sağlayıcı'nın "verileri" masa ContactsContract.Data, şemadan bağımsız bir örnektir tablosunu oluşturalım.
İçerik URI'lerini tasarlama
    İçerik URI'si, bir sağlayıcıdaki verileri tanımlayan bir URI'dir. İçerik URI'leri şunları içerir:
    tüm sağlayıcının (yetkilendirmesi) sembolik adı
    bir tabloyu veya dosyayı işaret eden ad (yol). İsteğe bağlı kimlik bölümü,
    tek bir satıra ekleyebilirsiniz. Şunun her veri erişim yöntemi:
    ContentProvider, bağımsız değişken olarak bir içerik URI'sine sahip. Bu şekilde şunları yapabilirsiniz:
    erişilecek tabloyu, satırı veya dosyayı belirleyin.
İçerik URI'leri hakkında bilgi için bkz. İçerik sağlayıcıyla ilgili temel bilgiler.
Bir otorite tasarlayın
Bir sağlayıcının genellikle Android dahili adı olarak işlev gören tek bir yetkilisi vardır. Alıcı: diğer sağlayıcılarla çakışmaları önler, internet alan adı sahipliğini kullan (ters sırada) belirlemektir. Bu öneri Android için de geçerli olduğu için bir uzantı olarak tanımlarsanız, sağlayıcı yetkilinizi paketinin verilerini içerir.
Örneğin, Android paketinizin adı
    com.example.<appname>, sağlayıcınıza
    yetkili com.example.<appname>.provider.
Yol yapısı tasarlama
    Geliştiriciler genellikle yetkiliden içerik URI'leri oluşturur. Bunun için
    kullanabilirsiniz. Örneğin, iki tablonuz varsa: table1 ve
    tablo2'yi kullanarak aşağıdaki örnekteki yetkiliyle birleştirebilirsiniz:
    içerik URI'leri
    com.example.<appname>.provider/table1 ve
    com.example.<appname>.provider/table2. Yollar
    tek bir segmentle sınırlıdır ve yolun her düzeyi için bir tablo olması gerekmez.
İçerik URI'si kimliklerini işleme
    Genel olarak, sağlayıcılar içerik URI'sini kabul ederek tablodaki tek bir satıra erişim sunar
    URI'nın sonundaki satır için bir kimlik değeriyle birlikte girin. Ayrıca kurala göre, sağlayıcılar
    Kimlik değerini, tablonun _ID sütununa girin ve istenen erişimi
    satır ekleyin.
    Bu kural, sağlayıcıya erişen uygulamalar için ortak bir tasarım kalıbını basitleştirir. Uygulama
    sağlayıcıya karşı bir sorgu yapar ve sonuç olarak elde edilen Cursor değerini görüntüler
    CursorAdapter kullanarak ListView içinde.
    CursorAdapter tanımı için
    _ID olacak Cursor
    Daha sonra, kullanıcı arayüzünde görüntülenen satırlardan birini seçerek
    dışı verilerdir. Uygulama, ilgili satırı Cursor sütunundan alır ve
    ListView, bu satır için _ID değerini alır ve şunu ekler:
    içerik URI'sini bulup erişim isteğini sağlayıcıya gönderir. Ardından sağlayıcı
    kullanıcının seçtiği satıra göre sorgu veya değişiklik yapabilirsiniz.
İçerik URI'si kalıpları
    Sağlayıcı API'si, gelen içerik URI'si için hangi işlemi gerçekleştireceğinizi seçmenize yardımcı olmak üzere
    içerik URI'si kalıplarınıUriMatcher
    tamsayı değerleri. Bir switch ifadesinde tam sayı değerlerini kullanabilirsiniz:
    belirli bir kalıpla eşleşen içerik URI'si veya URI'lar için istenen işlemi seçer.
İçerik URI'si kalıbı, joker karakterler kullanarak içerik URI'lerini eşleştirir:
- 
            *, herhangi bir uzunluktaki geçerli herhangi bir karakterden oluşan bir dizeyle eşleşir.
- 
            #, herhangi bir uzunluktaki sayısal karakterlerden oluşan bir dizeyle eşleşir.
    İçerik URI işlemesini tasarlama ve kodlamayla ilgili örnek olarak
    Aşağıdaki içerik URI'lerini tanıyan yetkili com.example.app.provider
    bir örnek:
- 
        content://com.example.app.provider/table1:table1adlı bir tablo.
- 
        content://com.example.app.provider/table2/dataset1: adlı tablodataset1.
- 
        content://com.example.app.provider/table2/dataset2: adlı tablodataset2.
- 
        content://com.example.app.provider/table3:table3adlı bir tablo.
    Sağlayıcı, eklenmiş bir satır kimliği varsa bu içerik URI'larını da tanır. Örneğin,content://com.example.app.provider/table3/1
    table3 içinde 1.
Aşağıdaki içerik URI'si kalıpları mümkündür:
- 
        content://com.example.app.provider/*
- . Sağlayıcıdaki herhangi bir içerik URI'siyle eşleşir.
- 
        content://com.example.app.provider/table2/*
- .
        dataset1tabloları için bir içerik URI'siyle eşleşir vedataset2ile eşleşmez ancaktable1veyatable3.
- 
        content://com.example.app.provider/table3/#
- .
      Bir içerik URI'si ile eşleşir
        table3değerindeki tek satırlar için; örneğin, tarafından tanımlanan satır içincontent://com.example.app.provider/table3/66.
    Aşağıdaki kod snippet'i, UriMatcher içindeki yöntemlerin nasıl çalıştığını gösterir.
    Bu kod, bir tablonun tamamı için URI'ları, bir
    içerik URI kalıbı kullanılarak tek satır
    Tablolar için content://<authority>/<path> ve
    Tek satırlar için content://<authority>/<path>/<id>.
    addURI() yöntemi
    otoriteyi ve tam sayı değerine giden yolu gösterir. match() yöntemi, bir URI için tam sayı değerini döndürür. switch ifadesi
    Tüm tabloyu sorgulama ile tek bir kayıt için sorgulama arasında seçim yapar.
Kotlin
private val sUriMatcher = UriMatcher(UriMatcher.NO_MATCH).apply { /* * The calls to addURI() go here for all the content URI patterns that the provider * recognizes. For this snippet, only the calls for table 3 are shown. */ /* * Sets the integer value for multiple rows in table 3 to 1. Notice that no wildcard is used * in the path. */ addURI("com.example.app.provider", "table3", 1) /* * Sets the code for a single row to 2. In this case, the # wildcard is * used. content://com.example.app.provider/table3/3 matches, but * content://com.example.app.provider/table3 doesn't. */ addURI("com.example.app.provider", "table3/#", 2) } ... class ExampleProvider : ContentProvider() { ... // Implements ContentProvider.query() override fun query( uri: Uri?, projection: Array<out String>?, selection: String?, selectionArgs: Array<out String>?, sortOrder: String? ): Cursor? { var localSortOrder: String = sortOrder ?: "" var localSelection: String = selection ?: "" when (sUriMatcher.match(uri)) { 1 -> { // If the incoming URI was for all of table3 if (localSortOrder.isEmpty()) { localSortOrder = "_ID ASC" } } 2 -> { // If the incoming URI was for a single row /* * Because this URI was for a single row, the _ID value part is * present. Get the last path segment from the URI; this is the _ID value. * Then, append the value to the WHERE clause for the query. */ localSelection += "_ID ${uri?.lastPathSegment}" } else -> { // If the URI isn't recognized, // do some error handling here } } // Call the code to actually do the query } }
Java
public class ExampleProvider extends ContentProvider { ... // Creates a UriMatcher object. private static final UriMatcher uriMatcher = new UriMatcher(UriMatcher.NO_MATCH); static { /* * The calls to addURI() go here for all the content URI patterns that the provider * recognizes. For this snippet, only the calls for table 3 are shown. */ /* * Sets the integer value for multiple rows in table 3 to one. No wildcard is used * in the path. */ uriMatcher.addURI("com.example.app.provider", "table3", 1); /* * Sets the code for a single row to 2. In this case, the # wildcard is * used. content://com.example.app.provider/table3/3 matches, but * content://com.example.app.provider/table3 doesn't. */ uriMatcher.addURI("com.example.app.provider", "table3/#", 2); } ... // Implements ContentProvider.query() public Cursor query( Uri uri, String[] projection, String selection, String[] selectionArgs, String sortOrder) { ... /* * Choose the table to query and a sort order based on the code returned for the incoming * URI. Here, too, only the statements for table 3 are shown. */ switch (uriMatcher.match(uri)) { // If the incoming URI was for all of table3 case 1: if (TextUtils.isEmpty(sortOrder)) sortOrder = "_ID ASC"; break; // If the incoming URI was for a single row case 2: /* * Because this URI was for a single row, the _ID value part is * present. Get the last path segment from the URI; this is the _ID value. * Then, append the value to the WHERE clause for the query. */ selection = selection + "_ID = " + uri.getLastPathSegment(); break; default: ... // If the URI isn't recognized, do some error handling here } // Call the code to actually do the query }
    Başka bir sınıf (ContentUris), çalışma için kolaylık yöntemleri sunuyor
    içerik URI'lerinin id bölümü ile. Uri ve
    Uri.Builder, mevcut verileri ayrıştırmak için kolaylık yöntemleri içeriyor
    Uri nesne ve yeni nesneler oluşturuluyor.
ContentProvider sınıfını uygulama
    Erişimi ContentProvider örneği yönetiyor
    istekleri ele alarak yapılandırılmış bir veri kümesine dönüştürmenize yardımcı olur. Tüm formlar
    en sonunda ContentResolver işlemini çağırır ve ardından bir somut
    ContentProvider yöntemini kullanarak erişebilirsiniz.
Gerekli yöntemler
    ContentProvider soyut sınıfı
    alt sınıfınızın bir parçası olarak
uygulayacaksınız. Aşağıdakiler hariç tüm bu yöntemler
    onCreate(), bir istemci uygulaması tarafından çağrılıyor
    bir hata alırsınız.
- 
        query()
- .
        Sağlayıcınızdan veri alın. Aşağıdakileri yapmak için tabloyu seçmek üzere bağımsız değişkenleri kullanın:
        döndürülecek satırları ile sütunları ve sonucun sıralama düzenini belirtir.
        Verileri Cursornesnesi olarak döndürün.
- 
        insert()
- . Sağlayıcınıza yeni bir satır ekleyin. Şunu seçmek için bağımsız değişkenleri kullanın: hedef tablo oluşturmak ve kullanılacak sütun değerlerini almak için kullanılır. Şu öğe için içerik URI'si döndürün: yeni eklenen satır.
- 
        update()
- . Sağlayıcınızdaki mevcut satırları güncelleyin. Tabloyu ve satırları seçmek için bağımsız değişkenleri kullanın değerini girin. Güncellenen satır sayısını döndürür.
- 
        delete()
- . Sağlayıcınızdan satır silin. Tabloyu seçmek için bağımsız değişkenleri, kullanılacak satırları ve sil. Silinen satır sayısını döndürür.
- 
        getType()
- . İçerik URI'sine karşılık gelen MIME türünü döndürür. Bu yöntem aşağıda açıklandığı gibi bölümündeki İçerik sağlayıcı MIME türlerini uygulama bölümündeki ayrıntıları inceleyin.
- 
        onCreate()
- .
        Sağlayıcınızı başlatın. Android sistemi bu yöntemi hemen sonra çağırır
        sağlayıcınızı oluşturur. Sağlayıcınız şu tarihe kadar oluşturulmaz:
        ContentResolvernesnesi erişmeye çalışıyor.
    Bu yöntemler, aynı ada sahip olan
    ContentResolver yöntem.
Bu yöntemleri uygularken aşağıdakileri göz önünde bulundurmanız gerekir:
- 
        onCreate()hariç tüm bu yöntemler aynı anda birden çok iş parçacığı tarafından çağrılabilir; bu nedenle, ileti dizisi açısından güvenli olmaları gerekir. Öğrenmek için daha fazla bilgi edinmek için Süreçlere ve ileti dizilerine genel bakış.
- 
        onCreate()öğesinde uzun işlemler yapmaktan kaçının. Başlatma görevlerini gerçekten ihtiyaç duyulana kadar erteleyin. onCreate() yöntemini uygulama ile ilgili bölüm bu konuyu daha ayrıntılı olarak ele alacağız.
- 
        Bu yöntemleri uygulamanız gerekse de, kodunuzun başka bir işlem yapması gerekmez.
        beklenen veri türünü döndürür. Örneğin, belirli bir uygulama için
        bazı tablolara veri eklenmesini engelleyebilirsiniz.
        insert()ve dönüş 0
query() yöntemini uygulama
    İlgili içeriği oluşturmak için kullanılan
    ContentProvider.query() yöntemi, Cursor nesnesi döndürmelidir veya
    başarısız olursa Exception hatası verir. Verileriniz olarak SQLite veritabanı kullanıyorsanız
    depolama alanı dışında kalan Cursor
    SQLiteDatabase sınıfının query() yöntemi.
Sorgu hiçbir satırla eşleşmezse Cursor döndürün
    getCount() yöntemi 0 döndüren örnek.
    null değerini yalnızca sorgu işlemi sırasında dahili bir hata oluştuysa döndürün.
    Veri depolamanız olarak SQLite veritabanı kullanmıyorsanız somut alt sınıflardan birini kullanın
    / Cursor. Örneğin, MatrixCursor sınıfı
    her satırın Object örnekten oluşan bir dizi olduğu bir imleç uygular. Bu dersle
    yeni bir satır eklemek için addRow() öğesini kullanın.
    Android sistemi, Exception ile iletişim kurabilmelidir
    çok daha fazlasıdır. Android, bu işlemi aşağıdaki faydalı istisnalar için yapabilir:
    bazı hatalar mevcut:
- 
        IllegalArgumentException. Sağlayıcınız şu koşulları karşılıyorsa bunu atmayı tercih edebilirsiniz: geçersiz bir içerik URI'si alır.
- 
        NullPointerException
Insert() yöntemini uygulama
    insert() yöntemi,
    uygun tabloya ContentValues içindeki değerler kullanılarak yeni satır ekleyebilirsiniz.
    bağımsız değişkeninin önüne geçer. ContentValues bağımsız değişkeninde sütun adı yoksa
    sağlayıcı kodunuzda veya veritabanınızda bunun için varsayılan bir değer sağlamak isteyebilirsiniz.
    şema.
    Bu yöntem, yeni satırın içerik URI'sini döndürür. Bunu oluşturmak için
    satırın birincil anahtarını (genellikle _ID değerini) tablonun içerik URI'sine ekleyin.
    withAppendedId().
delete() yöntemini uygulama
    delete() yöntemi
    veri depolama alanınızdaki satırları silmesi gerekmez. Senkronizasyon adaptörü kullanıyorsanız
    sağlayıcınıza danışarak, silinmiş satırları işaretleyebilirsiniz
    "sil" ile işaretini kullanın. Senkronizasyon bağdaştırıcısı,
    sağlayıcıdan silmeden önce silinmiş satırları kontrol edip sunucudan kaldırın.
Update() yöntemini uygulama
    update() yöntemi,ContentValues
    insert() ve
    tarafından kullanılan aynı selection ve selectionArgs bağımsız değişkenleri
    delete() ve
    ContentProvider.query().
    Bu sayede kodu bu yöntemler arasında yeniden kullanabilirsiniz.
onCreate() yöntemini uygulama
    Android sistemi onCreate() çağırıyor
    sağlayıcıyı başlatır. Yalnızca hızlı çalışan başlatma yap
    ve veri tabanı oluşturma ile veri yüklemeyi, sağlayıcı gerçekten satın alınana kadar
    Veriler için bir istek alır. Sauce and Spoon’un tablet projesinde
    onCreate(),
    için bir fırsattır. Bu da sağlayıcının verdiği yanıtın diğerlerine
    izin verir.
    Aşağıdaki iki snippet, önceki videoda gördüğümüz
    ContentProvider.onCreate() ve
    
    Room.databaseBuilder(). İlk
    snippet,
    ContentProvider.onCreate() burada:
    veritabanı nesnesi oluşturulur ve veri erişimi nesnelerinin tutamaçları oluşturulduğunda:
Kotlin
// Defines the database name private const val DBNAME = "mydb" ... class ExampleProvider : ContentProvider() { // Defines a handle to the Room database private lateinit var appDatabase: AppDatabase // Defines a Data Access Object to perform the database operations private var userDao: UserDao? = null override fun onCreate(): Boolean { // Creates a new database object appDatabase = Room.databaseBuilder(context, AppDatabase::class.java, DBNAME).build() // Gets a Data Access Object to perform the database operations userDao = appDatabase.userDao return true } ... // Implements the provider's insert method override fun insert(uri: Uri, values: ContentValues?): Uri? { // Insert code here to determine which DAO to use when inserting data, handle error conditions, etc. } }
Java
public class ExampleProvider extends ContentProvider // Defines a handle to the Room database private AppDatabase appDatabase; // Defines a Data Access Object to perform the database operations private UserDao userDao; // Defines the database name private static final String DBNAME = "mydb"; public boolean onCreate() { // Creates a new database object appDatabase = Room.databaseBuilder(getContext(), AppDatabase.class, DBNAME).build(); // Gets a Data Access Object to perform the database operations userDao = appDatabase.getUserDao(); return true; } ... // Implements the provider's insert method public Cursor insert(Uri uri, ContentValues values) { // Insert code here to determine which DAO to use when inserting data, handle error conditions, etc. } }
ContentProvider MIME türlerini uygulama
    ContentProvider sınıfının, MIME türlerini döndürmek için iki yöntemi vardır:
- 
        getType()
- . Her sağlayıcı için uyguladığınız zorunlu yöntemlerden biridir.
- 
        getStreamTypes()
- . Sağlayıcınız dosya sunuyorsa uygulamanız beklenen bir yöntem.
Tablolar için MIME türleri
    getType() yöntemi,
    İçeriğin döndürdüğü veri türünü tanımlayan MIME biçiminde String
    URI bağımsız değişkeni. Uri bağımsız değişkeni, belirli bir URI yerine bir kalıp olabilir.
    Bu durumda
    desen.
    Metin, HTML veya JPEG gibi yaygın veri türleri için
    getType(), standardı döndürür
    MIME türüdür. Bu standart türlerin tam listesi
    IANA MIME Medya Türleri
    web sitesi.
    Tablo verileri satırına veya satırlarına işaret eden içerik URI'leri için
    getType() karşılığında iade
    Android'in tedarikçi firmaya özel MIME biçiminde bir MIME türü:
- 
        Parçayı yazın: vnd
- 
        Alt tür bölümü:
        - 
    URI kalıbı tek bir satır içinse: android.cursor.item/
- 
    URI kalıbı birden fazla satır içinse: android.cursor.dir/
 
- 
    URI kalıbı tek bir satır içinse: 
- 
        Sağlayıcıya özel bölüm: vnd.<name>.<type><name>ve<type>sizin tarafınızdan sağlanır.<name>değeri genel olarak benzersizdir. ve<type>değeri, karşılık gelen URI'ye özgüdür desen.<name>için şirketinizin adı veya uygulamanızın Android paket adının bir kısmıdır. Proje yöneticisi için<type>, URI.
    Örneğin, sağlayıcının yetkilisi
    com.example.app.provider ve
    table1, table1 içinde birden fazla satırın MIME türü:
vnd.android.cursor.dir/vnd.com.example.provider.table1
    Tek bir table1 satırı için MIME türü:
vnd.android.cursor.item/vnd.com.example.provider.table1
Dosyalar için MIME türleri
    Sağlayıcınız dosyalar sunuyorsa
    getStreamTypes()
    Yöntem, sağlayıcınızın dosyaları için bir String MIME türü dizisi döndürür
    döndürebilir. Sunduğunuz MIME türlerini MIME türüne göre filtreleyin
    filtre bağımsız değişkeninin önüne geçerek yalnızca istemcinin işlemek istediği MIME türlerini döndürürsünüz.
    Örneğin, fotoğraf resimlerini JPG dosyası olarak sunan bir sağlayıcı,
    PNG ve GIF biçiminde olması gerekir.
    Bir uygulama, image/* filtre dizesiyle ContentResolver.getStreamTypes() öğesini çağırırsa
    "görsel",
    ContentProvider.getStreamTypes() yöntemi diziyi döndürür:
{ "image/jpeg", "image/png", "image/gif"}
    Uygulama yalnızca JPG dosyalarıyla ilgileniyorsa
    *\/jpeg filtre dizesiyle ContentResolver.getStreamTypes() ve
    getStreamTypes() şunu iade etti:
{"image/jpeg"}
    Sağlayıcınız filtre dizesinde istenen MIME türlerinden herhangi birini sunmuyorsa
    getStreamTypes().
    null değerini döndürür.
Sözleşme sınıfı uygulama
    Sözleşme sınıfı,public final
    URI'lar, sütun adları, MIME türleri ve sağlayıcıyla ilgili diğer meta veriler. Sınıf
    uygun koşulları karşılayarak sağlayıcı ile diğer uygulamalar arasında bir sözleşme
    URL'lerin gerçek değerlerinde, sütun adlarının veya
    vb.
Sözleşme sınıfı, geliştiricilere de yardımcı olur çünkü genellikle sabit değerleri, hafızalarda önemli adlar verir. Bu nedenle, geliştiricilerin sütun adları veya URI'lar için yanlış değerler kullanma olasılığı daha düşüktür. Bu sınıfını değiştirmek için Javadoc dokümanlarını içerebilir. Şu gibi entegre geliştirme ortamları: Android Studio, sözleşme sınıfındaki sabit adları otomatik olarak tamamlar ve sabit değerler.
Geliştiriciler, sözleşme sınıfının sınıf dosyasına uygulamanızdan erişemezler, ancak şunları yapabilirler: sağladığınız bir JAR dosyasından uygulamasına statik olarak derler.
    ContactsContract sınıfı ve iç içe yerleştirilmiş sınıfları
    sözleşmeli sınıflar.
İçerik sağlayıcı izinlerini uygulama
Android sisteminin tüm özellikleriyle ilgili izinler ve erişim şurada ayrıntılı olarak açıklanmıştır: Güvenlik ipuçları. Veri ve dosya depolama alanına genel bakış da , çeşitli depolama türleri için geçerli olan güvenliği ve izinleri açıklar. Özetle önemli noktalar şunlardır:
- Varsayılan olarak, cihazın dahili depolama alanında depolanan veri dosyaları yalnızca ve sağlayıcıyı kullanabilirsiniz.
- 
        Oluşturduğunuz SQLiteDatabaseveritabanı size özeldir ve sağlayıcıyı kullanabilirsiniz.
- Harici depolama alanına kaydettiğiniz veri dosyaları varsayılan olarak herkese açıktır ve okunabilir. Şuradaki dosyalara erişimi kısıtlamak için bir içerik sağlayıcı kullanamazsınız: Çünkü diğer uygulamalar, bunları okumak ve yazmak için başka API çağrılarını kullanabilir.
- Yöntem, cihazınızın dahili ayarlarında dosya veya SQLite veritabanlarının açılmasını ya da oluşturulmasını gerektirir depolama alanı potansiyel olarak tüm diğer uygulamalara hem okuma hem de yazma erişimi verebilir. Şu durumda: sağlayıcınızın deposu olarak dahili bir dosya veya veritabanı kullanın ve bunu "dünya tarafından okunabilir" veya "dünyada-yazılabilir" içinde sağlayıcınız için belirlediğiniz izinleri verilerinizi korumaz. Şuradaki dosyalar ve veritabanları için varsayılan erişim: dahili depolama "gizli"dir; sağlayıcınızın deposu için bunu değiştirmeyin.
Verilerinize erişimi kontrol etmek için içerik sağlayıcı izinlerini kullanmak isterseniz verilerinizi dahili dosyalarda, SQLite veritabanlarında veya bulutta 'a entegre edebilirsiniz. Ayrıca dosyalar ile veritabanlarını uygulamanıza özel tutabilirler.
İzinleri uygulama
    Temel veriler temel alınan veriler olsa bile varsayılan olarak tüm uygulamalar sağlayıcınızdan okuma veya sağlayıcınıza yazma imkanı
    Gizli. Çünkü sağlayıcınız varsayılan olarak ayarlı izinlere sahip değildir. Bunu değiştirmek için
    özellikleri veya alt öğeyi kullanarak manifest dosyanızda sağlayıcınız için izinleri ayarlayın
    
    <provider> öğesinin öğeleri. Belirlenen sağlayıcıdan bir ya da daha fazla sağlayıcı için
    belirli kayıtlara veya üçüne birden uygulayabilirsiniz.
    Sağlayıcınızın izinlerini bir veya daha fazla
    Manifest dosyanızda 
    <permission> öğeleri. To
    sağlayıcınıza özel bir izin değilse,
    
    android:name özelliği için de kullanılmaktadır. Örneğin, okuma iznini adlandırın.
    com.example.app.provider.permission.READ_PROVIDER
Aşağıdaki listede önce sağlayıcı için geçerli olan ve daha ayrıntılı hale gelen izinler Daha ayrıntılı izinler, daha geniş kapsamlı izinlere göre önceliklidir.
- Okuma-yazma sağlayıcı düzeyinde tek izin
- .
        Sağlayıcının tamamına hem okuma hem de yazma erişimini kontrol eden bir izin, belirtilmiş
        şunun android:permissionözelliğiyle<provider>öğesi.
- Okuma ve yazma sağlayıcı düzeyinde ayrı izinler
- .
        Sağlayıcının tamamı için okuma ve yazma izni. Bunları siz belirtirsiniz
        android:readPermissionveandroid:writePermissionözellikleri<provider>öğesi. Bunlar,android:permission
- Yol düzeyinde izin
- .
        Sağlayıcınızdaki içerik URI'si için okuma, yazma veya okuma/yazma izni. Siz
        
        <path-permission>alt öğesi<provider>öğesi. Belirttiğiniz her içerik URI'si için bir okuma/yazma izni, okuma izni, yazma izni veya üçü de vardır. Okuma ve yazma izinleri, okuma/yazma iznine göre önceliklidir. Ayrıca, yol düzeyinde bu izin, sağlayıcı düzeyindeki izinlere göre önceliklidir.
- Geçici izin
- .
        Bir uygulamaya geçici erişim izni veren bir izin düzeyi,
        , normalde gerekli olan izinlere sahip değil. Geçici
        erişim özelliği, bir uygulamanın istekte bulunması gereken izin sayısını azaltır
        bildireceğiz. Geçici izinleri açtığınızda, yalnızca
        sağlayıcınızın kalıcı izinleri, tüm cihazlarınıza sürekli olarak erişen izinlerdir.
        verileriniz.
        Örneğin, bir e-posta sağlayıcısı ve uygulaması uyguluyorsanız ve dışarıdaki bir resim görüntüleyici uygulamasının sağlar. Resim görüntüleyiciye izin gerektirmeden gerekli erişimi vermek için fotoğrafların içerik URI'lerine yönelik geçici izinler ayarlayabilirsiniz. E-posta uygulamanızı Kullanıcı bir fotoğraf görüntülemek istediğinde uygulamanın bu fotoğrafı içeren fotoğraf içerik URI'si ve resim görüntüleyici için izin işaretleri içerir. Resim görüntüleyici fotoğraf getirmesi için e-posta sağlayıcınızdan sorgu göndererek sağlayıcınızın normal okuma iznine sahip olması gerekir. Geçici izinleri etkinleştirmek için android:grantUriPermissions<provider>öğe veya bir ya da daha fazla öğe ekleyin<grant-uri-permission><provider>öğesi. Telefonla aramaContext.revokeUriPermission()sağlar.Bu özelliğin değeri, sağlayıcınızın ne kadarının erişilebilir olduğunu belirler. Özellik "true"değerine ayarlanırsa sistem, için gerekli diğer tüm izinleri geçersiz kılarak, sağlayıcınıza veya yol düzeyindeki izinlerinize göre belirlemeniz gerekir.Bu işaret "false"değerine ayarlanırsa<grant-uri-permission><provider>öğesi. Her alt öğe, içerik URI'sini veya Geçici erişim izni verilen URI'lar.Bir uygulamaya geçici erişim yetkisi vermek için amacın şunu içermesi gerekir: FLAG_GRANT_READ_URI_PERMISSIONbayrağı,FLAG_GRANT_WRITE_URI_PERMISSIONişareti veya her ikisi. BusetFlags()yöntemiyle ayarlanır.android:grantUriPermissionsözelliği yoksa mevcut olduğu varsayılır."false".
<provider> öğe
    Activity ve Service bileşenlerinde olduğu gibi,
    ContentProvider alt sınıfı
    aşağıdaki komut dosyası kullanılarak uygulamasının manifest dosyasında tanımlanır:
    
    <provider> öğesi. Android sistemi,
    öğe:
- 
        Yetki
        (android:authorities)
- . Sistemdeki tüm sağlayıcıyı tanımlayan sembolik adlar. Bu özelliği aşağıdaki sayfada daha ayrıntılı olarak açıklanmıştır: İçerik URI'leri tasarlama bölümü.
- 
        Sağlayıcı sınıf adı
        (android:name)
- .
        ContentProvideruygulayan sınıf. Bu sınıf daha ayrıntılı olarak ContentProvider sınıfını uygulama bölümünü inceleyin.
- İzinler
- .
        Diğer uygulamaların erişebilmek için sahip olması gereken izinleri belirten özellikler
        sağlayıcı verileri:
        - 
                android:grantUriPermissions: Geçici izin işareti
- 
                android:permission: sağlayıcı genelinde tek okuma/yazma izni
- 
                android:readPermission: Sağlayıcı genelinde okuma izni
- 
                android:writePermission: Sağlayıcı genelinde yazma izni
 İzinler ve bunlarla ilgili özellikler ve İçerik sağlayıcı izinlerini uygulama bölümünü inceleyin. 
- 
                
- Başlangıç ve kontrol özellikleri
- .
        Bu özellikler, Android sisteminin sağlayıcıyı nasıl ve ne zaman başlatacağını,
        diğer çalışma zamanı ayarları için de geçerlidir:
        - 
                android:enabled: Sistemin sağlayıcıyı başlatmasına izin veren işaretleyici
- 
                android:exported: diğer uygulamaların bu sağlayıcıyı kullanmasına izin verdiğini işaretle
- 
                android:initOrder: Bu sağlayıcının başlatılma sırası, aynı süreçteki diğer sağlayıcılara kıyasla
- 
                android:multiProcess: Sistemin sağlayıcıyı başlatmasına izin veren işaretleyici arayan müşteriyle aynı süreçte
- 
                android:process: Sağlayıcının çalıştırıldığı işlemin adıdır.
- 
                android:syncable: Sağlayıcıya ait verilerin toplanacağını belirten işaret bir sunucudaki verilerle senkronize edildi
 Bu özellikler, <provider>öğesi.
- 
                
- Bilgilendirici özellikler
- .
        Sağlayıcı için isteğe bağlı bir simge ve etiket:
        - 
                android:icon: Sağlayıcının simgesini içeren çekilebilir bir kaynaktır. Simge, Ayarlar > Uygulamalar > Tümü.
- 
                android:label: sağlayıcıyı, sağlayıcıyı ve firmayı tanımlayan bilgi etiketi verileri veya her ikisi de olabilir. Bu etiket, uygulama listesindeki uygulamalar listesinde görünür. Ayarlar > Uygulamalar > Tümü.
 Bu özellikler, <provider>öğesi.
- 
                
Not: Android 11 veya sonraki bir sürümü hedefliyorsanız şu makaleye göz atın: paket görünürlüğü belgeleri kullanın.
Amaçlar ve veri erişimi
    Uygulamalar, Intent ile dolaylı olarak içerik sağlayıcıya erişebilir.
    Uygulama, ContentResolver veya
    ContentProvider. Bunun yerine bir etkinlik başlatan,
    Bu genellikle sağlayıcının kendi uygulamasının bir parçasıdır. Varış noktası etkinliğinde nelerden bahsedilir?
    kullanıcı arayüzünde verilerini alıp görüntüleyebilirsiniz.
Amaçtaki işleme bağlı olarak, hedef etkinliği, kullanıcıdan sağlayıcının verilerinde değişiklik yapmasını da isteyebilir. Niyet, "ekstralar"ı da içerebilir hedef etkinliğin gösterdiği veriler görüntülenir. Böylece kullanıcı, verileri değiştirmek için kullanmadan önce bu verileri değiştirme kontrol edebilirsiniz.
Veri bütünlüğüne yardımcı olmak için intent erişimini kullanabilirsiniz. Sağlayıcınız aşağıdakilere göre değişir: titizlikle tanımlanmış iş mantığına göre veri eklenmesini, güncellenmesini ve silinmesini sağlamakla ilgilidir. Eğer Bu durumda, diğer uygulamaların verilerinizi doğrudan değiştirmesine izin vermek, geçersiz veri.
Geliştiricilerin amaç erişimini kullanmasını istiyorsanız bunu ayrıntılı bir şekilde belgelediğinizden emin olun. Uygulamanızın kullanıcı arayüzünü kullanarak intent erişiminin neden kodu kullanarak verileri değiştirebilir.
Sağlayıcınızın verilerini değiştirmek isteyen gelen bir niyetin ele alınması, eleştirel düşünme yetinizi kullanmanız gerekiyor. Amaçları kullanma hakkında daha fazla bilgiyi şuradan edinebilirsiniz: Niyetler ve Amaç Filtreleri.
Daha fazla ilgili bilgi için Takvim sağlayıcısına genel bakış.
