Contacts Provider

Kişi Sağlayıcı, cihazın kişilerle ilgili merkezi veri deposunu yöneten güçlü ve esnek bir Android bileşenidir. Kişiler Sağlayıcısı, cihazın kişiler uygulamasında gördüğünüz veri kaynağıdır. Ayrıca, kendi uygulamanızdan da bu sağlayıcının verilerine erişebilir ve cihaz ile çevrimiçi hizmetler arasında veri aktarabilirsiniz. Sağlayıcı, çok çeşitli veri kaynaklarını barındırır ve her kullanıcı için mümkün olduğunca fazla veri yönetmeye çalışır. Bu nedenle, kuruluşu karmaşıktır. Bu nedenle, sağlayıcının API'si hem veri alımını hem de değiştirilmesini kolaylaştıran kapsamlı bir sözleşme sınıfı ve arayüz grubu içerir.

Bu kılavuzda aşağıdakiler açıklanmaktadır:

  • Temel sağlayıcı yapısı.
  • Sağlayıcıdan veri alma.
  • Sağlayıcıdaki verileri değiştirme
  • Sunucunuzdaki verileri Kişiler Sağlayıcı ile senkronize etmek için senkronizasyon bağdaştırıcısı yazma

Bu kılavuzda, Android içerik sağlayıcılarla ilgili temel bilgileri bildiğiniz varsayılmaktadır. Android içerik sağlayıcıları hakkında daha fazla bilgi edinmek için İçerik Sağlayıcı ile ilgili temel bilgiler kılavuzunu okuyun.

Kişi Sağlayıcı kuruluşu

