Contacts Provider

Kişi Sağlayıcısı, cihazın insanlarla ilgili merkezi veri havuzunu yöneten esnek ve güçlü bir Android bileşenidir. Kişi Sağlayıcı, cihazın kişiler uygulamasında gördüğünüz verilerin kaynağıdır. Ayrıca kendi uygulamanızdan da verilere erişebilir ve cihaz ile online hizmetler arasında veri aktarabilirsiniz. Sağlayıcı çok çeşitli veri kaynaklarını barındırır ve her bir kişi için mümkün olduğunca fazla veri yönetmeye çalışır. Bu da organizasyonu karmaşık hale getirir. Bu nedenle sağlayıcının API'si, hem veri almayı hem de değiştirmeyi kolaylaştıran çok çeşitli sözleşme sınıfları ve arayüzler 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 veriler nasıl değiştirilir?
  • Sunucunuzdaki verileri Kişi 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 bilgilere sahip olduğunuz 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şi Sağlayıcı, bir Android içerik sağlayıcı bileşenidir. Bu özellik, Şekil 1'de gösterildiği gibi, bir kişiyle ilgili üç tür veri sağlar. Bunların her biri, sağlayıcı tarafından sunulan bir tabloya karşılık gelir:

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

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

ContactsContract.Contacts tablo
İşlenmemiş kişi satırlarının toplamlarına göre farklı kişileri temsil eden satırlar.
ContactsContract.RawContacts tablo
Kullanıcı verilerinin, kullanıcı hesabı ve türüne özel özetini içeren satırlar.
ContactsContract.Data tablo
İşlenmemiş iletişimle ilgili e-posta adresleri veya telefon numaraları gibi ayrıntıları içeren satırlar.

ContactsContract içinde sözleşmeli sınıflarla 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ında belirli işlevleri desteklemek için kullandığı yardımcı tablolardır.

Ham kişiler

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

Ham bir kişiye ait verilerin çoğu ContactsContract.RawContacts tablosunda depolanmaz. Bunun yerine, ContactsContract.Data tablosunda bir veya daha fazla satırda depolanı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 1. tabloda listelenmiştir. Lütfen tablodan sonra gelen notları okuyun:

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

Sütun adı Kullanım Notlar
ACCOUNT_NAME Bu ham ilgili kişinin kaynağı olan hesap türünün hesap adı. Örneğin, bir Google hesabının hesap adı, cihaz sahibinin Gmail adreslerinden biridir. Daha fazla bilgi için ACCOUNT_TYPE ile ilgili bir sonraki girişe bakın. Bu adın biçimi, hesap türüne özgüdür. Bu her zaman bir e-posta adresi değildir.
ACCOUNT_TYPE Bu ham kişinin kaynağı olan hesap türü. Örneğin, Google hesabı com.google şeklinde olabilir. Hesap türünüzü daima sahibi olduğunuz veya kontrol ettiğiniz bir alanın alan tanımlayıcısıyla nitelendirin. Böylece hesap türünüzün benzersiz olması sağlanır. Kişi verilerini sunan bir hesap türü, genellikle Kişi Sağlayıcı ile senkronize edilen ilişkili bir senkronizasyon bağdaştırıcısına sahiptir.
DELETED Ham kişi için "silindi" işareti. Bu işaret, Kişiler Sağlayıcı'nın, senkronizasyon bağdaştırıcıları satırı kendi sunucularından silene ve son olarak da satırı depodan silene kadar satırı dahili olarak korumasına olanak tanır.

Notlar

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

  • Ham kişinin adı, ContactsContract.RawContacts ürününde kendi satırında depolanmaz. Bunun yerine, ContactsContract.Data tablosunda, ContactsContract.CommonDataKinds.StructuredName satırında depolanır. Ham bir kişinin ContactsContract.Data tablosunda bu türde yalnızca bir satırı vardır.
  • Dikkat: Bir ham kişi satırında kendi hesap verilerinizi kullanmak için bu verilerin öncelikle AccountManager'a kayıtlı olması gerekir. Bunun 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ıyla web tabanlı hizmetinizin kişi verilerini saklamasını istiyorsanız ve kullanıcının hizmetinize ilişkin hesabı becky.sharp@dataservice.example.com ise uygulamanızın ham kişi satırları ekleyebilmesi için önce hesap "tür" (com.example.dataservice) ve hesap "adı" (becky.smart@dataservice.example.com) değerlerini eklemesi gerekir. Bu şartı dokümanlarda kullanıcıya açıklayabilir veya kullanıcıdan türü ve adı ya da her 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 verisi kaynakları

Ham kişilerin işleyiş şeklini anlamak için cihazında aşağıdaki üç kullanıcı hesabı tanımlanmış olan "Emel Dinçer" adlı kullanıcıyı düşünün:

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

