İç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ıdır. 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,CursorAdapter
veyaCursorLoader
sı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.
-
ContentProvider
sı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:
AbstractThreadedSyncAdapter
sağ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.net
veandroid.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._ID
kullanmak 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
ContentResolver
dosya 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
:table1
adlı 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
:table3
adlı 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/*
- .
dataset1
tabloları için bir içerik URI'siyle eşleşir vedataset2
ile eşleşmez ancaktable1
veyatable3
. -
content://com.example.app.provider/table3/#
- .
Bir içerik URI'si ile eşleşir
table3
değerindeki tek satırlar için; örneğin, tarafından tanımlanan satır içincontent://com.example.app.provider/table3/6
6
.
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
Cursor
nesnesi 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:
ContentResolver
nesnesi 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
SQLiteDatabase
veritabanı 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:readPermission
veandroid: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_PERMISSION
bayrağı,FLAG_GRANT_WRITE_URI_PERMISSION
iş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
) - .
ContentProvider
uygulayan 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ış.