Kişiler Sağlayıcı, Android içerik sağlayıcı bileşenidir. Bir kişiyle ilgili üç tür veri tutar. Bu verilerin her biri, sağlayıcı tarafından sunulan bir tabloya karşılık gelir (Şekil 1'de gösterilmiştir):

Şekil 1. Kişi Sağlayıcı tablosu yapısı.

Bu üç tabloya genellikle sözleşme sınıflarının adlarıyla değinilir. Sınıflar, tablolar tarafından kullanılan içerik URI'leri, sütun adları ve sütun değerleri için sabit değerler tanımlar:

ContactsContract.Contacts tablo
Ham kişi satırlarının toplamalarına göre farklı kişileri temsil eden satırlar.
ContactsContract.RawContacts tablo
Bir kullanıcı hesabına ve türüne özel kullanıcı verilerinin özetini içeren satırlar.
ContactsContract.Data tablo
Ham kişinin ayrıntılarını (ör. e-posta adresleri veya telefon numaraları) içeren satırlar.

ContactsContract bölümünde sözleşme sınıfları tarafından temsil edilen diğer tablolar, Kişi Sağlayıcı'nın işlemlerini yönetmek veya cihazın kişiler ya da telefon uygulamalarındaki belirli işlevleri desteklemek için kullandığı yardımcı tablolardır.

Ham kişiler

Ham kişi, bir kişinin tek bir hesap türünden ve hesap adından gelen verilerini temsil eder. Kişi Sağlayıcı, bir kişi için veri kaynağı olarak birden fazla online hizmete izin verdiğinden, Kişi Sağlayıcı aynı kişi için birden fazla ham kişiye izin verir. Birden fazla ham kişi, kullanıcıların aynı hesap türündeki birden fazla hesaptan gelen kullanıcı verilerini birleştirmesine de olanak tanır.

Ham bir kişiyle ilgili verilerin çoğu ContactsContract.RawContacts tablosunda depolanmaz. Bunun yerine, ContactsContract.Data tablosundaki bir veya daha fazla satırda saklanır. Her veri satırında, üst ContactsContract.RawContacts satırının RawContacts._ID değerini içeren bir Data.RAW_CONTACT_ID sütunu bulunur.

Önemli ham kişi sütunları

ContactsContract.RawContacts tablosundaki önemli sütunlar tablo 1'de listelenmiştir. Lütfen tablodan sonra aşağıdaki notları okuyun:

Tablo 1. Önemli ham kişi sütunları.

Sütun adı Kullanım Notlar
ACCOUNT_NAME Bu ham iletişimin kaynağı olan hesap türünün adı. Örneğin, bir Google Hesabı'nın hesap adı, cihaz sahibinin Gmail adreslerinden biri olabilir. Daha fazla bilgi için ACCOUNT_TYPE ile ilgili sonraki girişe bakın. Bu adın biçimi, hesap türüne özeldir. Bu değer mutlaka bir e-posta adresi
ACCOUNT_TYPE Bu ham kişinin kaynağı olan hesap türü. Örneğin, bir Google Hesabı'nın hesap türü com.google'tür. Hesap türünüzü her zaman sahip olduğunuz veya kontrol ettiğiniz bir alanın alan tanımlayıcısı ile doğrulayın. Bu sayede hesap türünüzün benzersiz olmasını sağlayabilirsiniz. Kişi verileri sunan hesap türlerinde genellikle Kişi Sağlayıcı ile senkronize eden ilişkili bir senkronizasyon adaptörü bulunur.
DELETED Ham bir kişi için "silindi" işareti. Bu işaret, senkronizasyon bağdaştırıcılar satırı sunucularından silene ve ardından nihayet depodan silene kadar Kişi Sağlayıcı'nın satırı dahili olarak muhafaza etmesine olanak tanır.

Notlar

ContactsContract.RawContacts tablosuyla ilgili önemli notlar aşağıda verilmiştir:

  • Ham kişinin adı, ContactsContract.RawContacts uygulamasındaki satırında depolanmaz. Bunun yerine, ContactsContract.Data tablosunda bir ContactsContract.CommonDataKinds.StructuredName satırında saklanır. Ham bir kişi, ContactsContract.Data tablosunda bu türden yalnızca bir satıra sahiptir.
  • Dikkat: Kendi hesap verilerinizi ham iletişim satırında kullanmak için öncelikle AccountManager ile kaydedilmiş olması gerekir. Bunu yapmak için kullanıcılardan hesap türünü ve hesap adlarını hesap listesine eklemelerini isteyin. Bunu yapmazsanız Kişi Sağlayıcı, ham kişi satırınızı otomatik olarak siler.

    Örneğin, uygulamanızın com.example.dataservice alan adıyla web tabanlı hizmetiniz için kişi verilerini saklamasını istiyorsanız ve kullanıcının hizmetinize ait hesabı becky.sharp@dataservice.example.com ise uygulamanızın ham kişi satırları ekleyebilmesi için önce kullanıcının hesap "türü" (com.example.dataservice) ve hesap "adı" (becky.smart@dataservice.example.com) bilgilerini eklemesi gerekir. Bu koşulu dokümanda kullanıcıya açıklayabilir veya kullanıcıdan türünü ve adını ya da ikisini birden eklemesini isteyebilirsiniz. Hesap türleri ve hesap adları, bir sonraki bölümde daha ayrıntılı olarak açıklanmıştır.

Ham kişi verilerinin kaynakları

Ham kişilerin nasıl çalıştığını anlamak için cihazında aşağıdaki üç kullanıcı hesabı tanımlanmış olan "Emily Dickinson" kullanıcısını düşünün:

  • emily.dickinson@gmail.com
  • emilyd@gmail.com
  • "belle_of_amherst" Twitter hesabı

Bu kullanıcı, Hesaplar ayarlarında bu hesapların üçünde de Kişileri Senkronize Et'i etkinleştirmiştir.

Emily Dickinson'ın bir tarayıcı penceresi açtığını, Gmail'e emily.dickinson@gmail.com olarak giriş yaptığını, Kişiler'i açıp "Thomas Higginson"u eklediğini varsayalım. Daha sonra emilyd@gmail.com olarak Gmail'e giriş yapar ve "Thomas Higginson"a bir e-posta gönderir. Bu e-posta, Thomas Higginson'u otomatik olarak kişi olarak ekler. Ayrıca Twitter'da "colonel_tom"u (Thomas Higginson'un Twitter kimliği) takip ediyor.

Kişi Sağlayıcı, bu çalışma sonucunda üç ham kişi oluşturur:

  1. emily.dickinson@gmail.com ile ilişkili "Thomas Higginson" adlı ham kişi. Kullanıcı hesabı türü Google'dır.
  2. emilyd@gmail.com ile ilişkili "Thomas Higginson" için ikinci ham kişi. Kullanıcı hesabı türü de Google'dır. Kişi farklı bir kullanıcı hesabı için eklendiğinden, ad önceki adla aynı olsa bile ikinci bir ham kişi var.
  3. "Thomas Higginson" için "belle_of_amherst" ile ilişkili üçüncü ham iletişim. Kullanıcı hesabı türü Twitter'dır.

Veri

Daha önce belirtildiği gibi, ham kişinin verileri ham kişinin _ID değerine bağlı olan bir ContactsContract.Data satırında depolanır. Bu sayede, tek bir ham kişide e-posta adresleri veya telefon numaraları gibi aynı türden birden fazla veri örneği bulunabilir. Örneğin, emilyd@gmail.com için "Thomas Higginson" (emilyd@gmail.com Google Hesabı ile ilişkili Thomas Higginson için ham kişi satırı) thigg@gmail.com ev e-posta adresine ve thomas.higginson@gmail.com iş e-posta adresine sahipse Kişi Sağlayıcı, iki e-posta adresi satırını depolar ve her ikisini de ham kişiye bağlar.

Bu tek tabloda farklı veri türlerinin depolandığını unutmayın. Görünen ad, telefon numarası, e-posta, posta adresi, fotoğraf ve web sitesi ayrıntısı satırlarının tümü ContactsContract.Data tablosunda bulunur. Bu durumu yönetmenize yardımcı olmak için ContactsContract.Data tablosunda açıklayıcı ada sahip bazı sütunlar ve genel ada sahip diğer sütunlar bulunur. Açıklayıcı ad sütununun içeriği, satırdaki veri türüne bakılmaksızın aynı anlama gelir. Genel ad sütununun içeriği ise veri türüne göre farklı anlamlara sahiptir.

Açıklayıcı sütun adları

Açıklayıcı sütun adlarına örnek olarak şunlar verilebilir:

RAW_CONTACT_ID
Bu verilere ait ham kişinin _ID sütununun değeri.
MIMETYPE
Bu satırda depolanan verilerin türü (özel MIME türü olarak ifade edilir). Kişi Sağlayıcı, ContactsContract.CommonDataKinds alt sınıflarında tanımlanan MIME türlerini kullanır. Bu MIME türleri açık kaynaktır ve Kişiler Sağlayıcı ile çalışan tüm uygulamalar veya senkronizasyon bağdaştırıcılar tarafından kullanılabilir.
IS_PRIMARY
Bu tür bir veri satırı ham bir kişi için birden fazla kez oluşabiliyorsa IS_PRIMARY sütunu, türün birincil verilerini içeren veri satırını işaretler. Örneğin, kullanıcı bir kişinin telefon numarasına uzun basar ve Varsayılan olarak ayarla'yı seçerse bu numarayı içeren ContactsContract.Data satırının IS_PRIMARY sütunu sıfır dışında bir değere ayarlanır.

Genel sütun adları

Genel olarak kullanılabilen DATA1-DATA15 adında 15 genel sütun ve yalnızca senkronizasyon bağdaştırıcıları tarafından kullanılması gereken SYNC1 ila SYNC4 arasında dört genel sütun bulunur. Genel sütun adı sabitleri, satırın içerdiği veri türüne bakılmaksızın her zaman çalışır.

DATA1 sütunu dizine eklendi. Kişi Sağlayıcı, bir sorgunun en sık hedefi olacağını düşündüğü veriler için bu sütunu her zaman kullanır. Örneğin, bir e-posta satırında bu sütun gerçek e-posta adresini içerir.

DATA15 sütunu, fotoğraf küçük resimleri gibi büyük ikili nesne (BLOB) verilerini depolamak için ayrılmıştır.

Türe özgü sütun adları

Kişi Sağlayıcı, belirli bir satır türüne ait sütunlarla çalışmayı kolaylaştırmak için ContactsContract.CommonDataKinds alt sınıflarında tanımlanan türe özgü sütun adı sabitleri de sağlar. Sabitler, aynı sütun adına farklı bir sabit ad verir. Bu, belirli bir türdeki bir satırdaki verilere erişmenize yardımcı olur.

Örneğin, ContactsContract.CommonDataKinds.Email sınıfı, MIME türü Email.CONTENT_ITEM_TYPE olan bir ContactsContract.Data satırı için türe özgü sütun adı sabitleri tanımlar. Sınıf, e-posta adresi sütunu için ADDRESS sabit değerini içerir. ADDRESS değerinin gerçek değeri "data1"dır ve bu değer, sütunun genel adıyla aynıdır.

Dikkat: Sağlayıcının önceden tanımlanmış MIME türlerinden birine sahip bir satırı kullanarak ContactsContract.Data tablosuna kendi özel verilerinizi eklemeyin. Bunu yaparsanız verileri kaybedebilir veya sağlayıcının hatalı çalışmasına neden olabilirsiniz. Örneğin, DATA1 sütununda e-posta adresi yerine kullanıcı adı içeren Email.CONTENT_ITEM_TYPE MIME türüne sahip bir satır eklememelisiniz. Satır için kendi özel MIME türünüzü kullanıyorsanız türe özgü kendi sütun adlarınızı tanımlayabilir ve sütunları istediğiniz gibi kullanabilirsiniz.

Şekil 2'de açıklayıcı sütunların ve veri sütunlarının bir ContactsContract.Data satırında nasıl göründüğü ve türe özgü sütun adlarının genel sütun adlarını nasıl "örttüğü" gösterilmektedir.

Türe özel sütun adları, genel sütun adlarıyla nasıl eşlenir?

Şekil 2. Türe özel sütun adları ve genel sütun adları.

Türe özel sütun adı sınıfları

Tablo 2'de, türe özel en yaygın sütun adı sınıfları listelenmiştir:

Tablo 2. Türe özgü sütun adı sınıfları

Sınıf eşleme Veri türü Notlar
ContactsContract.CommonDataKinds.StructuredName Bu veri satırıyla ilişkili ham kişinin ad verileri. Ham kişilerde bu satırlardan yalnızca biri bulunur.
ContactsContract.CommonDataKinds.Photo Bu veri satırıyla ilişkili ham kişinin ana fotoğrafı. Ham kişilerde bu satırlardan yalnızca biri bulunur.
ContactsContract.CommonDataKinds.Email Bu veri satırıyla ilişkilendirilmiş ham kişinin e-posta adresi. Ham bir kişinin birden fazla e-posta adresi olabilir.
ContactsContract.CommonDataKinds.StructuredPostal Bu veri satırıyla ilişkilendirilmiş ham kişinin posta adresi. Ham bir kişinin birden fazla posta adresi olabilir.
ContactsContract.CommonDataKinds.GroupMembership Ham kişiyi Kişiler Sağlayıcı'daki gruplardan birine bağlayan bir tanımlayıcı. Gruplar, hesap türünün ve hesap adının isteğe bağlı bir özelliğidir. Bu gruplar Kişi grupları bölümünde daha ayrıntılı olarak açıklanmıştır.

Kişiler

Kişi Sağlayıcı, tüm hesap türleri ve hesap adlarındaki ham kişi satırlarını birleştirerek kişi oluşturur. Bu, kullanıcının bir kişi için topladığı tüm verileri görüntülemeyi ve değiştirmeyi kolaylaştırır. Kişi Sağlayıcı, yeni kişi satırlarının oluşturulmasını ve ham kişilerin mevcut bir kişi satırıyla birleştirilmesini yönetir. Uygulamaların veya senkronizasyon bağdaştırıcıların kişilerin eklenmesine izin verilmez ve kişi satırındaki bazı sütunlar salt okunurdur.

Not: Kişi Sağlayıcı'ya insert() ile bir kişi eklemeye çalışırsanız UnsupportedOperationException istisnasıyla karşılaşırsınız. "Salt okunur" olarak listelenen bir sütunu güncellemeye çalışırsanız güncelleme yoksayılır.

Kişi Sağlayıcı, mevcut herhangi bir kişiyle eşleşmeyen, yeni bir ham kişi eklenmesine yanıt olarak yeni bir kişi oluşturur. Sağlayıcı, mevcut bir ham kişinin verileri artık daha önce bağlı olduğu kişiyle eşleşmeyecek şekilde değişirse de bunu yapar. Bir uygulama veya senkronizasyon bağdaştırıcısı, mevcut bir kişiyle eşleşen yeni bir ham kişi oluşturursa yeni ham kişi mevcut kişiyle birleştirilir.

Kişi Sağlayıcı, kişi satırını Contacts tablosundaki _ID sütunuyla kullanarak ham kişi satırlarına bağlar. Ham kişi tablosunun CONTACT_ID sütunu (ContactsContract.RawContacts), her ham kişi satırıyla ilişkili kişi satırı için _ID değerleri içerir.

ContactsContract.Contacts tablosunda, iletişim satırının "kalıcı" bağlantısı olan LOOKUP_KEY sütunu da yer alıyor. Kişi Sağlayıcı, kişileri otomatik olarak yönettiğinden bir toplama veya senkronizasyon işlemine yanıt olarak bir kişi satırının _ID değerini değiştirebilir. Böyle bir durumda bile, kişinin LOOKUP_KEY ile birlikte kullanılan içerik URI'si CONTENT_LOOKUP_URI, kişi satırını işaretlemeye devam eder. Bu nedenle, "favori" kişilere ve benzeri bağlantıları korumak için LOOKUP_KEY'yi kullanabilirsiniz. Bu sütunun, _ID sütununun biçimiyle alakalı olmayan kendi biçimi vardır.

Şekil 3'te, üç ana tablonun birbiriyle nasıl ilişkili olduğu gösterilmektedir.

Kişi sağlayıcı ana tabloları

Şekil 3. Kişiler, Ham Kişiler ve Ayrıntılar tablo ilişkileri.

Dikkat: Uygulamanızı Google Play Store'da yayınladıysanız veya uygulamanız Android 10 (API düzeyi 29) veya sonraki sürümleri çalıştıran bir cihazdaysa sınırlı sayıda kişi verileri alanının ve yönteminin kullanımdan kaldırıldığını unutmayın.

Sistem, belirtilen koşullar altında aşağıdaki veri alanlarına yazılan tüm değerleri düzenli olarak temizler:

Yukarıdaki veri alanlarını ayarlamak için kullanılan API'ler de kullanımdan kaldırılmıştır:

Ayrıca, aşağıdaki alanlar artık sık iletişim kurulan kişileri döndürmemektedir. Bu alanlardan bazılarının, kişilerin sıralamalarını yalnızca kişiler belirli bir veri türünün parçası olduklarında etkilediğini unutmayın.

Uygulamalarınız bu alanlara veya API'lere erişiyorsa ya da bunları güncelliyorsa alternatif yöntemler kullanın. Örneğin, özel içerik sağlayıcıları veya uygulamanızda ya da arka uç sistemlerinizde depolanan diğer verileri kullanarak belirli kullanım alanlarını karşılayabilirsiniz.

Uygulamanızın işlevselliğinin bu değişiklikten etkilenmediğini doğrulamak için bu veri alanlarını manuel olarak temizleyebilirsiniz. Bunu yapmak için Android 4.1 (API düzeyi 16) veya sonraki sürümleri çalıştıran bir cihazda aşağıdaki ADB komutunu çalıştırın:

adb shell content delete \
--uri content://com.android.contacts/contacts/delete_usage

Senkronizasyon bağdaştırıcılarından alınan veriler

Kullanıcılar kişi verilerini doğrudan cihaza girer ancak veriler, cihaz ile hizmetler arasındaki veri aktarımını otomatikleştiren senkronizasyon bağdaştırıcılar aracılığıyla web hizmetlerinden Kişiler Sağlayıcı'ya da aktarılır. Senkronizasyon bağdaştırıcılar, sistemin kontrolü altında arka planda çalışır ve verileri yönetmek için ContentResolver yöntemlerini çağırır.

Android'de, senkronizasyon bağdaştırıcının çalıştığı web hizmeti bir hesap türüyle tanımlanır. Her senkronizasyon bağdaştırıcısı tek bir hesap türüyle çalışır ancak bu tür için birden fazla hesap adını destekleyebilir. Hesap türleri ve hesap adları, Ham kişi verilerinin kaynakları bölümünde kısaca açıklanmaktadır. Aşağıdaki tanımlar daha fazla ayrıntı sunmakta ve hesap türü ile adının senkronizasyon bağdaştırıcıları ve hizmetleriyle olan ilişkisini açıklamaktadır.

Hesap türü
Kullanıcının veri depoladığı bir hizmeti tanımlar. Çoğu zaman kullanıcının hizmetle kimliğini doğrulaması gerekir. Örneğin, Google Kişiler, google.com koduyla tanımlanan bir hesap türüdür. Bu değer, AccountManager tarafından kullanılan hesap türüne karşılık gelir.
Hesap adı
Bir hesap türü için belirli bir hesabı veya girişi tanımlar. Google Kişiler hesapları, hesap adı olarak e-posta adresi kullanan Google Hesapları ile aynıdır. Diğer hizmetler tek kelimelik bir kullanıcı adı veya sayısal kimlik kullanabilir.

Hesap türlerinin benzersiz olması gerekmez. Kullanıcılar birden fazla Google Kişiler hesabı yapılandırabilir ve verilerini Kişiler Sağlayıcı'ya indirebilir. Bu durum, kullanıcının kişisel hesap adı için bir kişisel kişi grubu ve iş için başka bir kişi grubu varsa ortaya çıkabilir. Hesap adları genellikle benzersizdir. Birlikte, Kişi Sağlayıcı ile harici bir hizmet arasındaki belirli bir veri akışını tanımlarlar.

Hizmetinizin verilerini Kişiler Sağlayıcı'ya aktarmak istiyorsanız kendi senkronizasyon bağdaştırıcınızı yazmanız gerekir. Bu konu Kişi Sağlayıcı senkronizasyon bağdaştırıcılar bölümünde daha ayrıntılı olarak açıklanmıştır.

Şekil 4'te Kişi Sağlayıcı'nın kişilerle ilgili veri akışına nasıl uyum sağladığı gösterilmektedir. "Senkronizasyon bağdaştırıcılar" etiketli kutuda her bağdaştırıcının hesabı türüne göre etiketi bulunur.

Kullanıcılarla ilgili veri akışı

Şekil 4. Contacts Provider veri akışı.

Gerekli izinler

Kişiler sağlayıcısına erişmek isteyen uygulamaların aşağıdaki izinleri istemesi gerekir:

Bir veya daha fazla tabloya okuma erişimi
READ_CONTACTS, AndroidManifest.xml içinde <uses-permission android:name="android.permission.READ_CONTACTS"> olarak <uses-permission> öğesi ile belirtildi.
Bir veya daha fazla tabloya yazma erişimi
WRITE_CONTACTS, AndroidManifest.xml içinde <uses-permission> öğesiyle <uses-permission android:name="android.permission.WRITE_CONTACTS"> olarak belirtilir.

Bu izinler, kullanıcı profili verilerini kapsamaz. Kullanıcı profili ve gerekli izinleri, Kullanıcı profili bölümünde ele alınmıştır.

Kullanıcının kişi verilerinin kişisel ve hassas olduğunu unutmayın. Kullanıcılar gizlilik konusunda endişeli olduğundan, uygulamalardan kendileri veya kişileri hakkında veri toplamamalarını ister. Kişilerin verilerine erişmek için neden izne ihtiyacınız olduğu açık değilse, uygulamanız düşük puan verebilir veya uygulamayı yüklemeyi reddedebilir.

Kullanıcı profili

ContactsContract.Contacts tablosunda, cihazın kullanıcısına ait profil verilerini içeren tek bir satır bulunur. Bu veriler, kullanıcının kişilerinden birini değil, cihazın user özelliğini tanımlar. Profil kişileri satırı, profil kullanan her sistem için ham bir kişiler satırına bağlanır. Her profil ham kişi satırında birden fazla veri satırı olabilir. Kullanıcı profiline erişmek için ContactsContract.Profile sınıfındaki sabitler kullanılabilir.

Kullanıcı profiline erişim için özel izinler gerekir. Okuma ve yazma için gereken READ_CONTACTS ve WRITE_CONTACTS izinlerine ek olarak, kullanıcı profiline erişim için sırasıyla okuma ve yazma erişimi için android.Manifest.permission#READ_PROFILE ve android.Manifest.permission#WRITE_PROFILE izinleri gerekir.

Kullanıcı profilini hassas olarak değerlendirmeniz gerektiğini unutmayın. android.Manifest.permission#READ_PROFILE izni, cihaz kullanıcısının kimliğini tanımlayabilecek verilerine erişmenize olanak tanır. Uygulamanızın açıklamasında kullanıcıya neden kullanıcı profili erişim izinlerine ihtiyaç duyduğunuzu açıklayın.

Kullanıcının profilini içeren kişi satırını almak için ContentResolver.query() işlevini çağırın. İçerik URI'sini CONTENT_URI olarak ayarlayın ve herhangi bir seçim ölçütü sağlamaz. Bu içerik URI'sini, profil için ham kişileri veya verileri almak için temel URI olarak da kullanabilirsiniz. Örneğin, bu snippet profille ilgili verileri alır:

Kotlin

// Sets the columns to retrieve for the user profile
projection = arrayOf(
        ContactsContract.Profile._ID,
        ContactsContract.Profile.DISPLAY_NAME_PRIMARY,
        ContactsContract.Profile.LOOKUP_KEY,
        ContactsContract.Profile.PHOTO_THUMBNAIL_URI
)

// Retrieves the profile from the Contacts Provider
profileCursor = contentResolver.query(
        ContactsContract.Profile.CONTENT_URI,
        projection,
        null,
        null,
        null
)

Java

// Sets the columns to retrieve for the user profile
projection = new String[]
    {
        Profile._ID,
        Profile.DISPLAY_NAME_PRIMARY,
        Profile.LOOKUP_KEY,
        Profile.PHOTO_THUMBNAIL_URI
    };

// Retrieves the profile from the Contacts Provider
profileCursor =
        getContentResolver().query(
                Profile.CONTENT_URI,
                projection ,
                null,
                null,
                null);

Not: Birden fazla kişi satırı alıyorsanız ve bunlardan birinin kullanıcı profili olup olmadığını belirlemek istiyorsanız satırın IS_USER_PROFILE sütununu test edin. Kişi, kullanıcı profiliyse bu sütun "1" olarak ayarlanır.

Kişi Sağlayıcı meta verileri

Kişi Sağlayıcı, depoda bulunan kişi verilerinin durumunu izleyen verileri yönetir. Depoyla ilgili bu meta veriler, Ham Kişiler, Veriler ve Kişiler tablosu satırları, ContactsContract.Settings tablosu ve ContactsContract.SyncState tablosu dahil olmak üzere çeşitli yerlerde depolanır. Aşağıdaki tabloda, bu meta veri parçalarının her birinin etkisi gösterilmektedir:

Tablo 3. Kişiler sağlayıcısındaki meta veriler

Tablo Sütun Değerler Anlamı
ContactsContract.RawContacts DIRTY "0": Son senkronizasyondan bu yana değişmedi. Cihazda değiştirilen ve sunucuya tekrar senkronize edilmesi gereken ham kişileri işaretler. Android uygulamaları bir satırı güncellediğinde değer, Kişiler Sağlayıcı tarafından otomatik olarak ayarlanır.

Ham kişi veya veri tablolarını değiştiren senkronizasyon bağdaştırıcılar, kullandıkları içerik URI'sine her zaman CALLER_IS_SYNCADAPTER dizesini eklemelidir. Bu, sağlayıcının satırları kirli olarak işaretlemesini önler. Aksi takdirde, senkronizasyon adaptörü değişiklikleri yerel değişiklikler olarak görünür ve değişikliğin kaynağı sunucu olsa bile sunucuya gönderilir.

"1": Son senkronizasyondan beri değiştirildi, sunucuya geri senkronize edilmesi gerekiyor.
ContactsContract.RawContacts VERSION Bu satırın sürüm numarası. Kişi Sağlayıcı, satır veya ilgili verileri her değiştiğinde bu değeri otomatik olarak artırır.
ContactsContract.Data DATA_VERSION Bu satırın sürüm numarası. Kişi Sağlayıcı, veri satırı değiştiğinde bu değeri otomatik olarak artırır.
ContactsContract.RawContacts SOURCE_ID Bu ham kişiyi, oluşturulduğu hesapta benzersiz şekilde tanımlayan bir dize değeri. Bir senkronizasyon bağdaştırıcısı yeni bir ham kişi oluşturduğunda bu sütun, sunucunun ham kişi için benzersiz kimliğine ayarlanmalıdır. Bir Android uygulaması yeni bir ham kişi oluşturduğunda bu sütunu boş bırakmalıdır. Bu, senkronizasyon bağdaştırıcısı için sunucuda yeni bir ham kişi oluşturması ve SOURCE_ID için bir değer alması gerektiğine dair bir sinyal gönderir.

Özellikle kaynak kimliği her hesap türü için benzersiz olmalı ve senkronizasyonlarda sabit olmalıdır:

  • Benzersiz: Bir hesaptaki her ham kişinin kendi kaynak kimliği olmalıdır. Bu koşulu uygulamazsanız kişiler uygulamasında sorunlara yol açarsınız. Aynı hesap türü için iki ham kişinin aynı kaynak kimliğine sahip olabileceğini unutmayın. Örneğin, emily.dickinson@gmail.com hesabındaki "Thomas Higginson" adlı ham kişinin, emilyd@gmail.com hesabındaki "Thomas Higginson" adlı ham kişiyle aynı kaynak kimliğe sahip olmasına izin verilir.
  • Kararlı: Kaynak kimlikleri, ham kişi için online hizmetin verilerinin kalıcı bir parçasıdır. Örneğin, kullanıcı Uygulamalar ayarlarından Kişiler Depolama'sını temizleyip yeniden senkronize ederse geri yüklenen ham kişilerin kaynak kimlikleri öncekiyle aynı olmalıdır. Bunu zorunlu tutmazsanız kısayollar çalışmayı durdurur.
ContactsContract.Groups GROUP_VISIBLE "0": Bu gruptaki kişiler Android uygulama kullanıcı arayüzlerinde görünmez. Bu sütun, kullanıcının belirli gruplardaki kişileri gizlemesine izin veren sunucularla uyumluluk içindir.
"1": Bu gruptaki kişilerin uygulama kullanıcı arayüzlerinde görünmesine izin verilir.
ContactsContract.Settings UNGROUPED_VISIBLE "0": Bu hesap ve hesap türü için bir gruba ait olmayan kişiler Android uygulama kullanıcı arayüzlerinde görünmez. Ham kişilerinden hiçbiri bir gruba ait değilse kişiler varsayılan olarak görünmezdir (Ham bir kişinin grup üyeliği, ContactsContract.Data tablosunda bir veya daha fazla ContactsContract.CommonDataKinds.GroupMembership satırıyla gösterilir). Bir hesap türü ve hesap için ContactsContract.Settings tablo satırında bu işareti ayarlayarak grup içermeyen kişilerin görünür olmasını zorunlu kılabilirsiniz. Bu işaretin bir kullanımı da grup kullanmayan sunuculardaki kişileri göstermektir.
"1" - Bu hesap ve hesap türü için bir gruba ait olmayan kişiler, uygulama kullanıcı arayüzlerinde görünür.
ContactsContract.SyncState (tümü) Senkronizasyon bağdaştırıcınızın meta verilerini depolamak için bu tabloyu kullanın. Bu tabloyu kullanarak senkronizasyon durumunu ve senkronizasyonla ilgili diğer verileri cihazda kalıcı olarak saklayabilirsiniz.

Kişiler sağlayıcısı erişimi

Bu bölümde, Kişi Sağlayıcı'daki verilere erişmeyle ilgili yönergeler açıklanmakta olup aşağıdakilere odaklanılmaktadır:

  • Öğe sorguları.
  • Toplu değişiklik.
  • Niyetlerle getirme ve değiştirme.
  • Veri bütünlüğü.

Senkronizasyon bağdaştırıcısı üzerinden değişiklik yapma konusu, Kişiler sağlayıcı senkronizasyon bağdaştırıcılar bölümünde daha ayrıntılı olarak ele alınmıştır.

Varlıkları sorgulama

Kişi Sağlayıcı tabloları hiyerarşik olarak düzenlendiğinden, bir satırı ve ona bağlı tüm "alt" satırları almak genellikle yararlıdır. Örneğin, bir kullanıcının tüm bilgilerini görüntülemek için tek bir ContactsContract.Contacts satırı için tüm ContactsContract.RawContacts satırlarını veya tek bir ContactsContract.RawContacts satırı için tüm ContactsContract.CommonDataKinds.Email satırlarını almak isteyebilirsiniz. Kişiler sağlayıcısı, bu işlemi kolaylaştırmak için tablolar arasında veritabanı birleştirme işlemi gibi çalışan varlık yapıları sunar.

Varlık, bir üst tablodaki ve alt tablodaki seçili sütunlardan oluşan bir tabloya benzer. Bir varlığı sorgularken, varlıktaki sütunlara göre bir projeksiyon ve arama ölçütleri sağlarsınız. Sonuç, alınan her alt tablo satırı için bir satır içeren bir Cursor olur. Örneğin, bir kişi adı için ContactsContract.Contacts.Entity sorgusu yaparsanız ve bu adın tüm ham kişilerini almak için tüm ContactsContract.CommonDataKinds.Email satırlarını sorgularsanız her ContactsContract.CommonDataKinds.Email satırı için bir satır içeren bir Cursor alırsınız.

Öğeler, sorguları basitleştirir. Bir varlık kullanarak, bir kimlik almak için önce üst tabloyu sorgulamak ve ardından bu kimlikle alt tabloyu sorgulamak zorunda kalmadan bir kişiye veya ham kişiye ait tüm kişi verilerini tek seferde alabilirsiniz. Ayrıca Kişi Sağlayıcı, bir öğeyle ilgili sorguyu tek bir işlemde işler. Bu, alınan verilerin dahili olarak tutarlı olmasını sağlar.

Not: Bir varlık genellikle üst ve alt tablonun tüm sütunlarını içermez. Varlık için sütun adı sabitleri listesinde bulunmayan bir sütun adıyla çalışmaya çalışırsanız Exception alırsınız.

Aşağıdaki snippet'te, bir kişinin tüm ham iletişim satırlarının nasıl alınacağı gösterilmektedir. Snippet, "main" ve "detail" adlı iki etkinliğe sahip daha büyük bir uygulamanın parçasıdır. Ana etkinlik, iletişim kişisi satırlarının listesini gösterir. Kullanıcı bir satır seçtiğinde etkinlik, satırın kimliğini ayrıntı etkinliğine gönderir. Ayrıntı etkinliği, seçili kişiyle ilişkili tüm ham kişilerin tüm veri satırlarını görüntülemek için ContactsContract.Contacts.Entity değerini kullanır.

Bu snippet, "ayrıntı" etkinliğinden alınmıştır:

Kotlin

...
    /*
     * Appends the entity path to the URI. In the case of the Contacts Provider, the
     * expected URI is content://com.google.contacts/#/entity (# is the ID value).
     */
    contactUri = Uri.withAppendedPath(
            contactUri,
            ContactsContract.Contacts.Entity.CONTENT_DIRECTORY
    )

    // Initializes the loader identified by LOADER_ID.
    loaderManager.initLoader(
            LOADER_ID,  // The identifier of the loader to initialize
            null,       // Arguments for the loader (in this case, none)
            this        // The context of the activity
    )

    // Creates a new cursor adapter to attach to the list view
    cursorAdapter = SimpleCursorAdapter(
            this,                       // the context of the activity
            R.layout.detail_list_item,  // the view item containing the detail widgets
            mCursor,                    // the backing cursor
            fromColumns,               // the columns in the cursor that provide the data
            toViews,                   // the views in the view item that display the data
            0)                          // flags

    // Sets the ListView's backing adapter.
    rawContactList.adapter = cursorAdapter
...
override fun onCreateLoader(id: Int, args: Bundle?): Loader<Cursor> {
    /*
     * Sets the columns to retrieve.
     * RAW_CONTACT_ID is included to identify the raw contact associated with the data row.
     * DATA1 contains the first column in the data row (usually the most important one).
     * MIMETYPE indicates the type of data in the data row.
     */
    val projection: Array<String> = arrayOf(
            ContactsContract.Contacts.Entity.RAW_CONTACT_ID,
            ContactsContract.Contacts.Entity.DATA1,
            ContactsContract.Contacts.Entity.MIMETYPE
    )

    /*
     * Sorts the retrieved cursor by raw contact id, to keep all data rows for a single raw
     * contact collated together.
     */
    val sortOrder = "${ContactsContract.Contacts.Entity.RAW_CONTACT_ID} ASC"

    /*
     * Returns a new CursorLoader. The arguments are similar to
     * ContentResolver.query(), except for the Context argument, which supplies the location of
     * the ContentResolver to use.
     */
    return CursorLoader(
            applicationContext, // The activity's context
            contactUri,        // The entity content URI for a single contact
            projection,         // The columns to retrieve
            null,               // Retrieve all the raw contacts and their data rows.
            null,               //
            sortOrder           // Sort by the raw contact ID.
    )
}

Java

...
    /*
     * Appends the entity path to the URI. In the case of the Contacts Provider, the
     * expected URI is content://com.google.contacts/#/entity (# is the ID value).
     */
    contactUri = Uri.withAppendedPath(
            contactUri,
            ContactsContract.Contacts.Entity.CONTENT_DIRECTORY);

    // Initializes the loader identified by LOADER_ID.
    getLoaderManager().initLoader(
            LOADER_ID,  // The identifier of the loader to initialize
            null,       // Arguments for the loader (in this case, none)
            this);      // The context of the activity

    // Creates a new cursor adapter to attach to the list view
    cursorAdapter = new SimpleCursorAdapter(
            this,                        // the context of the activity
            R.layout.detail_list_item,   // the view item containing the detail widgets
            mCursor,                     // the backing cursor
            fromColumns,                // the columns in the cursor that provide the data
            toViews,                    // the views in the view item that display the data
            0);                          // flags

    // Sets the ListView's backing adapter.
    rawContactList.setAdapter(cursorAdapter);
...
@Override
public Loader<Cursor> onCreateLoader(int id, Bundle args) {

    /*
     * Sets the columns to retrieve.
     * RAW_CONTACT_ID is included to identify the raw contact associated with the data row.
     * DATA1 contains the first column in the data row (usually the most important one).
     * MIMETYPE indicates the type of data in the data row.
     */
    String[] projection =
        {
            ContactsContract.Contacts.Entity.RAW_CONTACT_ID,
            ContactsContract.Contacts.Entity.DATA1,
            ContactsContract.Contacts.Entity.MIMETYPE
        };

    /*
     * Sorts the retrieved cursor by raw contact id, to keep all data rows for a single raw
     * contact collated together.
     */
    String sortOrder =
            ContactsContract.Contacts.Entity.RAW_CONTACT_ID +
            " ASC";

    /*
     * Returns a new CursorLoader. The arguments are similar to
     * ContentResolver.query(), except for the Context argument, which supplies the location of
     * the ContentResolver to use.
     */
    return new CursorLoader(
            getApplicationContext(),  // The activity's context
            contactUri,              // The entity content URI for a single contact
            projection,               // The columns to retrieve
            null,                     // Retrieve all the raw contacts and their data rows.
            null,                     //
            sortOrder);               // Sort by the raw contact ID.
}

Yükleme tamamlandığında LoaderManager, onLoadFinished() için geri çağırma işlevi çağırır. Bu yönteme gelen bağımsız değişkenlerden biri, sorgunun sonuçlarını içeren bir Cursor bağımsız değişkenidir. Kendi uygulamanızda, göstermek veya daha fazla çalışmak için bu Cursor içindeki verileri alabilirsiniz.

Toplu değişiklik

Mümkün olduğunda, ContentProviderOperation nesnelerinden oluşan bir ArrayList oluşturarak ve applyBatch() işlevini çağırarak Kişi Sağlayıcı'ya "toplu modda" veri eklemeniz, güncellemeniz ve silmeniz gerekir. Kişi Sağlayıcı, tüm işlemleri tek bir applyBatch() işleminde gerçekleştirdiğinden, yaptığınız değişiklikler kişi deposunu hiçbir zaman tutarsız bir durumda bırakmaz. Toplu değişiklik, ham bir kişiyi ve ayrıntı verilerini aynı anda eklemeyi de kolaylaştırır.

Not: Tek ham kişiyi değiştirmek için değişikliği uygulamanızda işlemek yerine cihazın kişiler uygulamasına intent gönderebilirsiniz. Bu işlem Intent'lerle getirme ve değiştirme bölümünde daha ayrıntılı olarak açıklanmıştır.

Getiri puanları

Çok sayıda işlem içeren bir toplu değişiklik, diğer işlemleri engelleyebilir ve genel kullanıcı deneyiminin kötü olmasına neden olabilir. Gerçekleştirmek istediğiniz tüm değişiklikleri mümkün olduğunca az sayıda ayrı listede düzenlemek ve aynı zamanda bu değişikliklerin sistemi engellemesini önlemek amacıyla bir veya daha fazla işlem için getiri noktaları ayarlamanız gerekir. Verim noktası, isYieldAllowed() değeri true olarak ayarlanmış bir ContentProviderOperation nesnesi. Kişi Sağlayıcı bir getiri noktasıyla karşılaştığında diğer işlemlerin çalıştırılmasına izin vermek için çalışmasını duraklatır ve geçerli işlemi kapatır. Sağlayıcı tekrar başladığında ArrayList içinde bir sonraki işlemle devam eder ve yeni bir işlem başlatır.

Getiri puanları, applyBatch() için yapılan arama başına birden fazla işlemle sonuçlanır. Bu nedenle, ilgili bir satır grubu için son işleme bir verim noktası ayarlamanız gerekir. Örneğin, ham kişi satırlarını ve ilişkili veri satırlarını ekleyen bir gruptaki son işlem veya tek bir kişiyle ilişkili satır kümesi için son işlem için getiri noktası belirlemeniz gerekir.

Getiri noktaları da atomik işlem birimidir. İki getiri noktası arasındaki tüm erişimler tek bir birim olarak başarılı veya başarısız olur. Verim noktası ayarlamazsanız en küçük atomik işlem, tüm işlem grubudur. Verim noktalarını kullanırsanız işlemlerin sistem performansını düşürmesini önlerken aynı zamanda işlemlerin bir alt kümesinin atomik olmasını sağlarsınız.

Değişiklik geri referansları

Yeni bir ham kişi satırı ve ilişkili veri satırlarını bir ContentProviderOperation nesnesi grubu olarak eklerken, RAW_CONTACT_ID değeri olarak ham kişinin _ID değerini ekleyerek veri satırlarını ham kişi satırına bağlamanız gerekir. Ancak ham kişi satırı için ContentProviderOperation henüz uygulanmadığından, veri satırı için ContentProviderOperation oluştururken bu değer kullanılamaz. Bu sorunu gidermek için ContentProviderOperation.Builder sınıfında withValueBackReference() yöntemi bulunur. Bu yöntem, önceki bir işlemin sonucunu içeren bir sütun eklemenize veya değiştirmenize olanak tanır.

withValueBackReference() yönteminin iki bağımsız değişkeni vardır:

key
Anahtar/değer çiftinin anahtarıdır. Bu bağımsız değişkenin değeri, değiştirdiğiniz tablodaki bir sütunun adı olmalıdır.
previousResult
applyBatch() alanındaki ContentProviderResult nesne dizisindeki bir değerin 0 tabanlı dizini. Toplu işlemler uygulanırken her işlemin sonucu bir ara sonuç dizisinde saklanır. previousResult değeri, bu sonuçlardan birinin dizinidir ve key değeriyle birlikte alınıp saklanır. Bu sayede yeni bir ham kişi kaydı ekleyebilir ve _ID değerini alabilir, ardından ContactsContract.Data satırı eklediğinizde değere "geri referans" verebilirsiniz.

Sonuç dizisinin tamamı, applyBatch() işlevini ilk kez çağırdığınızda oluşturulur. Bu dizi, sağladığınız ContentProviderOperation nesnelerinin ArrayList boyutuna eşittir. Ancak sonuç dizisindeki tüm öğeler null olarak ayarlanır ve henüz uygulanmamış bir işlem için bir sonuca geri referans vermeye çalışırsanız withValueBackReference() Exception oluşturur.

Aşağıdaki snippet'lerde, yeni bir ham kişi ve verilerin toplu olarak nasıl ekleneceği gösterilmektedir. Bunlar, bir verim noktası oluşturan ve geri referans kullanan kod içerir.

İlk snippet, kullanıcı arayüzünden kişi verilerini alır. Bu noktada kullanıcı, yeni ham kişinin ekleneceği hesabı zaten seçmiştir.

Kotlin

// Creates a contact entry from the current UI values, using the currently-selected account.
private fun createContactEntry() {
    /*
     * Gets values from the UI
     */
    val name = contactNameEditText.text.toString()
    val phone = contactPhoneEditText.text.toString()
    val email = contactEmailEditText.text.toString()

    val phoneType: String = contactPhoneTypes[mContactPhoneTypeSpinner.selectedItemPosition]

    val emailType: String = contactEmailTypes[mContactEmailTypeSpinner.selectedItemPosition]

Java

// Creates a contact entry from the current UI values, using the currently-selected account.
protected void createContactEntry() {
    /*
     * Gets values from the UI
     */
    String name = contactNameEditText.getText().toString();
    String phone = contactPhoneEditText.getText().toString();
    String email = contactEmailEditText.getText().toString();

    int phoneType = contactPhoneTypes.get(
            contactPhoneTypeSpinner.getSelectedItemPosition());

    int emailType = contactEmailTypes.get(
            contactEmailTypeSpinner.getSelectedItemPosition());

Sonraki snippet, ham kişi satırını ContactsContract.RawContacts tablosuna eklemek için bir işlem oluşturur:

Kotlin

    /*
     * Prepares the batch operation for inserting a new raw contact and its data. Even if
     * the Contacts Provider does not have any data for this person, you can't add a Contact,
     * only a raw contact. The Contacts Provider will then add a Contact automatically.
     */

    // Creates a new array of ContentProviderOperation objects.
    val ops = arrayListOf<ContentProviderOperation>()

    /*
     * Creates a new raw contact with its account type (server type) and account name
     * (user's account). Remember that the display name is not stored in this row, but in a
     * StructuredName data row. No other data is required.
     */
    var op: ContentProviderOperation.Builder =
            ContentProviderOperation.newInsert(ContactsContract.RawContacts.CONTENT_URI)
                    .withValue(ContactsContract.RawContacts.ACCOUNT_TYPE, selectedAccount.name)
                    .withValue(ContactsContract.RawContacts.ACCOUNT_NAME, selectedAccount.type)

    // Builds the operation and adds it to the array of operations
    ops.add(op.build())

Java

    /*
     * Prepares the batch operation for inserting a new raw contact and its data. Even if
     * the Contacts Provider does not have any data for this person, you can't add a Contact,
     * only a raw contact. The Contacts Provider will then add a Contact automatically.
     */

     // Creates a new array of ContentProviderOperation objects.
    ArrayList<ContentProviderOperation> ops =
            new ArrayList<ContentProviderOperation>();

    /*
     * Creates a new raw contact with its account type (server type) and account name
     * (user's account). Remember that the display name is not stored in this row, but in a
     * StructuredName data row. No other data is required.
     */
    ContentProviderOperation.Builder op =
            ContentProviderOperation.newInsert(ContactsContract.RawContacts.CONTENT_URI)
            .withValue(ContactsContract.RawContacts.ACCOUNT_TYPE, selectedAccount.getType())
            .withValue(ContactsContract.RawContacts.ACCOUNT_NAME, selectedAccount.getName());

    // Builds the operation and adds it to the array of operations
    ops.add(op.build());

Ardından kod, görünen ad, telefon ve e-posta satırları için veri satırları oluşturur.

Her işlem oluşturucu nesnesi, RAW_CONTACT_ID değerini almak için withValueBackReference() değerini kullanır. Referans, ilk işlemdeki ContentProviderResult nesnesine geri döner. Bu nesne, ham iletişim satırı ekleyip yeni _ID değerini döndürür. Sonuç olarak, her veri satırı RAW_CONTACT_ID ile ait olduğu yeni ContactsContract.RawContacts satırı arasında otomatik olarak bağlanır.

E-posta satırını ekleyen ContentProviderOperation.Builder nesnesi, bir getiri noktası belirleyen withYieldAllowed() ile işaretlenir:

Kotlin

    // Creates the display name for the new raw contact, as a StructuredName data row.
    op = ContentProviderOperation.newInsert(ContactsContract.Data.CONTENT_URI)
            /*
             * withValueBackReference sets the value of the first argument to the value of
             * the ContentProviderResult indexed by the second argument. In this particular
             * call, the raw contact ID column of the StructuredName data row is set to the
             * value of the result returned by the first operation, which is the one that
             * actually adds the raw contact row.
             */
            .withValueBackReference(ContactsContract.Data.RAW_CONTACT_ID, 0)

            // Sets the data row's MIME type to StructuredName
            .withValue(ContactsContract.Data.MIMETYPE,
                    ContactsContract.CommonDataKinds.StructuredName.CONTENT_ITEM_TYPE)

            // Sets the data row's display name to the name in the UI.
            .withValue(ContactsContract.CommonDataKinds.StructuredName.DISPLAY_NAME, name)

    // Builds the operation and adds it to the array of operations
    ops.add(op.build())

    // Inserts the specified phone number and type as a Phone data row
    op = ContentProviderOperation.newInsert(ContactsContract.Data.CONTENT_URI)
            /*
             * Sets the value of the raw contact id column to the new raw contact ID returned
             * by the first operation in the batch.
             */
            .withValueBackReference(ContactsContract.Data.RAW_CONTACT_ID, 0)

            // Sets the data row's MIME type to Phone
            .withValue(ContactsContract.Data.MIMETYPE,
                    ContactsContract.CommonDataKinds.Phone.CONTENT_ITEM_TYPE)

            // Sets the phone number and type
            .withValue(ContactsContract.CommonDataKinds.Phone.NUMBER, phone)
            .withValue(ContactsContract.CommonDataKinds.Phone.TYPE, phoneType)

    // Builds the operation and adds it to the array of operations
    ops.add(op.build())

    // Inserts the specified email and type as a Phone data row
    op = ContentProviderOperation.newInsert(ContactsContract.Data.CONTENT_URI)
            /*
             * Sets the value of the raw contact id column to the new raw contact ID returned
             * by the first operation in the batch.
             */
            .withValueBackReference(ContactsContract.Data.RAW_CONTACT_ID, 0)

            // Sets the data row's MIME type to Email
            .withValue(ContactsContract.Data.MIMETYPE,
                    ContactsContract.CommonDataKinds.Email.CONTENT_ITEM_TYPE)

            // Sets the email address and type
            .withValue(ContactsContract.CommonDataKinds.Email.ADDRESS, email)
            .withValue(ContactsContract.CommonDataKinds.Email.TYPE, emailType)

    /*
     * Demonstrates a yield point. At the end of this insert, the batch operation's thread
     * will yield priority to other threads. Use after every set of operations that affect a
     * single contact, to avoid degrading performance.
     */
    op.withYieldAllowed(true)

    // Builds the operation and adds it to the array of operations
    ops.add(op.build())

Java

    // Creates the display name for the new raw contact, as a StructuredName data row.
    op =
            ContentProviderOperation.newInsert(ContactsContract.Data.CONTENT_URI)
            /*
             * withValueBackReference sets the value of the first argument to the value of
             * the ContentProviderResult indexed by the second argument. In this particular
             * call, the raw contact ID column of the StructuredName data row is set to the
             * value of the result returned by the first operation, which is the one that
             * actually adds the raw contact row.
             */
            .withValueBackReference(ContactsContract.Data.RAW_CONTACT_ID, 0)

            // Sets the data row's MIME type to StructuredName
            .withValue(ContactsContract.Data.MIMETYPE,
                    ContactsContract.CommonDataKinds.StructuredName.CONTENT_ITEM_TYPE)

            // Sets the data row's display name to the name in the UI.
            .withValue(ContactsContract.CommonDataKinds.StructuredName.DISPLAY_NAME, name);

    // Builds the operation and adds it to the array of operations
    ops.add(op.build());

    // Inserts the specified phone number and type as a Phone data row
    op =
            ContentProviderOperation.newInsert(ContactsContract.Data.CONTENT_URI)
            /*
             * Sets the value of the raw contact id column to the new raw contact ID returned
             * by the first operation in the batch.
             */
            .withValueBackReference(ContactsContract.Data.RAW_CONTACT_ID, 0)

            // Sets the data row's MIME type to Phone
            .withValue(ContactsContract.Data.MIMETYPE,
                    ContactsContract.CommonDataKinds.Phone.CONTENT_ITEM_TYPE)

            // Sets the phone number and type
            .withValue(ContactsContract.CommonDataKinds.Phone.NUMBER, phone)
            .withValue(ContactsContract.CommonDataKinds.Phone.TYPE, phoneType);

    // Builds the operation and adds it to the array of operations
    ops.add(op.build());

    // Inserts the specified email and type as a Phone data row
    op =
            ContentProviderOperation.newInsert(ContactsContract.Data.CONTENT_URI)
            /*
             * Sets the value of the raw contact id column to the new raw contact ID returned
             * by the first operation in the batch.
             */
            .withValueBackReference(ContactsContract.Data.RAW_CONTACT_ID, 0)

            // Sets the data row's MIME type to Email
            .withValue(ContactsContract.Data.MIMETYPE,
                    ContactsContract.CommonDataKinds.Email.CONTENT_ITEM_TYPE)

            // Sets the email address and type
            .withValue(ContactsContract.CommonDataKinds.Email.ADDRESS, email)
            .withValue(ContactsContract.CommonDataKinds.Email.TYPE, emailType);

    /*
     * Demonstrates a yield point. At the end of this insert, the batch operation's thread
     * will yield priority to other threads. Use after every set of operations that affect a
     * single contact, to avoid degrading performance.
     */
    op.withYieldAllowed(true);

    // Builds the operation and adds it to the array of operations
    ops.add(op.build());

Son snippet'te, yeni ham kişi ve veri satırlarını ekleyen applyBatch() çağrısı gösterilmektedir.

Kotlin

    // Ask the Contacts Provider to create a new contact
    Log.d(TAG, "Selected account: ${mSelectedAccount.name} (${mSelectedAccount.type})")
    Log.d(TAG, "Creating contact: $name")

    /*
     * Applies the array of ContentProviderOperation objects in batch. The results are
     * discarded.
     */
    try {
        contentResolver.applyBatch(ContactsContract.AUTHORITY, ops)
    } catch (e: Exception) {
        // Display a warning
        val txt: String = getString(R.string.contactCreationFailure)
        Toast.makeText(applicationContext, txt, Toast.LENGTH_SHORT).show()

        // Log exception
        Log.e(TAG, "Exception encountered while inserting contact: $e")
    }
}

Java

    // Ask the Contacts Provider to create a new contact
    Log.d(TAG,"Selected account: " + selectedAccount.getName() + " (" +
            selectedAccount.getType() + ")");
    Log.d(TAG,"Creating contact: " + name);

    /*
     * Applies the array of ContentProviderOperation objects in batch. The results are
     * discarded.
     */
    try {

            getContentResolver().applyBatch(ContactsContract.AUTHORITY, ops);
    } catch (Exception e) {

            // Display a warning
            Context ctx = getApplicationContext();

            CharSequence txt = getString(R.string.contactCreationFailure);
            int duration = Toast.LENGTH_SHORT;
            Toast toast = Toast.makeText(ctx, txt, duration);
            toast.show();

            // Log exception
            Log.e(TAG, "Exception encountered while inserting contact: " + e);
    }
}

Toplu işlemler, temel deposu kilitlemek zorunda kalmadan değişiklik işlemlerini uygulama yöntemi olan iyimser eşzamanlılık denetimini de uygulamanıza olanak tanır. Bu yöntemi kullanmak için işlemi uygular ve ardından aynı anda yapılmış olabilecek diğer değişiklikleri kontrol edersiniz. Tutarsız bir değişiklik yapıldığını tespit ederseniz işleminizi geri alıp yeniden deneyebilirsiniz.

Optimistic concurrency control, aynı anda yalnızca bir kullanıcının bulunduğu ve veri deposuna eşzamanlı erişimlerin nadir olduğu mobil cihazlar için kullanışlıdır. Kilitleme kullanılmadığından, kilit ayarlama veya diğer işlemlerin kilitlerini açmalarını beklemekle zaman kaybetmezsiniz.

Tek bir satırı güncellerken iyimser eşzamanlılık denetimini kullanmak için şu adımları uygulayın: ContactsContract.RawContacts

  1. Aldığınız diğer verilerle birlikte ham kişinin VERSION sütununu alın.
  2. newAssertQuery(Uri) yöntemini kullanarak kısıtlamayı uygulamaya uygun bir ContentProviderOperation.Builder nesnesi oluşturun. İçerik URI'si için ham kişinin _ID kısmı eklenmiş şekilde RawContacts.CONTENT_URI kullanın.
  3. ContentProviderOperation.Builder nesnesi için VERSION sütununu az önce aldığınız sürüm numarasıyla karşılaştırmak üzere withValue() işlevini çağırın.
  4. Aynı ContentProviderOperation.Builder için bu iddianın yalnızca bir satırı test etmesini sağlamak amacıyla withExpectedCount() işlevini çağırın.
  5. ContentProviderOperation nesnesini oluşturmak için build() işlevini çağırın, ardından bu nesneyi applyBatch() işlevine ilettiğiniz ArrayList içinde ilk nesne olarak ekleyin.
  6. Toplu işlemi uygulayın.

Ham kişi satırı, satırın okunması ile değiştirilmeye çalışılması arasında başka bir işlem tarafından güncellenirse "assert" ContentProviderOperation başarısız olur ve işlem grubunun tamamı geri alınır. Ardından, grubu yeniden denemeyi veya başka bir işlem yapmayı seçebilirsiniz.

Aşağıdaki snippet'te, CursorLoader kullanarak tek bir ham kişi için sorgu yaptıktan sonra nasıl "assert" ContentProviderOperation oluşturulacağı gösterilmektedir:

Kotlin

/*
 * The application uses CursorLoader to query the raw contacts table. The system calls this method
 * when the load is finished.
 */
override fun onLoadFinished(loader: Loader<Cursor>, cursor: Cursor) {
    // Gets the raw contact's _ID and VERSION values
    rawContactID = cursor.getLong(cursor.getColumnIndex(BaseColumns._ID))
    mVersion = cursor.getInt(cursor.getColumnIndex(SyncColumns.VERSION))
}

...

// Sets up a Uri for the assert operation
val rawContactUri: Uri = ContentUris.withAppendedId(
        ContactsContract.RawContacts.CONTENT_URI,
        rawContactID
)

// Creates a builder for the assert operation
val assertOp: ContentProviderOperation.Builder =
        ContentProviderOperation.newAssertQuery(rawContactUri).apply {
            // Adds the assertions to the assert operation: checks the version
            withValue(SyncColumns.VERSION, mVersion)

            // and count of rows tested
            withExpectedCount(1)
        }

// Creates an ArrayList to hold the ContentProviderOperation objects
val ops = arrayListOf<ContentProviderOperation>()

ops.add(assertOp.build())

// You would add the rest of your batch operations to "ops" here

...

// Applies the batch. If the assert fails, an Exception is thrown
try {
    val results: Array<ContentProviderResult> = contentResolver.applyBatch(AUTHORITY, ops)
} catch (e: OperationApplicationException) {
    // Actions you want to take if the assert operation fails go here
}

Java

/*
 * The application uses CursorLoader to query the raw contacts table. The system calls this method
 * when the load is finished.
 */
public void onLoadFinished(Loader<Cursor> loader, Cursor cursor) {

    // Gets the raw contact's _ID and VERSION values
    rawContactID = cursor.getLong(cursor.getColumnIndex(BaseColumns._ID));
    mVersion = cursor.getInt(cursor.getColumnIndex(SyncColumns.VERSION));
}

...

// Sets up a Uri for the assert operation
Uri rawContactUri = ContentUris.withAppendedId(RawContacts.CONTENT_URI, rawContactID);

// Creates a builder for the assert operation
ContentProviderOperation.Builder assertOp = ContentProviderOperation.newAssertQuery(rawContactUri);

// Adds the assertions to the assert operation: checks the version and count of rows tested
assertOp.withValue(SyncColumns.VERSION, mVersion);
assertOp.withExpectedCount(1);

// Creates an ArrayList to hold the ContentProviderOperation objects
ArrayList ops = new ArrayList<ContentProviderOperation>;

ops.add(assertOp.build());

// You would add the rest of your batch operations to "ops" here

...

// Applies the batch. If the assert fails, an Exception is thrown
try
    {
        ContentProviderResult[] results =
                getContentResolver().applyBatch(AUTHORITY, ops);

    } catch (OperationApplicationException e) {

        // Actions you want to take if the assert operation fails go here
    }

Niyetlerle getirme ve değiştirme

Cihazın kişiler uygulamasına bir intent göndermek, Kişi Sağlayıcı'ya dolaylı olarak erişmenize olanak tanır. Intent, cihazın kişiler uygulaması kullanıcı arayüzünü başlatır. Kullanıcılar bu arayüzde kişilerle ilgili işlemleri yapabilir. Bu erişim türüyle kullanıcılar şunları yapabilir:

  • Listeden bir kişi seçip daha fazla işlem yapmak için uygulamanıza döndürün.
  • Mevcut bir kişinin verilerini düzenleyin.
  • Hesaplarından herhangi biri için yeni bir ham kişi ekleyin.
  • Bir kişiyi veya kişi verilerini silme.

Kullanıcı veri ekliyor veya güncelliyorsa verileri önce toplayabilir ve intent'in bir parçası olarak gönderebilirsiniz.

Cihazın kişiler uygulaması aracılığıyla Kişiler Sağlayıcısına erişmek için intent'leri kullandığınızda sağlayıcıya erişmek için kendi kullanıcı arayüzünüzü veya kodunuzu yazmanız gerekmez. Ayrıca, sağlayıcıya okuma veya yazma izni vermeniz de gerekmez. Cihazın kişiler uygulaması, bir kişi için size okuma izni verebilir. Sağlayıcıda başka bir uygulama üzerinden değişiklik yaptığınız için yazma izinlerine sahip olmanız gerekmez.

Bir sağlayıcıya erişmek için intent göndermeyle ilgili genel süreç, İçerik Sağlayıcı ile ilgili temel bilgiler kılavuzunun "Intent'ler aracılığıyla veri erişimi" bölümünde ayrıntılı olarak açıklanmıştır. Mevcut görevler için kullandığınız işlem, MIME türü ve veri değerleri Tablo 4'te özetlenmiştir. putExtra() ile kullanabileceğiniz ekstra değerler ise ContactsContract.Intents.Insert'e ait referans dokümanlarında listelenmiştir:

Tablo 4. Kişi Sağlayıcı Intent'leri.

Görev İşlem Veri MIME türü Notlar
Listeden kişi seçme ACTION_PICK Şunlardan biri: Kullanılmadı Sağladığınız içerik URI türüne bağlı olarak ham kişilerin veya ham bir kişideki verilerin listesini gösterir.

startActivityForResult() işlevini çağırın. Bu işlev, seçilen satırın içerik URI'sini döndürür. URI'nin biçimi, tablonun içerik URI'sine satırın LOOKUP_ID eklenmesiyle oluşturulur. Cihazın kişiler uygulaması, etkinliğinizin süresi boyunca bu içerik URI'sine okuma ve yazma izinlerini atar. Daha fazla bilgi için İçerik Sağlayıcılarla ilgili temel bilgiler kılavuzunu inceleyin.

Yeni ham kişi ekleme Insert.ACTION Yok RawContacts.CONTENT_TYPE, ham kişi grubu için MIME türü. Cihazın Kişiler uygulamasının Kişi Ekle ekranını gösterir. Amaca eklediğiniz ekstra değerler gösterilir. startActivityForResult() ile gönderilirse yeni eklenen ham kişinin içerik URI'si, Intent bağımsız değişkenindeki "veri" alanındaki etkinliğinizin onActivityResult() geri çağırma yöntemine geri gönderilir. Değeri almak için getData() işlevini çağırın.
Kişileri düzenleme ACTION_EDIT CONTENT_LOOKUP_URI Düzenleyici etkinliği, kullanıcının bu kişiyle ilişkili tüm verileri düzenlemesine olanak tanır. Contacts.CONTENT_ITEM_TYPE, tek bir kişi. Kişiler uygulamasında Kişi Düzenle ekranını görüntüler. Intent'e eklediğiniz ek değerler gösterilir. Kullanıcı, düzenlemeleri kaydetmek için Bitti'yi tıkladığında etkinliğiniz ön plana döner.
Veri de ekleyebilen bir seçici gösterin. ACTION_INSERT_OR_EDIT Yok CONTENT_ITEM_TYPE Bu intent her zaman kişiler uygulamasının seçici ekranını gösterir. Kullanıcı, düzenleyeceği bir kişiyi seçebilir veya yeni bir kişi ekleyebilir. Kullanıcının seçimine bağlı olarak düzenleme veya ekleme ekranı görünür ve intent'e ilettiğiniz ekstra veriler gösterilir. Uygulamanız e-posta veya telefon numarası gibi iletişim verilerini gösteriyorsa kullanıcının verileri mevcut bir kişiye eklemesine izin vermek için bu intent'i kullanın. iletişime geçebilir.

Not: Kullanıcı her zaman mevcut bir adı seçtiği veya yeni bir ad eklediği için bu intent'in eklerinde ad değeri göndermeniz gerekmez. Ayrıca, bir ad gönderirseniz ve kullanıcı düzenleme yapmayı seçerse kişiler uygulaması, gönderdiğiniz adı gösterir ve önceki değerin üzerine yazar. Kullanıcı bunu fark etmezse ve düzenlemeyi kaydederse eski değer kaybolur.

Cihazın kişi uygulaması, ham bir kişiyi veya verilerini bir intent ile silmenize izin vermez. Bunun yerine, ham bir kişiyi silmek için ContentResolver.delete() veya ContentProviderOperation.newDelete() değerini kullanın.

Aşağıdaki snippet'te, yeni bir ham iletişim ve veri ekleyen bir intent'in nasıl oluşturulacağı ve gönderileceği gösterilmektedir:

Kotlin

// Gets values from the UI
val name = contactNameEditText.text.toString()
val phone = contactPhoneEditText.text.toString()
val email = contactEmailEditText.text.toString()

val company = companyName.text.toString()
val jobtitle = jobTitle.text.toString()

/*
 * Demonstrates adding data rows as an array list associated with the DATA key
 */

// Defines an array list to contain the ContentValues objects for each row
val contactData = arrayListOf<ContentValues>()

/*
 * Defines the raw contact row
 */

// Sets up the row as a ContentValues object
val rawContactRow = ContentValues().apply {
    // Adds the account type and name to the row
    put(ContactsContract.RawContacts.ACCOUNT_TYPE, selectedAccount.type)
    put(ContactsContract.RawContacts.ACCOUNT_NAME, selectedAccount.name)
}

// Adds the row to the array
contactData.add(rawContactRow)

/*
 * Sets up the phone number data row
 */

// Sets up the row as a ContentValues object
val phoneRow = ContentValues().apply {
    // Specifies the MIME type for this data row (all data rows must be marked by their type)
    put(ContactsContract.Data.MIMETYPE,ContactsContract.CommonDataKinds.Phone.CONTENT_ITEM_TYPE)

    // Adds the phone number and its type to the row
    put(ContactsContract.CommonDataKinds.Phone.NUMBER, phone)
}

// Adds the row to the array
contactData.add(phoneRow)

/*
 * Sets up the email data row
 */

// Sets up the row as a ContentValues object
val emailRow = ContentValues().apply {
    // Specifies the MIME type for this data row (all data rows must be marked by their type)
    put(ContactsContract.Data.MIMETYPE, ContactsContract.CommonDataKinds.Email.CONTENT_ITEM_TYPE)

    // Adds the email address and its type to the row
    put(ContactsContract.CommonDataKinds.Email.ADDRESS, email)
}

// Adds the row to the array
contactData.add(emailRow)

// Creates a new intent for sending to the device's contacts application
val insertIntent = Intent(ContactsContract.Intents.Insert.ACTION).apply {
    // Sets the MIME type to the one expected by the insertion activity
    type = ContactsContract.RawContacts.CONTENT_TYPE

    // Sets the new contact name
    putExtra(ContactsContract.Intents.Insert.NAME, name)

    // Sets the new company and job title
    putExtra(ContactsContract.Intents.Insert.COMPANY, company)
    putExtra(ContactsContract.Intents.Insert.JOB_TITLE, jobtitle)

    /*
    * Adds the array to the intent's extras. It must be a parcelable object in order to
    * travel between processes. The device's contacts app expects its key to be
    * Intents.Insert.DATA
    */
    putParcelableArrayListExtra(ContactsContract.Intents.Insert.DATA, contactData)
}

// Send out the intent to start the device's contacts app in its add contact activity.
startActivity(insertIntent)

Java

// Gets values from the UI
String name = contactNameEditText.getText().toString();
String phone = contactPhoneEditText.getText().toString();
String email = contactEmailEditText.getText().toString();

String company = companyName.getText().toString();
String jobtitle = jobTitle.getText().toString();

// Creates a new intent for sending to the device's contacts application
Intent insertIntent = new Intent(ContactsContract.Intents.Insert.ACTION);

// Sets the MIME type to the one expected by the insertion activity
insertIntent.setType(ContactsContract.RawContacts.CONTENT_TYPE);

// Sets the new contact name
insertIntent.putExtra(ContactsContract.Intents.Insert.NAME, name);

// Sets the new company and job title
insertIntent.putExtra(ContactsContract.Intents.Insert.COMPANY, company);
insertIntent.putExtra(ContactsContract.Intents.Insert.JOB_TITLE, jobtitle);

/*
 * Demonstrates adding data rows as an array list associated with the DATA key
 */

// Defines an array list to contain the ContentValues objects for each row
ArrayList<ContentValues> contactData = new ArrayList<ContentValues>();


/*
 * Defines the raw contact row
 */

// Sets up the row as a ContentValues object
ContentValues rawContactRow = new ContentValues();

// Adds the account type and name to the row
rawContactRow.put(ContactsContract.RawContacts.ACCOUNT_TYPE, selectedAccount.getType());
rawContactRow.put(ContactsContract.RawContacts.ACCOUNT_NAME, selectedAccount.getName());

// Adds the row to the array
contactData.add(rawContactRow);

/*
 * Sets up the phone number data row
 */

// Sets up the row as a ContentValues object
ContentValues phoneRow = new ContentValues();

// Specifies the MIME type for this data row (all data rows must be marked by their type)
phoneRow.put(
        ContactsContract.Data.MIMETYPE,
        ContactsContract.CommonDataKinds.Phone.CONTENT_ITEM_TYPE
);

// Adds the phone number and its type to the row
phoneRow.put(ContactsContract.CommonDataKinds.Phone.NUMBER, phone);

// Adds the row to the array
contactData.add(phoneRow);

/*
 * Sets up the email data row
 */

// Sets up the row as a ContentValues object
ContentValues emailRow = new ContentValues();

// Specifies the MIME type for this data row (all data rows must be marked by their type)
emailRow.put(
        ContactsContract.Data.MIMETYPE,
        ContactsContract.CommonDataKinds.Email.CONTENT_ITEM_TYPE
);

// Adds the email address and its type to the row
emailRow.put(ContactsContract.CommonDataKinds.Email.ADDRESS, email);

// Adds the row to the array
contactData.add(emailRow);

/*
 * Adds the array to the intent's extras. It must be a parcelable object in order to
 * travel between processes. The device's contacts app expects its key to be
 * Intents.Insert.DATA
 */
insertIntent.putParcelableArrayListExtra(ContactsContract.Intents.Insert.DATA, contactData);

// Send out the intent to start the device's contacts app in its add contact activity.
startActivity(insertIntent);

Veri bütünlüğü

Kişi deposu, kullanıcıların doğru ve güncel olmasını beklediği önemli ve hassas verileri içerdiğinden Kişi Sağlayıcısı, iyi tanımlanmış veri bütünlüğü kurallarına sahiptir. Kişi verilerini değiştirirken bu kurallara uymak sizin sorumluluğunuzdadır. Önemli kurallar aşağıda listelenmiştir:

Eklediğiniz her ContactsContract.RawContacts satırı için daima bir ContactsContract.CommonDataKinds.StructuredName satırı ekleyin.
ContactsContract.Data tablosunda ContactsContract.CommonDataKinds.StructuredName satırı olmayan ContactsContract.RawContacts satırı, toplama sırasında sorunlara neden olabilir.
Yeni ContactsContract.Data satırlarını her zaman üst ContactsContract.RawContacts satırına bağla.
ContactsContract.RawContacts cihazına bağlı olmayan ContactsContract.Data satırı, cihazın kişiler uygulamasında görünmez ve bu durum senkronizasyon bağdaştırıcılarıyla ilgili sorunlara neden olabilir.
Yalnızca sahibi olduğunuz ham kişilerin verilerini değiştirin.
Kişi Sağlayıcı'nın genellikle birkaç farklı hesap türünden/online hizmetten gelen verileri yönettiğini unutmayın. Uygulamanızın yalnızca size ait satırlardaki verileri değiştirdiğinden veya sildiğinden ve yalnızca kontrol ettiğiniz hesap türünde ve adında veri eklediğinden emin olmanız gerekir.
Yetkililer, içerik URI'leri, URI yolları, sütun adları, MIME türleri ve TYPE değerleri için her zaman ContactsContract ve alt sınıflarında tanımlanan sabitleri kullanın.
Bu sabitleri kullanmak, hataları önlemenize yardımcı olur. Ayrıca, sabit değerlerden herhangi biri kullanımdan kaldırılırsa derleyici uyarılarıyla bilgilendirilirsiniz.

Özel veri satırları

Kendi özel MIME türlerinizi oluşturup kullanarak ContactsContract.Data tablosuna kendi veri satırlarınızı ekleyebilir, düzenleyebilir, silebilir ve alabilirsiniz. Satırlarınız, ContactsContract.DataColumns içinde tanımlanan sütunu kullanmakla sınırlıdır. Bununla birlikte, kendi türe özgü sütun adlarınızı varsayılan sütun adlarıyla eşleyebilirsiniz. Cihazın kişiler uygulamasında satırlarınıza ait veriler gösterilir ancak düzenlenemez veya silinemez. Ayrıca kullanıcılar ek veri ekleyemez. Kullanıcıların özel veri satırlarınızı değiştirmesine izin vermek için kendi uygulamanızda bir düzenleyici etkinliği sağlamanız gerekir.

Özel verilerinizi görüntülemek için <ContactsAccountType> öğesini ve bu öğenin en az bir <ContactsDataKind> alt öğesini içeren bir contacts.xml dosyası sağlayın. Bu konu <ContactsDataKind> element bölümünde daha ayrıntılı olarak açıklanmıştır.

Özel MIME türleri hakkında daha fazla bilgi edinmek için İçerik Sağlayıcı Oluşturma kılavuzunu okuyun.

Kişi Sağlayıcı senkronizasyon adaptörleri

Kişi Sağlayıcısı, kişi verilerinin bir cihaz ile çevrimiçi bir hizmet arasında senkronize edilmesi için özel olarak tasarlanmıştır. Bu sayede kullanıcılar mevcut verileri yeni bir cihaza indirebilir ve yeni bir hesaba yükleyebilir. Senkronizasyon, eklemelerin ve değişikliklerin kaynağından bağımsız olarak kullanıcıların en güncel verilere sahip olmasını da sağlar. Senkronizasyonun bir başka avantajı da cihaz ağa bağlı olmasa bile kişi verilerinin kullanılabilmesidir.

Senkronizasyonu çeşitli şekillerde uygulayabilseniz de Android sistemi, aşağıdaki görevleri otomatikleştiren bir eklenti senkronizasyon çerçevesi sağlar:

  • Ağ kullanılabilirliği kontrol ediliyor.
  • Kullanıcı tercihlerine göre senkronizasyonu planlama ve yürütme.
  • Durdurulan senkronizasyonları yeniden başlatma.

Bu çerçeveyi kullanmak için bir senkronizasyon bağdaştırıcısı eklentisi sağlarsınız. Her senkronizasyon bağdaştırıcısı bir hizmete ve içerik sağlayıcıya özgüdür ancak aynı hizmet için birden fazla hesap adını işleyebilir. Çerçeve, aynı servis ve sağlayıcı için birden fazla senkronizasyon bağdaştırıcısı da kullanmanıza olanak tanır.

Senkronizasyon adaptörü sınıflarını ve dosyalarını senkronize etme

Bir senkronizasyon bağdaştırıcısını AbstractThreadedSyncAdapter alt sınıfı olarak uygular ve bir Android uygulamasının parçası olarak yüklersiniz. Sistem, senkronizasyon bağdaştırıcısı hakkında bilgileri uygulama manifestinizdeki öğelerden ve manifest tarafından işaretlenen özel bir XML dosyasından öğrenir. XML dosyası, online hizmet için hesap türünü ve içerik sağlayıcının yetkilisini tanımlar. Bu da birlikte bağdaştırıcıyı benzersiz bir şekilde tanımlar. Kullanıcı, senkronizasyon bağdaştırıcısı için hesap türüne uygun bir hesap ekleyip senkronizasyon bağdaştırıcısı ile senkronize edilen içerik sağlayıcı için senkronizasyonu etkinleştirene kadar senkronizasyon bağdaştırıcısı etkin olmaz. Bu noktada sistem, bağdaştırıcıyı yönetmeye başlar ve içerik sağlayıcı ile sunucu arasında senkronizasyon yapmak için gerektiğinde bağdaştırıcıyı çağırır.

Not: Senkronizasyon bağdaştırıcısının tanımlamasının bir parçası olarak bir hesap türünün kullanılması, sistemin aynı kuruluştan farklı hizmetlere erişen senkronizasyon bağdaştırıcılarını algılamasına ve birlikte gruplandırmasına olanak tanır. Örneğin, Google online hizmetlerinin senkronizasyon bağdaştırıcıların tümü aynı com.google hesap türüne sahiptir. Kullanıcılar cihazlarına bir Google Hesabı eklediğinde, Google hizmetleri için yüklenen tüm senkronizasyon bağdaştırıcılar birlikte listelenir. Listelenen her senkronizasyon bağdaştırıcısı, cihazdaki farklı bir içerik sağlayıcıyla senkronize edilir.

Çoğu hizmet, kullanıcıların verilere erişmeden önce kimliklerini doğrulamasını gerektirdiğinden Android sistemi, senkronizasyon bağdaştırıcısı çerçevesine benzer ve genellikle bu çerçeveyle birlikte kullanılan bir kimlik doğrulama çerçevesi sunar. Kimlik doğrulama çerçevesi, AbstractAccountAuthenticator sınıfının alt sınıfları olan eklenti kimlik doğrulayıcıları kullanır. Kimlik doğrulayıcı, kullanıcının kimliğini aşağıdaki adımlarda doğrular:

  1. Kullanıcının adını, şifresini veya benzer bilgilerini (kullanıcı kimlik bilgilerini) toplar.
  2. Kimlik bilgilerini hizmete gönderir
  3. Hizmetin yanıtını inceler.

Hizmet kimlik bilgilerini kabul ederse kimlik doğrulayıcı, kimlik bilgilerini daha sonra kullanmak için saklayabilir. Eklenti kimlik doğrulayıcı çerçevesi sayesinde AccountManager, bir kimlik doğrulayıcının desteklediği ve göstermeyi seçtiği tüm kimlik doğrulama jetonlarına (ör. OAuth2 kimlik doğrulama jetonları) erişim sağlayabilir.

Kimlik doğrulama gerekli olmasa da çoğu kişi hizmeti bunu kullanır. Ancak kimlik doğrulama yapmak için Android kimlik doğrulama çerçevesini kullanmanız gerekmez.

Senkronizasyon bağdaştırıcısı uygulaması

Kişiler Sağlayıcı için bir senkronizasyon bağdaştırıcısı uygulamak üzere, aşağıdakileri içeren bir Android uygulaması oluşturarak başlarsınız:

Sistemden gelen ve senkronizasyon bağdaştırıcısı ile bağlanma isteklerine yanıt veren bir Service bileşeni.
Sistem bir senkronizasyon çalıştırmak istediğinde, senkronizasyon bağdaştırıcısı için bir IBinder almak üzere hizmetin onBind() yöntemini çağırır. Bu sayede sistem, adaptörün yöntemlerine süreç arası çağrılar yapabilir.
AbstractThreadedSyncAdapter sınıfının somut bir alt sınıfı olarak uygulanan gerçek senkronizasyon adaptörü.
Bu sınıf, sunucudan veri indirme, cihazdan veri yükleme ve çakışmaları çözme işlemlerini yürütür. Adaptörün ana çalışması onPerformSync() yönteminde yapılır. Bu sınıf tekil olarak oluşturulmalıdır.
Application alt sınıfı.
Bu sınıf, senkronizasyon bağdaştırıcısı tekil nesnesi için bir fabrika görevi görür. Senkronizasyon bağdaştırıcısını örneklemek için onCreate() yöntemini kullanın ve tekil nesneyi senkronizasyon bağdaştırıcının hizmetinin onBind() yöntemine döndürmek için statik bir "alıcı" yöntemi sağlayın.
İsteğe bağlı: Sistemden gelen kullanıcı kimlik doğrulama isteklerine yanıt veren bir Service bileşeni.
AccountManager, kimlik doğrulama sürecini başlatmak için bu hizmeti başlatır. Hizmetin onCreate() yöntemi, bir kimlik doğrulayıcı nesnesi oluşturur. Sistem, uygulamanın senkronizasyon bağdaştırıcısı için bir kullanıcı hesabının kimliğini doğrulamak istediğinde, kimlik doğrulayıcı için IBinder almak üzere hizmetin onBind() yöntemini çağırır. Bu sayede sistem, kimlik doğrulayıcının yöntemlerine çapraz işlem çağrıları yapabilir.
İsteğe bağlı: Kimlik doğrulama isteklerini işleyen somut bir AbstractAccountAuthenticator alt sınıfı.
Bu sınıf, kullanıcının kimlik bilgilerini sunucuda doğrulamak için AccountManager tarafından çağrılan yöntemleri sağlar. Kimlik doğrulama işleminin ayrıntıları, kullanılan sunucu teknolojisine bağlı olarak büyük ölçüde değişiklik gösterir. Kimlik doğrulama hakkında daha fazla bilgi edinmek için sunucu yazılımınızın dokümanlarına göz atmanız gerekir.
Sistemde senkronizasyon bağdaştırıcısı ve kimlik doğrulayıcıyı tanımlayan XML dosyaları.
Daha önce açıklanan senkronizasyon bağdaştırıcısı ve kimlik doğrulayıcı hizmet bileşenleri, uygulama manifestindeki <service> öğelerinde tanımlanmıştır. Bu öğeler, sisteme belirli veriler sağlayan <meta-data> alt öğeleri içerir:
  • Senkronizasyon bağdaştırıcısı hizmeti için <meta-data> öğesi, res/xml/syncadapter.xml adlı XML dosyasını gösteriyor. Bu dosya da sırasıyla, Kişiler Sağlayıcı ile senkronize edilecek web hizmeti için bir URI ve web hizmeti için bir hesap türünü belirtir.
  • İsteğe bağlı: Kimlik doğrulayıcının <meta-data> öğesi, res/xml/authenticator.xml XML dosyasını gösterir. Buna karşılık bu dosya, bu kimlik doğrulayıcının desteklediği hesap türünü ve kimlik doğrulama işlemi sırasında görünen kullanıcı arayüzü kaynaklarını belirtir. Bu öğede belirtilen hesap türü, senkronizasyon bağdaştırıcısı için belirtilen hesap türüyle aynı olmalıdır.

Sosyal medya akışı verileri

android.provider.ContactsContract.StreamItems ve android.provider.ContactsContract.StreamItemPhotos tabloları, sosyal ağlardan gelen verileri yönetir. Kendi ağınızdan bu tablolara veri akışı ekleyen bir senkronizasyon bağdaştırıcısı yazabilir veya bu tablolardaki veri akışlarını okuyup kendi uygulamanızda görüntüleyebilir ya da ikisini birden yapabilirsiniz. Bu özellikler sayesinde sosyal ağ hizmetleriniz ve uygulamalarınız Android'in sosyal ağ deneyimine entegre edilebilir.

Sosyal medya akış metni

Akış öğeleri her zaman ham kişiyle ilişkilendirilir. android.provider.ContactsContract.StreamItemsSütunlar#RAW_CONTACT_ID, ham kişi için _ID değerine bağlantı verir. Ham kişinin hesap türü ve hesap adı da akış öğesi satırında depolanır.

Akışınızdaki verileri aşağıdaki sütunlarda depolayın:

android.provider.ContactsContract.StreamItemsColumns#ACCOUNT_TYPE
Zorunlu. Bu akış öğesiyle ilişkili ham kişi için kullanıcının hesap türü. Akış öğesi eklerken bu değeri ayarlamayı unutmayın.
android.provider.ContactsContract.StreamItemsColumns#ACCOUNT_NAME
Zorunlu. Bu akış öğesiyle ilişkili ham kişi için kullanıcının hesap adı. Bir yayın öğesi eklerken bu değeri ayarlamayı unutmayın.
Tanımlayıcı sütunları
Zorunlu. Akış öğesi eklerken aşağıdaki tanımlayıcı sütunlarını eklemeniz gerekir:
  • android.provider.ContactsContract.StreamItemsSütunlar#CONTACT_ID: Bu akış öğesinin ilişkilendirildiği kişinin android.provider.BaseSütunlar#_ID değeri.
  • android.provider.ContactsContract.StreamItemsColumns#CONTACT_LOOKUP_KEY: Bu akış öğesinin ilişkili olduğu kişinin android.provider.ContactsContract.ContactsColumns#LOOKUP_KEY değeri.
  • android.provider.ContactsContract.StreamItemsColumns#RAW_CONTACT_ID: Bu akış öğesinin ilişkili olduğu ham kişinin android.provider.BaseColumns#_ID değeri.
android.provider.ContactsContract.StreamItemsColumns#COMMENTS
İsteğe bağlı. Bir yayın öğesinin başında görüntüleyebileceğiniz özet bilgileri depolar.
android.provider.ContactsContract.StreamItemsColumns#TEXT
Akış öğesinin metni, öğenin kaynağı tarafından yayınlanan içerik veya akış öğesini oluşturan işlemin açıklaması. Bu sütunda, fromHtml() tarafından oluşturulabilen tüm biçimlendirmeler ve yerleşik kaynak resimleri bulunabilir. Sağlayıcı, uzun içerikleri kısaltabilir veya elips içine alabilir ancak etiketleri bölmekten kaçınmaya çalışır.
android.provider.ContactsContract.StreamItemsColumns#TIMESTAMP
Yayın öğesinin eklenme veya güncellenme zamanını içeren bir metin dizesi. Bu değer, başlangıç zamanından itibaren milisaniye cinsindendir. Akış öğeleri ekleyen veya güncelleyen uygulamalar bu sütunun bakımından sorumludur. Bu sütun, Kişi Sağlayıcı tarafından otomatik olarak korunmaz.

Akış öğelerinizle ilgili tanımlayıcı bilgileri görüntülemek için uygulamanızdaki kaynaklara bağlantı oluşturmak üzere android.provider.ContactsContract.StreamItemsColumns#RES_ICON, android.provider.ContactsContract.StreamItemsColumns#RES_LABEL ve android.provider.ContactsContract.StreamItemsColumns#RES_PACKAGE öğelerini kullanın.

android.provider.ContactsContract.StreamItems tablosu, senkronizasyon bağdaştırıcıların özel kullanımı için android.provider.ContactsContract.StreamItemsColumns#SYNC1 ile android.provider.ContactsContract.StreamItemsColumns#SYNC4 arasındaki sütunları da içerir.

Sosyal akış fotoğrafları

android.provider.ContactsContract.StreamItemPhotos tablosu, bir akış öğesiyle ilişkili fotoğrafları depolar. Tablonun android.provider.ContactsContract.StreamItemPhotosColumns#STREAM_ITEM_ID sütunu, android.provider.ContactsContract.StreamItems tablosunun _ID sütunundaki değerlere bağlantı verir. Fotoğraf referansları şu sütunlarda tabloda depolanır:

android.provider.ContactsContract.StreamItemPhotos#PHOTO sütunu (BLOB).
Fotoğrafın, depolama ve görüntüleme için sağlayıcı tarafından yeniden boyutlandırılmış ikili gösterimi. Bu sütun, fotoğrafları depolamak için kullanan Kişi Sağlayıcı'nın önceki sürümleriyle geriye dönük uyumluluk için kullanılabilir. Ancak mevcut sürümde fotoğraf depolamak için bu sütunu kullanmamanız gerekir. Bunun yerine, fotoğrafları bir dosyada depolamak için android.provider.ContactsContract.StreamItemPhotosColumns#PHOTO_FILE_ID veya android.provider.ContactsContract.StreamItemPhotosColumns#PHOTO_URI (her ikisi de aşağıdaki noktalarda açıklanmıştır) sütunlarını kullanın. Bu sütunda artık okunabilen bir küçük resim bulunuyor.
android.provider.ContactsContract.StreamItemPhotosColumn#PHOTO_FILE_ID
Ham bir kişi için fotoğrafın sayısal tanımlayıcısı. Tek bir fotoğraf dosyasını işaret eden bir içerik URI'si almak için bu değeri sabit değere DisplayPhoto.CONTENT_URI ekleyin ve ardından fotoğraf dosyasının adını almak için openAssetFileDescriptor() işlevini çağırın.
android.provider.ContactsContract.StreamItemPhotosColumns#PHOTO_URI
Bu satır tarafından temsil edilen fotoğrafın fotoğraf dosyasını doğrudan işaret eden bir içerik URI'si. Fotoğraf dosyasının adını almak için bu URI ile openAssetFileDescriptor() işlevini çağırın.

Sosyal akış tablolarını kullanma

Bu tablolar, aşağıdakiler dışında Kişi Sağlayıcı'daki diğer ana tablolarla aynı şekilde çalışır:

  • Bu tablolar için ek erişim izinleri gerekir. Bu kaynaklardan veri okumak için uygulamanızda android.Manifest.permission#READ_SOCIAL_STREAM izni olmalıdır. Bu verileri değiştirmek için uygulamanızda android.Manifest.permission#WRITE_SOCIAL_STREAM izni olmalıdır.
  • android.provider.ContactsContract.StreamItems tablosunda, her ham kişi için depolanan satır sayısı sınırlıdır. Bu sınıra ulaşıldığında, Kişiler Sağlayıcı, en eski android.provider.ContactsContract.StreamItemsColumns#TIMESTAMP değerine sahip satırları otomatik olarak silerek yeni akış öğesi satırlarına yer açar. Sınırı almak için android.provider.ContactsContract.StreamItems#CONTENT_LIMIT_URI içerik URI'sine sorgu gönderin. İçerik URI'si dışındaki tüm bağımsız değişkenleri null olarak ayarlayabilirsiniz. Sorgu, android.provider.ContactsContract.StreamItems#MAX_ITEMS tek sütunlu tek bir satır içeren bir imleç döndürür.

android.provider.ContactsContract.StreamItems.StreamItemPhotos sınıfı, tek bir akış öğesinin fotoğraf satırlarını içeren android.provider.ContactsContract.StreamItemPhotos alt tablosunu tanımlar.

Sosyal medya akışı etkileşimleri

Kişi Sağlayıcı tarafından yönetilen sosyal akış verileri, cihazın kişi uygulamasıyla birlikte sosyal ağ sisteminizi mevcut kişilerle bağlamanın güçlü bir yolunu sunar. Aşağıdaki özellikler kullanılabilir:

  • Bir senkronizasyon adaptörü kullanarak sosyal ağ hizmetinizi Kişiler Sağlayıcı ile senkronize ederek bir kullanıcının kişileriyle ilgili en son etkinlikleri alabilir ve daha sonra kullanmak üzere android.provider.ContactsContract.StreamItems ve android.provider.ContactsContract.StreamItemPhotos tablolarında depolayabilirsiniz.
  • Normal senkronizasyonun yanı sıra senkronizasyon bağdaştırıcınızı, kullanıcı görüntülemek için bir kişi seçtiğinde ek veriler alması için tetikleyebilirsiniz. Bu sayede senkronizasyon bağdaştırıcınız, ilgili kişi için yüksek çözünürlüklü fotoğrafları ve en son akış öğelerini alabilir.
  • Cihazın kişiler uygulamasına ve Kişiler Sağlayıcısına bildirim kaydederek bir kişi görüntülendiğinde intent alabilir ve bu noktada hizmetinizden kişinin durumunu güncelleyebilirsiniz. Bu yaklaşım, senkronizasyon adaptörüyle tam senkronizasyon yapmadan daha hızlı olabilir ve daha az bant genişliği kullanabilir.
  • Kullanıcılar, cihazın kişiler uygulamasında bir kişiye bakarken bu kişiyi sosyal ağ hizmetinize ekleyebilir. Bu özelliği, "kişiyi davet et" özelliğiyle etkinleştirirsiniz. Bu özelliği, mevcut bir kişiyi ağınıza ekleyen bir etkinliğin yanı sıra cihazın kişi uygulamasına ve Kişi Sağlayıcı'ya uygulamanızın ayrıntılarını sağlayan bir XML dosyasıyla etkinleştirirsiniz.

Akış öğelerinin Kişi Sağlayıcı ile düzenli senkronizasyonu, diğer senkronizasyonlarla aynıdır. Senkronizasyon hakkında daha fazla bilgi edinmek için Kişi Sağlayıcı senkronizasyon bağdaştırıcılar bölümüne bakın. Bildirimleri kaydetme ve kişileri davet etme konuları sonraki iki bölümde ele alınmaktadır.

Sosyal ağ görüntülemelerini işlemek için kaydolun

Kullanıcı, senkronizasyon bağdaştırıcınız tarafından yönetilen bir kişiyi görüntülediğinde bildirim almak için senkronizasyon bağdaştırıcınızı kaydetme:

  1. Projenizin res/xml/ dizininde contacts.xml adlı bir dosya oluşturun. Bu dosyayı zaten yüklediyseniz bu adımı atlayabilirsiniz.
  2. Bu dosyaya <ContactsAccountType xmlns:android="http://schemas.android.com/apk/res/android"> öğesini ekleyin. Bu öğe zaten mevcutsa bu adımı atlayabilirsiniz.
  3. Kullanıcı cihazın kişiler uygulamasında bir kişinin ayrıntılar sayfasını açtığında bilgilendirilen bir hizmet kaydetmek için öğeye viewContactNotifyService="serviceclass" özelliğini ekleyin. Burada serviceclass, cihazın kişiler uygulamasından intent'i alması gereken hizmetin tam nitelikli sınıf adıdır. Bildirim hizmeti için, hizmetin intent almasına izin vermek amacıyla IntentService sınıfını genişleten bir sınıf kullanın. Gelen niyetteki veriler, kullanıcının tıkladığı ham kişinin içerik URI'sini içerir. Bildirim hizmeti üzerinden, ham kişinin verilerini güncellemek için senkronizasyon bağdaştırıcınızı bağlayabilir ve ardından çağırabilirsiniz.

Kullanıcı bir yayın öğesini, fotoğrafı veya her ikisini birden tıkladığında çağrılacak bir etkinlik kaydetmek için:

  1. Projenizin res/xml/ dizininde contacts.xml adlı bir dosya oluşturun. Bu dosyaya zaten sahipseniz bu adımı atlayabilirsiniz.
  2. Bu dosyaya <ContactsAccountType xmlns:android="http://schemas.android.com/apk/res/android"> öğesini ekleyin. Bu öğe zaten mevcutsa bu adımı atlayabilirsiniz.
  3. Kullanıcının cihazın kişiler uygulamasında bir akış öğesini tıklamasını sağlamak amacıyla etkinliklerinizden birini öğeye viewStreamItemActivity="activityclass" özelliğini ekleyin. Burada activityclass, cihazın kişiler uygulamasından amacı alması gereken etkinliğin tam nitelikli sınıf adıdır.
  4. Kullanıcının cihazın kişiler uygulamasında bir akış fotoğrafını tıklamasını işlemesi için etkinliklerinizden birini kaydettirmek isterseniz öğeye viewStreamItemPhotoActivity="activityclass" özelliğini ekleyin. Bu durumda, activityclass, cihazın kişiler uygulamasından intent'i alması gereken etkinliğin tam nitelikli sınıf adıdır.

<ContactsAccountType> öğesi, <ContactsAccountType> öğesi bölümünde daha ayrıntılı olarak açıklanmıştır.

Gelen intent, kullanıcının tıkladığı öğenin veya fotoğrafın içerik URI'sini içerir. Metin öğeleri ve fotoğraflar için farklı etkinliklere sahip olmak istiyorsanız her iki özelliği aynı dosyada kullanın.

Sosyal ağ hizmetinizle etkileşimde bulunma

Kullanıcıların, kişileri sosyal ağ sitenize davet etmek için cihazın kişiler uygulamasından çıkmaları gerekmez. Bunun yerine, cihazın kişiler uygulamasının kişiyi etkinliklerinizden birine davet etmek için intent göndermesini sağlayabilirsiniz. Bunu ayarlamak için:

  1. Projenizin res/xml/ dizininde contacts.xml adlı bir dosya oluşturun. Bu dosyaya zaten sahipseniz bu adımı atlayabilirsiniz.
  2. Bu dosyaya <ContactsAccountType xmlns:android="http://schemas.android.com/apk/res/android"> öğesini ekleyin. Bu öğe zaten mevcutsa bu adımı atlayabilirsiniz.
  3. Aşağıdaki özellikleri ekleyin:
    • inviteContactActivity="activityclass"
    • inviteContactActionLabel="@string/invite_action_label"
    activityclass değeri, amacı alması gereken etkinliğin tam nitelikli sınıf adıdır. invite_action_label değeri, cihazın kişiler uygulamasındaki Bağlantı Ekle menüsünde görüntülenen bir metin dizesidir.

Not: ContactsSource, ContactsAccountType için kullanımdan kaldırılmış bir etiket adıdır.

contacts.xml referansı

contacts.xml dosyası, senkronizasyon bağdaştırıcınızın ve uygulamanızın kişiler uygulaması ve Kişiler Sağlayıcı ile etkileşimini kontrol eden XML öğelerini içerir. Bu öğeler aşağıdaki bölümlerde açıklanmıştır.

<ContactsAccountType> öğesi

<ContactsAccountType> öğesi, uygulamanızın kişiler uygulamasıyla etkileşimini kontrol eder. Şu söz dizimine sahiptir:

<ContactsAccountType
        xmlns:android="http://schemas.android.com/apk/res/android"
        inviteContactActivity="activity_name"
        inviteContactActionLabel="invite_command_text"
        viewContactNotifyService="view_notify_service"
        viewGroupActivity="group_view_activity"
        viewGroupActionLabel="group_action_text"
        viewStreamItemActivity="viewstream_activity_name"
        viewStreamItemPhotoActivity="viewphotostream_activity_name">

şunlardır:

res/xml/contacts.xml

şunları içerebilir:

<ContactsDataKind>

Açıklama:

Kullanıcıların kişilerinden birini sosyal ağa davet etmesine, sosyal ağ akışlarından biri güncellendiğinde kullanıcıları bilgilendirmesine vb. olanak tanıyan Android bileşenlerini ve kullanıcı arayüzü etiketlerini tanımlar.

<ContactsAccountType> özelliğinin ön eklerinin android: olması gerekmez.

Özellikler:

inviteContactActivity
Kullanıcı, cihazın kişiler uygulamasından Bağlantı ekle'yi seçtiğinde uygulamanızda etkinleştirmek istediğiniz etkinliğin tam nitelikli sınıf adı.
inviteContactActionLabel
Bağlantı ekle menüsündeki inviteContactActivity ile belirtilen etkinlik için görüntülenen metin dizesi. Örneğin, "Ağımda takip et" dizesini kullanabilirsiniz. Bu etiket için dize kaynak tanımlayıcısı kullanabilirsiniz.
viewContactNotifyService
Kullanıcı bir kişiyi görüntülediğinde bildirim alması gereken, uygulamanızdaki bir hizmetin tam nitelikli sınıf adı. Bu bildirim, cihazın kişiler uygulaması tarafından gönderilir ve uygulamanızın, veri yoğun işlemlerini gerektiğinde kadar ertelemesine olanak tanır. Örneğin, uygulamanız bu bildirime yanıt olarak kişinin yüksek çözünürlüklü fotoğrafını ve en son sosyal medya akışı öğelerini okuyup görüntüleyebilir. Bu özellik, Sosyal medya akışı etkileşimleri bölümünde daha ayrıntılı olarak açıklanmıştır.
viewGroupActivity
Uygulamanızda grup bilgilerini görüntüleyebilen bir etkinliğin tam sınıf adıdır. Kullanıcı, cihazın Kişiler uygulamasında grup etiketini tıkladığında bu etkinliğin kullanıcı arayüzü gösterilir.
viewGroupActionLabel
Kullanıcının uygulamanızdaki gruplara bakmasına olanak tanıyan bir kullanıcı arayüzü denetimi için kişiler uygulamasının gösterdiği etiket.

Bu özellik için dize kaynak tanımlayıcısı kullanılabilir.

viewStreamItemActivity
Kullanıcı ham kişi için bir akış öğesini tıkladığında cihazın kişiler uygulamasının başlattığı, uygulamanızda bir etkinliğin tam sınıf adı.
viewStreamItemPhotoActivity
Uygulamanızdaki, kullanıcı ham bir kişi için akış öğesindeki bir fotoğrafı tıkladığında cihazın kişi uygulamasının başlattığı etkinliğin tam nitelikli sınıf adı.

<ContactsDataKind> öğesi

<ContactsDataKind> öğesi, uygulamanızın özel veri satırlarının kişiler uygulamasının kullanıcı arayüzünde gösterilmesini kontrol eder. Şu söz dizimine sahiptir:

<ContactsDataKind
        android:mimeType="MIMEtype"
        android:icon="icon_resources"
        android:summaryColumn="column_name"
        android:detailColumn="column_name">

Şu ürünlerde bulunur:

<ContactsAccountType>

Açıklama:

Kişiler uygulamasının, ham bir kişinin ayrıntılarının bir parçası olarak özel veri satırının içeriğini göstermesi için bu öğeyi kullanın. <ContactsAccountType> öğesinin her <ContactsDataKind> alt öğesi, senkronizasyon bağdaştırıcınızın ContactsContract.Data tablosuna eklediği bir özel veri satırı türünü temsil eder. Kullandığınız her özel MIME türü için bir <ContactsDataKind> öğesi ekleyin. Verilerini görüntülemek istemediğiniz özel bir veri satırınız varsa öğeyi eklemeniz gerekmez.

Özellikler:

android:mimeType
ContactsContract.Data tablosundaki özel veri satırı türlerinizden biri için tanımladığınız özel MIME türü. Örneğin, vnd.android.cursor.item/vnd.example.locationstatus değeri, bir kişinin bilinen son konumunu kaydeden bir veri satırı için özel bir MIME türü olabilir.
android:icon
Kişiler uygulamasının verilerinizin yanında gösterdiği bir Android drawable kaynağı Kullanıcıya verilerin hizmetinizden geldiğini belirtmek için bu seçeneği kullanın.
android:summaryColumn
Veri satırından alınan iki değerden ilkinin sütun adı. Değer, bu veri satırının girişinin ilk satırı olarak gösterilir. İlk satır, verilerin bir özeti olarak kullanılmak üzere tasarlanmıştır ancak isteğe bağlıdır. Ayrıca android:detailColumn özelliğine de bakın.
android:detailColumn
Veri satırından alınan iki değerden ikincisinin sütun adı. Değer, bu veri satırının girişinin ikinci satırı olarak gösterilir. Ayrıca android:summaryColumn sayfasını da inceleyin.

Diğer Kişi Sağlayıcı özellikleri

Kişi Sağlayıcı, önceki bölümlerde açıklanan temel özelliklerin yanı sıra, kişi verileriyle çalışmak için şu faydalı özellikleri sunar:

  • Kişi grupları
  • Fotoğraf özellikleri

Kişi grupları

Kişi Sağlayıcı, isteğe bağlı olarak ilgili kişi koleksiyonlarını grup verileriyle etiketleyebilir. Bir kullanıcı hesabıyla ilişkili sunucu grupları korumak istiyorsa hesabın hesap türüne ait senkronizasyon bağdaştırıcısı, grup verilerini Kişiler Sağlayıcı ile sunucu arasında aktarmalıdır. Kullanıcılar sunucuya yeni bir kişi ekleyip bu kişiyi yeni bir gruba eklediğinde senkronizasyon bağdaştırıcısı yeni grubu ContactsContract.Groups tablosuna eklemelidir. Ham bir kişinin ait olduğu grup veya gruplar, ContactsContract.CommonDataKinds.GroupMembership MIME türü kullanılarak ContactsContract.Data tablosunda depolanır.

Sunucudan Kişiler Sağlayıcı'ya ham kişi verileri ekleyecek bir senkronizasyon bağdaştırıcısı tasarlıyorsanız ve grup kullanmıyorsanız sağlayıcıya verilerinizi görünür hale getirmesini söylemeniz gerekir. Kullanıcı cihaza hesap eklediğinde çalıştırılan kodda, Kişi Sağlayıcı'nın hesap için eklediği ContactsContract.Settings satırını güncelleyin. Bu satırda Settings.UNGROUPED_VISIBLE sütununun değerini 1 olarak ayarlayın. Bunu yaptığınızda, Kişiler Sağlayıcı, grup kullanmasanız bile kişi verilerinizi her zaman görünür yapar.

Kişi fotoğrafları

ContactsContract.Data tablosu, fotoğrafları Photo.CONTENT_ITEM_TYPE MIME türüyle satır olarak depolar. Satırın CONTACT_ID sütunu, ait olduğu ham kişinin _ID sütununa bağlıdır. ContactsContract.Contacts.Photo sınıfı, bir kişinin birincil fotoğrafı (kişinin birincil ham kişisinin birincil fotoğrafı) için fotoğraf bilgilerini içeren ContactsContract.Contacts alt tablosunu tanımlar. Benzer şekilde, ContactsContract.RawContacts.DisplayPhoto sınıfı, ham bir kişinin birincil fotoğrafının fotoğraf bilgilerini içeren ContactsContract.RawContacts alt tablosunu tanımlar.

ContactsContract.Contacts.Photo ve ContactsContract.RawContacts.DisplayPhoto referans belgeleri, fotoğraf bilgilerinin alınmasıyla ilgili örnekler içerir. Ham bir kişinin birincil küçük resmini almak için kolaylık sınıfı yoktur ancak ham kişinin birincil fotoğraf satırını bulmak için ham kişinin _ID, Photo.CONTENT_ITEM_TYPE ve IS_PRIMARY sütununu seçerek ContactsContract.Data tablosuna sorgu gönderebilirsiniz.

Bir kullanıcının sosyal medya akışıyla ilgili verileri fotoğrafları da içerebilir. Bunlar, Sosyal akış fotoğrafları bölümünde daha ayrıntılı olarak açıklanan android.provider.ContactsContract.StreamItemPhotos tablosunda depolanır.