Bu kullanıcı, Hesaplar ayarlarında bu hesapların üçü için 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çtığını ve "Thomas Higginson" ifadesini eklediğini varsayalım. Daha sonra emilyd@gmail.com olarak Gmail'de oturum açar ve "Thomas Higginson"a bir e-posta gönderir. Bu e-posta, kullanıcıyı otomatik olarak kişi olarak ekler. Ayrıca Twitter'da "colonel_tom"u (Thomas Higginson'ın Twitter kimliği) takip ediyor.

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

  1. emily.dickinson@gmail.com ile ilişkili "Thomas Higginson" için ham kişi. Kullanıcı hesabının türü Google'dır.
  2. emilyd@gmail.com ile ilişkili "Thomas Higginson" için ikinci ham iletişim. Kullanıcı hesabının türü de Google'dır. Ad, önceki adla aynı olsa bile ikinci bir ham kişi daha bulunur. Bunun nedeni, söz konusu kişi farklı bir kullanıcı hesabı için eklenmiş olmasıdır.
  3. "Thomas Higginson" için "belle_of_amherst" ile ilişkili üçüncü ham temas. 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ı bir ContactsContract.Data satırında depolanır. Bu, tek bir ham kişinin e-posta adresi veya telefon numarası gibi aynı türden birden fazla veri örneğini kullanmasına olanak tanır. Örneğin, emilyd@gmail.com için "Thomas Higginson" (emilyd@gmail.com Google Hesabı ile ilişkili Thomas Higginson'ın ham iletişim satırı) ev e-posta adresi thigg@gmail.com ve iş e-posta adresi thomas.higginson@gmail.com ise Kişi Sağlayıcı iki e-posta adresi satırını depolar ve ikisini de ham kişiye bağlar.

Bu tek tabloda farklı türde verilerin depolandığına dikkat edin. 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. Bunu yönetmeye yardımcı olmak için ContactsContract.Data tablosunda açıklayıcı adlara sahip bazı sütunlar, genel ada sahip bazı sütunlar bulunur. Açıklayıcı ad sütununun içeriği, satırdaki verinin türünden bağımsız olarak aynı anlama sahipken genel ad sütununun içeriği, veri türüne bağlı olarak farklı anlamlara sahiptir.

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

Açıklayıcı sütun adlarına bazı örnekler:

RAW_CONTACT_ID
Bu veriler için ham ilgili kişinin _ID sütununun değeri.
MIMETYPE
Bu satırda depolanan veri türü (Özel MIME türü olarak belirtilir). 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 kaynaklıdır ve Kişi Sağlayıcı ile çalışan herhangi bir uygulama veya senkronizasyon bağdaştırıcısı tarafından kullanılabilir.
IS_PRIMARY
Bu tür veri satırı bir ham kişi için birden fazla kez gerçekleşebilirse IS_PRIMARY sütunu, bu türe ait birincil verileri içeren veri satırını işaretler. Örneğin, kullanıcı, bir kişi için 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ılabilir olan DATA1-DATA15 adlı 15 genel sütun ve yalnızca senkronizasyon bağdaştırıcıları tarafından kullanılması gereken dört genel sütun SYNC1-SYNC4 vardır. Genel sütun adı sabitleri, satırın içerdiği veri türünden bağımsız olarak her zaman çalışır.

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

Genel olarak DATA15 sütunu, fotoğraf küçük resimleri gibi İkili Büyük Nesne (BLOB) verilerini depolamak için ayrılmıştır.

Türe özel sütun adları

Kişi Sağlayıcısı, belirli bir satır türünün sütunlarıyla çalışmayı kolaylaştırmak için ContactsContract.CommonDataKinds alt sınıflarında tanımlanan türe özel sütun adı sabitleri de sağlar. Sabit değerler, 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ı, Email.CONTENT_ITEM_TYPE MIME türüne sahip bir ContactsContract.Data satırı için türe özel sütun adı sabitlerini tanımlar. Sınıfta, e-posta adresi sütunu için ADDRESS sabit değeri bulunur. ADDRESS öğesinin gerçek değeri, sütunun genel adıyla aynı olan "data1"dir.

Dikkat: ContactsContract.Data tablosuna, sağlayıcının önceden tanımlanmış MIME türlerinden birini içeren bir satırı kullanarak kendi özel verilerinizi eklemeyin. Aksi takdirde verileri kaybedebilir veya sağlayıcının bozulmasına neden olabilirsiniz. Örneğin, DATA1 sütununa, 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 kendi türe özel sütun adlarınızı tanımlayabilir ve bu sütunları istediğiniz gibi kullanabilirsiniz.

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

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

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

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

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

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

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

Kişiler

Kişi Sağlayıcısı, 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 toplanmasını yönetir. Ne uygulamaların ne de senkronizasyon bağdaştırıcılarının kişi eklemesine izin verilmez ve kişi satırındaki bazı sütunlar salt okunur özelliktedir.

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

Kişi Sağlayıcı, mevcut kişilerle eşleşmeyen yeni bir ham kişi eklenmesine yanıt olarak yeni bir kişi oluşturur. Sağlayıcı ayrıca bunu, mevcut bir ham kişinin verilerinde daha önce ekli olduğu kişiyle eşleşmeyecek şekilde değişmesi durumunda da 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 toplanır.

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

ContactsContract.Contacts tablosunda, kişi satırı için "kalıcı" bir bağlantı olan LOOKUP_KEY sütunu da bulunur. Kişi Sağlayıcısı kişileri otomatik olarak koruduğundan, toplama veya senkronizasyona yanıt olarak kişi satırının _ID değerini değiştirebilir. Böyle bir durumda bile, CONTENT_LOOKUP_URI içerik URI'sı (kişinin LOOKUP_KEY) ile birlikte yine kişi satırını işaret eder. Böylece, "favori" kişilerine bağlantı vermek için LOOKUP_KEY kullanabilirsiniz. Bu sütunun, _ID sütununun biçimiyle ilgili olmayan kendi biçimi vardır.

Şekil 3, üç ana tablonun birbiriyle ilişkisini göstermektedir.

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

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

Dikkat: Uygulamanızı Google Play Store'da yayınlarsanız veya uygulamanız Android 10 (API düzeyi 29) ya da sonraki sürümleri çalıştıran bir cihazdaysa sınırlı sayıda kişi verisi alanları ve yöntemlerinin eski olduğunu unutmayın.

Belirtilen koşullar altında, sistem şu veri alanlarına yazılan tüm değerleri düzenli olarak siler:

Yukarıdaki veri alanlarını ayarlamak için kullanılan API'ler de eskidir:

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

Uygulamalarınız bu alanlara veya API'lere erişiyor 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şlevlerinin bu değişiklikten etkilenmediğini doğrulamak için bu veri alanlarını manuel olarak temizleyebilirsiniz. Bunun 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 adaptörlerinden alınan veriler

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

Android'de, bir senkronizasyon bağdaştırıcısının çalıştığı web hizmeti bir hesap türüne göre tanımlanır. Her senkronizasyon bağdaştırıcısı bir hesap türüyle çalışır ancak söz konusu 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çıklanmıştır. Aşağıdaki tanımlarda daha ayrıntılı bilgi sunulmakta ve hesap türü ile adın senkronizasyon bağdaştırıcıları ve hizmetleri ile ilişkisi açıklanmaktadır.

Hesap türü
Kullanıcının veri depoladığı bir hizmeti tanımlar. Çoğu zaman kullanıcının hizmette kimlik doğrulaması yapması 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ı
Belirli bir hesabı veya bir hesap türü için girişi tanımlar. Google Kişiler hesapları, hesap adı olarak bir e-posta adresine sahip olan Google hesaplarıyla aynıdır. Diğer hizmetler tek kelimelik bir kullanıcı adı veya sayısal kimlik kullanabilir.

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

Hizmetinizin verilerini Kişi 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ı" kutusunda, her bağdaştırıcı kendi hesap türüne göre etiketlenir.

Kişilerle ilgili veri akışı

4. Şekil. Kişi Sağlayıcı veri akışı.

Gerekli izinler

Kişi Sağlayıcı'ya erişmek isteyen uygulamalar aşağıdaki izinleri istemelidir:

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

Bu izinler kullanıcı profili verilerini kapsamaz. Kullanıcı profili ve gerekli izinler, 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 gizlilikleri konusunda endişeli olduğundan uygulamaların kendileri veya kişileri hakkında veri toplamasını istemezler. Kişiler verilerine erişmek için neden izin almanız gerektiği açık değilse, bu kişiler uygulamanıza düşük puan verebilir veya uygulamayı yüklemeyi reddedebilirler.

Kullanıcı profili

ContactsContract.Contacts tablosunda, cihaz kullanıcısının profil verilerini içeren tek bir satır bulunur. Bu veriler, kullanıcının kişilerinden biri yerine cihazın user bilgilerini tanımlar. Profil kişileri satırı, profil kullanan her sistem için ham kişiler satırına bağlanır. Her profil ham kişi satırında birden çok veri satırı olabilir. Kullanıcı profiline erişimle ilgili sabitler, ContactsContract.Profile sınıfında mevcuttur.

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

Bir kullanıcının profilinin hassas olarak kabul edilmesi gerektiğini unutmayın. android.Manifest.permission#READ_PROFILE izni, cihaz kullanıcısının kimliğini tanımlayan verilere erişmenizi sağlar. Uygulamanızın açıklamasında, kullanıcıya neden kullanıcı profili erişim izinlerine ihtiyacınız olduğunu söylemeyi unutmayın.

Kullanıcının profilini içeren kişi satırını almak için ContentResolver.query() numaralı telefonu arayın. İçerik URI'sini CONTENT_URI olarak ayarlayın ve herhangi bir seçim kriteri sağlamayın. 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 profile ait 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 çok kişi satırı alırsanı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ı, depodaki kişi verilerinin durumunu izleyen verileri yönetir. Depoyla ilgili bu meta veriler; Ham Kişiler, Veriler ve Kişiler tablo 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şi Sağlayıcıdaki meta veriler

Tablo Sütun Değerler Anlamı
ContactsContract.RawContacts DIRTY "0": Son senkronizasyondan sonra değişmemiştir. Cihazda değiştirilen ve sunucuyla tekrar senkronize edilmesi gereken ham kişileri işaretler. Android uygulamaları bir satırı güncellediğinde değer, Kişi 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 işlem, sağlayıcının satırları kirli olarak işaretlemesini engeller. Aksi takdirde, senkronizasyon bağdaştırıcısı değişiklikleri yerel değişiklikler gibi görünür ve sunucu değişikliğin kaynağı olsa bile sunucuya gönderilir.

"1" - Son senkronizasyondan bu yana değişti, tekrar sunucuyla senkronize edilmesi gerekiyor.
ContactsContract.RawContacts VERSION Bu satırın sürüm numarası. Kişi Sağlayıcı, satır veya ilgili veriler 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ı her değiştirildiğinde bu değeri otomatik olarak artırır.
ContactsContract.RawContacts SOURCE_ID Bu ham kişiyi, oluşturulduğu hesapla benzersiz şekilde tanımlayan bir dize değeri. 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, uygulamanın bu sütunu boş bırakması gerekir. Bu, senkronizasyon bağdaştırıcısına sunucuda yeni bir ham kişi oluşturması ve SOURCE_ID için bir değer alması gerektiğini bildirir.

Özellikle, kaynak kimliğinin her hesap türü için benzersiz olması ve senkronizasyonlarda da kararlı olması gerekir:

  • Benzersiz: Bir hesap için her ham ilgili kişinin kendi kaynak kimliği olmalıdır. Bunu zorunlu kılmazsanız kişiler uygulamasında sorunlara neden olursunuz. Aynı hesap türü için iki ham kişinin aynı kaynak kimliğine sahip olabileceğine dikkat edin. Örneğin, emily.dickinson@gmail.com hesabı için "Thomas Higginson" adlı ham kişinin, emilyd@gmail.com hesabının "Thomas Higginson" adlı ham kişisiyle aynı kaynak kimliğine sahip olmasına izin verilir.
  • Kararlı: Kaynak kimlikleri, ham kişi için online hizmet verilerinin kalıcı bir parçasıdır. Örneğin, kullanıcı Uygulamalar ayarlarından Kişiler Depolama Alanı'nı temizler ve yeniden senkronizasyon gerçekleştirirse geri yüklenen ham kişilerin önceki kimlikleriyle aynı kaynak kimliklerine sahip olması gerekir. Bu işlemi uygulamazsanız kısayollar çalışmayı durdurur.
ContactsContract.Groups GROUP_VISIBLE "0" - Bu gruptaki kişiler Android uygulaması kullanıcı arayüzlerinde görünür olmamalıdır. 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ünde, bir gruba ait olmayan kişiler Android uygulaması kullanıcı arayüzlerinde görünmez. Varsayılan olarak, ham kişilerinden hiçbiri bir gruba aitse kişiler görünmez (ham kişilerin 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 bu işareti ContactsContract.Settings tablo satırına ayarlayarak grubu olmayan kişilerin görünür olmasını sağlayabilirsiniz. Bu işaretin bir kullanımı, grup kullanmayan sunuculardaki kişilerin gösterilmesidir.
"1" - Uygulama kullanıcı arayüzleri, bu hesap ve hesap türünde bir gruba ait olmayan kişiler tarafından görülebilir.
ContactsContract.SyncState (tümü) Senkronizasyon bağdaştırıcınızın meta verilerini depolamak için bu tabloyu kullanın. Bu tablo sayesinde, senkronizasyon durumunu ve senkronizasyonla ilgili diğer verileri cihazda kalıcı olarak depolayabilirsiniz.

Kişi Sağlayıcı erişimi

Bu bölümde, Kişi Sağlayıcı'dan gelen verilere erişimle ilgili kurallar, aşağıdaki noktalara odaklanılarak açıklanmaktadır:

  • Varlık sorguları.
  • Toplu değişiklik.
  • Amaçlarla veri alma ve değiştirme.
  • Veri bütünlüğü.

Senkronizasyon bağdaştırıcısından değişiklik yapma konusu da Kişi 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ı bir hiyerarşide düzenlendiği için bir satırın ve ona bağlı tüm "alt" satırların alınması genellikle yararlıdır. Örneğin, bir kullanıcıyla ilgili tüm bilgileri 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şi Sağlayıcı, bunu kolaylaştırmak için tablolar arasında veritabanı birleştirmeleri gibi davranan entity yapıları sunar.

Varlık, bir üst tablo ve onun alt tablosundan seçili sütunlardan oluşan bir tablo gibidir. Bir varlığı sorguladığınızda, varlıkta bulunan sütunlara göre bir projeksiyon ve arama ölçütü sağlarsınız. Sonuç, alınan her alt tablo satırı için bir satır içeren bir Cursor olur. Örneğin, ContactsContract.Contacts.Entity adlı veride bir kişi adı ve bu addaki tüm ham kişiler 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 Cursor elde edersiniz.

Varlıklar, 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şi veya ham kişinin tüm kişi verilerini tek seferde alabilirsiniz. Ayrıca Kişi Sağlayıcısı, tek bir işlemdeki bir varlığa yönelik sorgu 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ı sabit değerleri listesinde yer almayan 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 işlenmemiş kişi satırlarının nasıl alınacağı gösterilmektedir. Snippet, "ana" ve "ayrıntı" olmak üzere iki etkinliği olan daha büyük bir uygulamanın parçasıdır. Ana etkinlikte kişi satırlarının listesi gösterilir. Kullanıcı bir satır seçdiğinde etkinlik, kimliğini ayrıntı etkinliğine gönderir. Ayrıntı etkinliği, seçilen kişiyle ilişkilendirilmiş tüm ham kişilerden gelen tüm veri satırlarını görüntülemek için ContactsContract.Contacts.Entity öğesini 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 bir geri çağırma ç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örüntülemek veya daha fazla çalışmak için bu Cursor cihazındaki verileri alabilirsiniz.

Toplu değişiklik

Mümkün olduğunda, ContentProviderOperation nesne içeren ArrayList oluşturup applyBatch() yöntemini çağırarak Kişi Sağlayıcı'daki verileri "toplu modda" eklemeniz, güncellemeniz ve silmeniz gerekir. Kişi Sağlayıcısı, bir applyBatch() içindeki tüm işlemleri tek bir işlemde gerçekleştirdiğinden değişiklikleriniz kişiler deposunu hiçbir zaman tutarsız bir durumda bırakmaz. Toplu değişiklik, ham bir kişinin ve ayrıntı verilerinin aynı anda eklenmesini de kolaylaştırır.

Not: Tek bir ham kişiyi değiştirmek için, değişikliği uygulamanızda gerçekleştirmek yerine cihazın kişiler uygulamasına niyet gönderebilirsiniz. Bu tür işlemler, Amaçlarla alma 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 toplu değişiklik, diğer işlemleri engelleyerek genel kullanıcı deneyimini olumsuz yönde etkileyebilir. Yapmak istediğiniz tüm değişiklikleri mümkün olduğunca az sayıda ayrı listede düzenlemek ve aynı zamanda bunların sistemi engellemelerini önlemek amacıyla bir veya daha fazla işlem için getiri noktaları ayarlamanız gerekir. Getiri noktası, isYieldAllowed() değeri true olarak ayarlanmış bir ContentProviderOperation nesnesidir. Kişi Sağlayıcı bir getiri noktasıyla karşılaştığında, diğer işlemlerin çalıştırılması için çalışmalarını duraklatır ve geçerli işlemi kapatır. Sağlayıcı tekrar başladığında, ArrayList içindeki bir sonraki işlemle devam eder ve yeni bir işlem başlatır.

Getiri puanları, applyBatch() için yapılan çağrı başına birden fazla işlemle sonuçlanır. Bu nedenle, ilgili satır kümesi için son işlem için bir getiri 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 ilgili satır kümesi için son işlem için bir getiri noktası ayarlamanız gerekir.

Çıkış noktaları aynı zamanda bir 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. Herhangi bir getiri noktası ayarlamazsanız en küçük atom işlemi, tüm işlem grubu olur. Getiri puanları kullandığınızda işlemlerin sistem performansının düşmesini önlerken bir işlem alt kümesinin atomik olmasını da sağlarsınız.

Değişiklik geri referansları

Yeni bir ham kişi satırını ve ilişkili veri satırlarını ContentProviderOperation nesne kümesi olarak eklerken ham kişinin _ID değerini RAW_CONTACT_ID değeri olarak ekleyerek veri satırlarını ham kişi satırına bağlamanız gerekir. Ancak ham kişi satırı için ContentProviderOperation özelliğini henüz uygulamadığınızdan bu değer, veri satırı için ContentProviderOperation oluştururken kullanılamaz. Bu sorunu çözmek için ContentProviderOperation.Builder sınıfı, withValueBackReference() yöntemini kullanır. Bu yöntem, önceki bir işlemin sonucunu içeren bir sütun eklemenize veya mevcut bir sütunu değiştirmenize olanak tanır.

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

key
Anahtar/değer çiftinin anahtarı. Bu bağımsız değişkenin değeri, değiştirdiğiniz tablodaki bir sütunun adı olmalıdır.
previousResult
applyBatch() aralığındaki ContentProviderResult nesne dizisindeki bir değerin 0 tabanlı dizini. Toplu işlemler uygulandıkça, her işlemin sonucu ara sonuç dizisinde depolanır. previousResult değeri, bu sonuçlardan birinin dizinidir. Bu dizin, key değeriyle alınır ve depolanır. Bu işlem, yeni bir ham kişi kaydı eklemenize ve bu kaydın _ID değerini geri almanıza, ardından ContactsContract.Data satırı eklediğinizde değere "geri başvuru" yapmanıza olanak tanır.

applyBatch() yöntemini ilk çağırdığınızda sonuç dizisinin tamamı, sağladığınız ContentProviderOperation nesnenin ArrayList boyutuna eşit bir boyutta oluşturulur. Bununla birlikte, sonuç dizisindeki tüm öğeler null olarak ayarlanır ve henüz uygulanmamış bir işlem için sonuca geri başvuruda bulunmaya çalışırsanız withValueBackReference() bir Exception döndürür.

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

İlk snippet, kişi verilerini kullanıcı arayüzünden alır. Bu noktada, kullanıcı yeni ham kişinin eklenmesi gereken 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 derleyici nesnesi, RAW_CONTACT_ID elde etmek için withValueBackReference() kullanır. Referans, ilk işlemdeki ContentProviderResult nesnesine geri döner. Bu nesne, ham kişi satırını ekler ve 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ına otomatik olarak bağlanır.

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

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, yeni ham kişi ve veri satırlarını ekleyen applyBatch() çağrısını gösterir.

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 kod deposunu kilitlemek zorunda kalmadan değişiklik işlemleri uygulama yöntemi olan iyimser eşzamanlılık kontrolü uygulamanıza da olanak tanır. Bu yöntemi kullanmak için işlemi uygularsınız ve ardından aynı anda yapılmış olabilecek diğer değişiklikleri kontrol edersiniz. Tutarsız bir değişiklik yapıldığını fark ederseniz işleminizi geri alıp yeniden denersiniz.

İyimser eşzamanlılık kontrolü, aynı anda yalnızca tek bir kullanıcının bulunduğu ve bir veri deposuna eş zamanlı erişimin nadir olduğu mobil cihazlar için kullanışlıdır. Kilitleme kullanılmadığı için kilit ayarlamak veya diğer işlemlerin kilitlerini açmasını beklemekle zaman kaybetmezsiniz.

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

  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 eklenmiş olarak RawContacts.CONTENT_URI kullanın.
  3. ContentProviderOperation.Builder nesnesi için withValue() yöntemini çağırarak VERSION sütununu az önce aldığınız sürüm numarasıyla karşılaştırın.
  4. Aynı ContentProviderOperation.Builder için withExpectedCount() çağrısı yaparak bu doğrulama ile yalnızca bir satırın test edildiğinden emin olun.
  5. ContentProviderOperation nesnesini oluşturmak için build() yöntemini çağırın, ardından bu nesneyi applyBatch() öğesine ilettiğiniz ArrayList içindeki ilk nesne olarak ekleyin.
  6. Toplu işlemi uygulayın.

Ham kişi satırı, satırı okumanız ile değiştirmeyi denediğiniz zaman arasında başka bir işlemle güncellenirse "iddia" ContentProviderOperation başarısız olur ve tüm işlem grubu yedeklenir. Daha sonra grubu yeniden deneyebilir veya başka bir işlem yapabilirsiniz.

Aşağıdaki snippet'te CursorLoader kullanarak tek bir ham kişi için sorgulama yaptıktan sonra "iddia" ContentProviderOperation oluşturma işleminin nasıl yapılacağı 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
    }

Amaçlarla alma ve değiştirme

Cihazın kişiler uygulamasına niyet göndermek, Kişi Sağlayıcı'ya dolaylı olarak erişmenize olanak tanır. Amaç, cihazın kişiler uygulaması kullanıcı arayüzünü başlatır. Kullanıcılar burada kişilerle ilgili işler yapabilir. Bu erişim türüyle kullanıcılar:

  • Listeden bir kişi seçip bu kişinin daha fazla çalışmak için uygulamanıza dönmesini sağlayın.
  • Mevcut bir kişinin verilerini düzenleyin.
  • Hesaplarından herhangi biri için yeni bir ham kişi ekleme.
  • Bir kişiyi veya kişi verilerini silin.

Kullanıcı veri ekliyor veya güncelliyorsa önce verileri toplayıp amacın bir parçası olarak gönderebilirsiniz.

Cihazın kişiler uygulaması üzerinden Kişi Sağlayıcı'ya erişmek için niyet kullandığınızda kendi kullanıcı arayüzünüzü veya sağlayıcıya erişim kodunu yazmanız gerekmez. Ayrıca, sağlayıcıya okuma veya yazma izni istemeniz gerekmez. Cihazın kişiler uygulaması, bir kişi için size okuma izni yetkisi verebilir ve sağlayıcıda başka bir uygulama üzerinden değişiklik yaptığınız için yazma izinlerinizin olması gerekmez.

Bir sağlayıcıya erişmek için amaç göndermeyle ilgili genel süreç, "Amaçlar aracılığıyla veri erişimi" bölümündeki İçerik Sağlayıcı ile ilgili temel bilgiler kılavuzunda 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 referans dokümanlarında listelenmiştir:

Tablo 4. Kişi Sağlayıcı Amaçları.

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'si türüne bağlı olarak, ham kişilerin listesini veya ham kişinin verilerinin listesini görüntüler.

Seçilen satırın içerik URI'sini döndüren startActivityForResult() işlevini çağırın. URI'nın biçimi, tablonun içerik URI'sidir ve satırın LOOKUP_ID sonuna eklenir. Cihazın kişiler uygulaması, etkinliğinizin süresi boyunca bu içerik URI'sine okuma ve yazma izinleri için yetki verir. Daha ayrıntılı bilgi için İçerik Sağlayıcı ile ilgili temel bilgiler kılavuzuna bakın.

Yeni ham kişi ekleme Insert.ACTION Yok RawContacts.CONTENT_TYPE, bir dizi ham kişi için MIME türü. Cihazın kişiler uygulamasının Kişi Ekle ekranını görüntüler. Amaca eklediğiniz ekstra değerler gösterilir. startActivityForResult() ile gönderilirse yeni eklenen ham kişinin içerik URI'sı, etkinliğinizin "veri" alanındaki Intent bağımsız değişkenindeki onActivityResult() geri çağırma yöntemine geri aktarılır. Değeri öğrenmek için getData() numaralı telefonu arayın.
Kişiyi düzenleme ACTION_EDIT Kişi için CONTENT_LOOKUP_URI. Düzenleyici etkinliği, kullanıcının bu kişiyle ilişkilendirilmiş tüm verileri düzenlemesine izin verir. Contacts.CONTENT_ITEM_TYPE, tek bir kişi. Kişiler uygulamasında Kişiyi Düzenle ekranını görüntüler. Amaca eklediğiniz ekstra değerler görüntülenir. Kullanıcı, düzenlemeleri kaydetmek için Bitti'yi tıkladığında etkinliğiniz ön plana döner.
Veri ekleyebilen bir seçici görüntüleyin. ACTION_INSERT_OR_EDIT Yok CONTENT_ITEM_TYPE Bu niyet, her zaman kişiler uygulamasının seçici ekranını gösterir. Kullanıcı, düzenlemek üzere bir kişi 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 amaçta ilettiğiniz ekstra veriler görüntülenir. Uygulamanızda e-posta veya telefon numarası gibi iletişim verileri gösteriliyorsa kullanıcının bu verileri mevcut bir kişiye eklemesine izin vermek için bu niyeti kullanın. kişi,

Not: Kullanıcı her zaman mevcut bir adı seçtiği veya yeni bir ad eklediği için bu amacın ekstra öğelerinde ad değeri göndermenize gerek yoktur. Ayrıca, bir ad gönderirseniz ve kullanıcı düzenleme yapmayı seçerse kişiler uygulaması gönderdiğiniz adı görüntüler ve önceki değerin üzerine yazar. Kullanıcı bunu fark etmez ve düzenlemeyi kaydederse eski değer kaybolur.

Cihazın kişiler uygulaması, ham bir kişiyi veya niyeti olan verilerini silmenize izin vermez. Bunun yerine, ham bir kişiyi silmek için ContentResolver.delete() veya ContentProviderOperation.newDelete() işlevini kullanın.

Aşağıdaki snippet'te yeni bir ham kişi 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 veriler içerdiğinden Kişi Sağlayıcısı, veri bütünlüğü için iyi tanımlanmış kurallar sunar. Kişi verilerini değiştirirken bu kurallara uymak sizin sorumluluğunuzdadır. Önemli kurallar burada 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 bir 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ğlayın.
ContactsContract.RawContacts ile bağlantılı olmayan ContactsContract.Data satırı, cihazın kişiler uygulamasında görünmez ve senkronizasyon adaptörleriyle ilgili sorunlara neden olabilir.
Yalnızca sahip olduğunuz ham kişilerin verilerini değiştirin.
Kişi Sağlayıcısının genellikle birkaç farklı hesap türünden/online hizmetten 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 sizin kontrol ettiğiniz bir hesap türü ve ada sahip veriler 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 özelliğinde ve alt sınıflarında tanımlanan sabitleri kullanın.
Bu sabit değerleri kullanmak, hataları önlemenize yardımcı olur. Ayrıca, sabit değerlerden herhangi birinin desteği sonlandırıldığında derleyici uyarılarıyla ilgili bildirim alırsınız.

Özel veri satırları

Kendi özel MIME türlerinizi oluşturup kullanarak ContactsContract.Data tablosunda kendi veri satırlarınızı ekleyebilir, düzenleyebilir, silebilir ve alabilirsiniz. Satırlarınız, ContactsContract.DataColumns politikasında tanımlanan sütunu kullanmayla sınırlıdır ancak kendi türe özel 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örüntülenir ancak bu veriler düzenlenemez veya silinemez ve kullanıcılar başka 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> öğesi ve en az bir <ContactsDataKind> alt öğesi içeren bir contacts.xml dosyası sağlayın. Bu konu, <ContactsDataKind> element bölümünde daha ayrıntılı olarak açıklanmaktadır.

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

Kişi Sağlayıcı senkronizasyon bağdaştırıcıları

Kişi Sağlayıcısı, bir cihaz ile çevrimiçi bir hizmet arasında kişi verilerinin senkronizasyonunu gerçekleştirmek için özel olarak tasarlanmıştır. Bu, kullanıcıların mevcut verileri yeni bir cihaza indirmelerine ve mevcut verileri yeni bir hesaba yüklemelerine olanak tanır. Senkronizasyon ayrıca kullanıcıların, ekleme ve değişikliklerin kaynağından bağımsız olarak en yeni verilere sahip olmalarını da sağlar. Senkronizasyonun bir başka avantajı da cihaz ağa bağlı olmasa bile kişi verilerinin kullanılabilir durumda olmasını sağlamasıdır.

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

  • Ağ kullanılabilirliği kontrol ediliyor.
  • Senkronizasyonun zamanlaması ve yürütülmesi, kullanıcı tercihlerine bağlıdır.
  • Duran senkronizasyonlar yeniden başlatılıyor.

Bu çerçeveyi kullanmak için bir senkronizasyon bağdaştırıcısı eklentisi sağlamanız gerekir. Her senkronizasyon bağdaştırıcısı bir hizmet 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ına da izin verir.

Bağdaştırıcı sınıflarını ve dosyalarını senkronize etme

Bir senkronizasyon bağdaştırıcısını AbstractThreadedSyncAdapter sınıfının 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ını uygulama manifestinizdeki öğelerden ve manifest dosyasının işaret ettiği özel bir XML dosyasından öğrenir. XML dosyası, online hizmetin hesap türünü ve içerik sağlayıcı yetkilisini tanımlar. Bunlar birlikte bağdaştırıcıyı benzersiz şekilde tanımlar. Kullanıcı, senkronizasyon bağdaştırıcısının hesap türü için bir hesap ekleyene ve senkronizasyon adaptörünün senkronize edildiği içerik sağlayıcı için senkronizasyonu etkinleştirene kadar senkronizasyon bağdaştırıcısı etkin hale gelmez. Bu noktada sistem, bağdaştırıcıyı yönetmeye başlar ve içerik sağlayıcı ile sunucu arasında senkronizasyon yapılması için gerekli olduğunda bağdaştırıcıyı çağırır.

Not: Senkronizasyon bağdaştırıcısının kimliğinin 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ılayıp gruplandırmasına olanak tanır. Örneğin, Google online hizmetlerinin senkronizasyon bağdaştırıcıları aynı hesap türüne (com.google) sahiptir. Kullanıcılar cihazlarına bir Google Hesabı eklediğinde Google hizmetleri için yüklü 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 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ımları uygulayarak doğrular:

  1. Kullanıcının adını, şifresini veya benzer bilgilerini (kullanıcının kimlik bilgileri) 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 üzere saklayabilir. Eklenti kimlik doğrulayıcı çerçevesi sayesinde AccountManager, 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 zorunlu olmasa da çoğu kişi hizmeti bunu kullanır. Ancak, kimlik doğrulama için Android kimlik doğrulama çerçevesini kullanmanız gerekmez.

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

Kişi 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:

Senkronizasyon bağdaştırıcısına bağlanmak için sistemden gelen isteklere 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 amacıyla hizmetin onBind() yöntemini çağırır. Bu, sistemin, bağdaştırıcının yöntemlerine çapraz işlem çağrıları yapmasına olanak tanır.
Somut bir AbstractThreadedSyncAdapter alt sınıfı olarak uygulanmış gerçek senkronizasyon bağdaştırıcısı.
Bu sınıf; sunucudan veri indirme, cihazdan veri yükleme ve çakışmaları çözme işlerini yapar. Adaptörün ana işi onPerformSync() yönteminde yapılır. Bu sınıf, bir tekil yapılarak örneklenmelidir.
Application sınıfının bir alt sınıfı.
Bu sınıf, senkronizasyon adaptörü tekli için fabrika işlevi görür. Senkronizasyon bağdaştırıcısını örneklendirmek için onCreate() yöntemini kullanın ve tekil kişiyi senkronizasyon bağdaştırıcısının hizmetinin onBind() yöntemine döndürmek için statik bir "getter" yöntemi sağlayın.
İsteğe bağlı: Kullanıcı kimlik doğrulaması için sistemden gelen isteklere yanıt veren bir Service bileşeni.
AccountManager, kimlik doğrulama işlemini başlatmak için bu hizmeti başlatır. Hizmetin onCreate() yöntemi, bir kimlik doğrulayıcı nesnesi örneği 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 bir IBinder almak amacıyla hizmetin onBind() yöntemini çağırır. Bu, sistemin, kimlik doğrulayıcının yöntemlerine çapraz işlem çağrıları yapmasına olanak tanır.
İsteğe bağlı: Kimlik doğrulama isteklerini işleyen somut bir AbstractAccountAuthenticator alt sınıfı.
Bu sınıf, AccountManager hizmetinin, kullanıcının kimlik bilgilerini sunucuda doğrulamak için çağırdığı yöntemleri sağlar. Kimlik doğrulama işleminin ayrıntıları, kullanılan sunucu teknolojisine bağlı olarak büyük ölçüde farklılık gösterir. Kimlik doğrulama hakkında daha fazla bilgi edinmek için sunucu yazılımınızın belgelerine bakmanız gerekir.
Senkronizasyon bağdaştırıcısını ve sistem kimlik doğrulayıcısını 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ının <meta-data> öğesi, res/xml/syncadapter.xml XML dosyasını işaret ediyor. Buna karşılık bu dosya, web hizmeti için Kişi Sağlayıcı ile senkronize edilecek bir URI ve web hizmeti için bir hesap türü belirtir.
  • İsteğe bağlı: Kimlik doğrulayıcının <meta-data> öğesi, res/xml/authenticator.xml adlı XML dosyasına işaret eder. 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 gelen akış verilerini bu tablolara ekleyen bir senkronizasyon bağdaştırıcısı yazabilir ya da bu tablolardaki akış verilerini okuyup kendi uygulamanızda görüntüleyebilir veya her ikisini de yapabilirsiniz. Bu özellikler sayesinde sosyal ağ hizmetleriniz ve uygulamalarınız Android'in sosyal ağ deneyimine entegre edilebilir.

Sosyal akış metni

Akış öğeleri her zaman ham bir kişiyle ilişkilendirilir. android.provider.ContactsContract.StreamItemsColumn#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 saklanır.

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

android.provider.ContactsContract.StreamItemsSütunlar#ACCOUNT_TYPE
Zorunlu. Bu akış öğesiyle ilişkili ham kişi için kullanıcının hesap türü. Yayın öğesi eklerken bu değeri ayarlamayı unutmayın.
android.provider.ContactsContract.StreamItemsColumn#ACCOUNT_NAME
Zorunlu. Bu akış öğesiyle ilişkili ham kişi için kullanıcı hesap adı. Yayın öğesi eklerken bu değeri ayarlamayı unutmayın.
Tanımlayıcı sütunlar
Zorunlu. Bir 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.BaseColumn#_ID değeri.
  • android.provider.ContactsContract.StreamItemscolumn#CONTACT_LOOKUP_KEY: Bu akış öğesinin ilişkilendirildiği kişinin android.provider.ContactsContract.ContactsSütunlar#LOOKUP_KEY değeri.
  • android.provider.ContactsContract.StreamItemscolumn#RAW_CONTACT_ID: Bu akış öğesinin ilişkilendirildiği ham kişinin android.provider.BaseColumn#_ID değeri.
android.provider.ContactsContract.StreamItemsSütunlar#COMMENTS
İsteğe bağlı. Bir akış öğesinin başında görüntüleyebileceğiniz özet bilgileri depolar.
android.provider.ContactsContract.StreamItemsColumn#TEXT
Akış öğesinin metni (öğenin kaynağı tarafından yayınlanan içerik veya akış öğesini oluşturan bir işlemin açıklaması). Bu sütun, fromHtml() tarafından oluşturulabilecek tüm biçimlendirmeleri ve yerleştirilmiş kaynak resimlerini içerebilir. Sağlayıcı uzun içeriği kırpabilir veya elips haline getirebilir ancak etiketleri kırmamaya çalışır.
android.provider.ContactsContract.StreamItemsSütunlar#TIMESTAMP
Dönemden beri akış öğesinin eklendiği veya güncellendiği zamanı içeren milisaniye biçiminde bir metin dizesi. Akış öğelerini 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ış öğelerinizin tanımlayıcı bilgilerini görüntülemek için uygulamanızdaki kaynaklara bağlantı vermek üzere android.provider.ContactsContract.StreamItemsColumn#RES_ICON, android.provider.ContactsContract.StreamItemsColumn#RES_LABEL ve android.provider.ContactsContract.StreamItemsColumn#RES_PACKAGE öğelerini kullanın.

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

Sosyal akış fotoğrafları

android.provider.ContactsContract.StreamItemPhotos tablosu, bir akış öğesiyle ilişkilendirilmiş fotoğrafları depolar. Tablonun android.provider.ContactsContract.StreamItemPhotosColumn#STREAM_ITEM_ID sütunu, android.provider.ContactsContract.StreamItems tablosunun _ID sütunundaki değerlere bağlantı oluşturur. Fotoğraf referansları, tabloda şu sütunlarda 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ılan ikili temsili. Bu sütun, fotoğrafları depolamak için onu kullanan Kişi Sağlayıcısı'nın önceki sürümleriyle geriye dönük uyumluluk sağlamak amacıyla kullanılabilir. Ancak, geçerli sürümde fotoğrafları saklamak için bu sütunu kullanmamanız gerekir. Bunun yerine, fotoğrafları bir dosyada depolamak için android.provider.ContactsContract.StreamItemPhotosColumn#PHOTO_FILE_ID veya android.provider.ContactsContract.StreamItemPhotosColumn#PHOTO_URI kullanın. bunların her ikisi de aşağıda açıklanmıştır. Bu sütun artık fotoğrafın okunabileceğiniz küçük resmini içerir.
android.provider.ContactsContract.StreamItemPhotosColumn#PHOTO_FILE_ID
Ham bir kişinin fotoğrafının sayısal tanımlayıcısı. Tek bir fotoğraf dosyasını işaret eden içerik URI'si almak için bu değeri DisplayPhoto.CONTENT_URI sabit öğesine ekleyin, ardından fotoğraf dosyasının herkese açık kullanıcı adını almak için openAssetFileDescriptor() yöntemini çağırın.
android.provider.ContactsContract.StreamItemPhotosColumn#PHOTO_URI
Bu satır tarafından temsil edilen fotoğraf için doğrudan fotoğraf dosyasını işaret eden bir içerik URI'si. Fotoğraf dosyasının herkese açık kullanıcı adını almak için bu URI ile openAssetFileDescriptor() çağırın.

Sosyal akış tablolarını kullanma

Bu tablolar, aşağıda belirtilenler 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. Bunları okuyabilmek için uygulamanızın android.Manifest.permission#READ_SOCIAL_STREAM iznine sahip olması gerekir. Bunları değiştirebilmek için uygulamanızın android.Manifest.permission#WRITE_SOCIAL_STREAM iznine sahip olması gerekir.
  • android.provider.ContactsContract.StreamItems tablosunda, her bir ham kişi için depolanan satır sayısı sınırlıdır. Bu sınıra ulaşıldığında Kişi Sağlayıcısı, en eski android.provider.ContactsContract.StreamItemsColumn#TIMESTAMP zamana sahip satırları otomatik olarak silerek yeni akış öğesi satırları için yer açar. Sınırı almak için android.provider.ContactsContract.StreamItems#CONTENT_LIMIT_URI içerik URI'sine bir sorgu gönderin. İçerik URI'si dışındaki tüm bağımsız değişkenleri null olarak ayarlanmış şekilde bırakabilirsiniz. Sorgu, android.provider.ContactsContract.StreamItems#MAX_ITEMS tek sütuna sahip, tek bir satır içeren bir İmleç döndürür.

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

Sosyal akış etkileşimleri

Kişi Sağlayıcı tarafından yönetilen sosyal akış verileri ve cihazın kişiler uygulaması ile birlikte, sosyal ağ sisteminizi mevcut kişilerinize bağlamak için etkili bir yol sunar. Aşağıdaki özellikler kullanılabilir:

  • Sosyal ağ hizmetinizi bir senkronizasyon bağdaştırıcısı kullanarak Kişi Sağlayıcı ile senkronize ederek, bir kullanıcının kişilerine ilişkin 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, kullanıcı görüntülemek üzere bir kişi seçtiğinde ek veriler almak için senkronizasyon bağdaştırıcınızı tetikleyebilirsiniz. Bu sayede senkronizasyon adaptörünüz kişi için yüksek çözünürlüklü fotoğrafları ve en yeni akış öğelerini alabilir.
  • Cihazın kişiler uygulamasına ve Kişi Sağlayıcı'ya bildirim kaydederek bir kişi görüntülendiğinde amaç alabilir ve bu noktada, hizmetinizden kişinin durumunu güncelleyebilirsiniz. Bu yaklaşım, senkronizasyon adaptörüyle tam senkronizasyon yapmaktan daha hızlı olabilir ve daha az bant genişliği kullanabilir.
  • Kullanıcılar, bir kişiyi cihazın kişiler uygulamasında görürken sosyal ağ hizmetinize ekleyebilir. Bu özelliği, ağınıza mevcut bir kişiyi ekleyen bir etkinlik ve cihazın kişiler uygulamasına ve Kişi Sağlayıcı'ya uygulamanızın ayrıntılarını sağlayan bir XML dosyası kombinasyonuyla etkinleştirdiğiniz"kişi davet et" özelliği ile 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 göz atın. Bildirimleri kaydetme ve kişileri davet etme konuları sonraki iki bölümde ele alınmıştır.

Sosyal ağ görünümlerini işlemek için kaydolma

Kullanıcı, senkronizasyon bağdaştırıcınız tarafından yönetilen bir kişiyi görüntülediğinde bildirim almak üzere senkronizasyon bağdaştırıcınızı 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ı, cihazın kişiler uygulamasında bir kişinin ayrıntılar sayfasını açtığında bildirim alan bir hizmeti kaydetmek için öğeye viewContactNotifyService="serviceclass" özelliğini ekleyin. Burada serviceclass, cihazın kişiler uygulamasından amacı alması gereken hizmetin tam sınıf adıdır. Bildirimci hizmetinde, hizmetin amaçlar almasına izin vermek için IntentService kapsamını genişleten bir sınıf kullanın. Gelen amaçtaki veriler, kullanıcının tıkladığı ham kişinin içerik URI'sini içerir. Bildirimci hizmetinden, ham kişinin verilerini güncellemek için senkronizasyon bağdaştırıcınıza bağlanıp çağrı yapabilirsiniz.

Kullanıcı bir akış öğesini, fotoğrafını ya da her ikisini tıkladığında çağrılacak bir etkinliği 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. Bir kullanıcının cihazın kişiler uygulamasında bir akış öğesini tıklamasını işleme almak amacıyla etkinliklerinizden birini kaydetmek için viewStreamItemActivity="activityclass" özelliğini öğeye ekleyin. Burada activityclass, cihazın kişiler uygulamasından amacı alması gereken etkinliğin tam sınıf adıdır.
  4. Bir kullanıcının cihazın kişiler uygulamasındaki bir akış fotoğrafını tıklamasını işleme almak amacıyla etkinliklerinizden birini kaydetmek için viewStreamItemPhotoActivity="activityclass" özelliğini öğeye ekleyin. Burada activityclass, cihazın kişiler uygulamasından amacı alması gereken etkinliğin tam 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'sını içerir. Metin öğeleri ve fotoğraflar için ayrı etkinlikleriniz olması için her iki özelliği de aynı dosyada kullanın.

Sosyal ağ hizmetinizle etkileşimde bulunma

Kullanıcıların, bir kişiyi sosyal ağ sitenize davet etmek için cihazın kişiler uygulamasından ayrılması gerekmez. Bunun yerine, cihazın kişiler uygulamasının, kişiyi etkinliklerinizden birine davet etmek için bir niyet 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şi 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. Aşağıdaki 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">

şunu içeriyor:

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> özellikleri için android: özellik önekinin gerekli olmadığına dikkat edin.

Ö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
inviteContactActivity bölümündeki Bağlantı ekle menüsünde belirtilen etkinlik için görüntülenen metin dizesi. Örneğin, "Ağımda takip et" dizesini kullanabilirsiniz. Bu etiket için dize kaynağı 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şlemleri ihtiyaç duyulana kadar ertelemesine olanak tanır. Örneğin, uygulamanız, kişinin yüksek çözünürlüklü fotoğrafını ve en son sosyal akış öğelerini okuyup görüntüleyerek bu bildirime yanıt verebilir. Bu özellik, Sosyal 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 nitelikli sınıf adı. Kullanıcı, cihazın kişiler uygulamasında grup etiketini tıkladığında bu etkinliğin kullanıcı arayüzü görüntülenir.
viewGroupActionLabel
Kullanıcının uygulamanızdaki gruplara bakmasına olanak tanıyan bir kullanıcı arayüzü kontrolü için kişiler uygulamasının görüntülediği etiket.

Bu özellik için dize kaynağı tanımlayıcısına izin verilir.

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

<ContactsDataKind> öğesi

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

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

şunu içeriyor:

<ContactsAccountType>

Açıklama:

Kişiler uygulamasının, ham kişinin ayrıntılarının bir parçası olarak özel bir veri satırı içeriği görüntülemesini sağlamak 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 MIME türü olabilir.
android:icon
Kişiler uygulamasının verilerinizin yanında gösterdiği bir Android çizim kaynağı. Kullanıcıya verilerin hizmetinizden geldiğini belirtmek için bunu kullanın.
android:summaryColumn
Veri satırından alınan iki değerden ilkinin sütun adı. Değer, bu veri satırı için girişin ilk satırı olarak görüntülenir. İlk satır, verilerin bir özeti olarak kullanılmak üzere tasarlanmıştır ancak isteğe bağlıdır. android:detailColumn bölümüne de bakın.
android:detailColumn
Veri satırından alınan iki değerden ikincisinin sütun adı. Değer, bu veri satırı için girişin ikinci satırı olarak görüntülenir. Ayrıca bkz. android:summaryColumn.

Ek Kişi Sağlayıcısı özellikleri

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

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

Kişi grupları

Kişi Sağlayıcısı, isteğe bağlı olarak ilgili kişilerden oluşan koleksiyonları grup verileriyle etiketleyebilir. Bir kullanıcı hesabıyla ilişkilendirilmiş sunucu, grupları korumak istiyorsa hesabın hesap türünün senkronizasyon bağdaştırıcısının grup verilerini Kişi Sağlayıcı ile sunucu arasında aktarması gerekir. Kullanıcılar sunucuya yeni bir kişi eklediğinde ve ardından bu kişiyi yeni bir gruba yerleştirdiğinde, senkronizasyon bağdaştırıcısının yeni grubu ContactsContract.Groups tablosuna eklemesi gerekir. Ham kişinin ait olduğu grup veya gruplar, ContactsContract.CommonDataKinds.GroupMembership MIME türü kullanılarak ContactsContract.Data tablosunda depolanır.

Sunucudan Kişi 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 bildirmeniz gerekir. Bir kullanıcı cihaza hesap eklediğinde yürütülen 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, grup kullanmıyor olsanız bile Kişi Sağlayıcı kişi verilerinizi her zaman görünür hale getirir.

Kişi fotoğrafları

ContactsContract.Data tablosu, fotoğrafları Photo.CONTENT_ITEM_TYPE MIME türünde satırlar halinde 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ı, kişinin birincil ham kişisinin birincil fotoğrafı olan birincil fotoğrafının fotoğraf bilgilerini içeren ContactsContract.Contacts alt tablosundan tanımlanır. Benzer şekilde, ContactsContract.RawContacts.DisplayPhoto sınıfı ham kişinin birincil fotoğrafının fotoğraf bilgilerini içeren bir ContactsContract.RawContacts alt tablosu tanımlar.

ContactsContract.Contacts.Photo ve ContactsContract.RawContacts.DisplayPhoto referans dokümanlarında, fotoğraf bilgilerinin alınmasıyla ilgili örnekler yer almaktadır. Ham kişinin birincil küçük resminin alınması kolay bir sınıf değildir 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ütunlarını seçerek ContactsContract.Data tablosuna sorgu gönderebilirsiniz.

Bir kişinin sosyal akış verilerinde fotoğraflar da bulunabilir. Bunlar, Sosyal akış fotoğrafları bölümünde daha ayrıntılı olarak açıklanan android.provider.ContactsContract.StreamItemPhotos tablosunda depolanır.