Contacts Provider

Kişiler Sağlayıcı, cihazın kişilerle ilgili merkezi veri deposunu yöneten güçlü ve esnek bir Android bileşenidir. Kişiler Sağlayıcı, cihazın kişiler uygulamasında gördüğünüz verilerin kaynağıdır. Ayrıca kendi uygulamanızda bu verilere erişebilir ve cihaz ile online hizmetler arasında veri aktarabilirsiniz. Sağlayıcı, çok çeşitli veri kaynaklarını destekler ve her kişi için mümkün olduğunca fazla veriyi yönetmeye çalışır. Bu durum, kuruluşunun karmaşık olmasına neden olur. Bu nedenle, sağlayıcının API'si hem veri almayı hem de değiştirmeyi kolaylaştıran kapsamlı bir sözleşme sınıfları ve arayüzleri grubu içerir.

Bu rehberde aşağıdakiler açıklanmaktadır:

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

Bu kılavuzda, Android içerik sağlayıcılarının temel işlevleri hakkında bilgi sahibi olduğunuz varsayılmaktadır. Android içerik sağlayıcıları hakkında daha fazla bilgi edinmek için İçerik sağlayıcılarla ilgili temel bilgiler kılavuzunu inceleyin.

Contacts Provider kuruluşu

Contacts Provider, bir Android içerik sağlayıcı bileşenidir. Bir kişi hakkında üç tür veri tutar. Bunların her biri, sağlayıcının sunduğu bir tabloya karşılık gelir. Şekil 1'de gösterildiği gibi:

1.şekil Contacts Provider tablo yapısı.

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

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

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

Ham kişiler

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

Bir ham kişiye ait verilerin çoğu ContactsContract.RawContacts tablosunda depolanmaz. Bunun yerine, ContactsContract.Data tablosundaki bir veya daha fazla satırda depolanır. Her veri satırında, Data.RAW_CONTACT_ID üst satırının RawContacts._ID değerini içeren ContactsContract.RawContacts bir sütun bulunur.

Önemli ham kişi sütunları

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

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

Sütun adı Kullan Notlar
ACCOUNT_NAME Bu ham 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 sonraki girişe bakın. Bu adın biçimi, hesap türüne özeldir. Bu değerin e-posta adresi olması gerekmez.
ACCOUNT_TYPE Bu ham kişinin kaynağı olan hesap türü. Örneğin, Google Hesabı'nın hesap türü com.google'dır. Hesap türünüzü her zaman sahip olduğunuz veya kontrol ettiğiniz bir alanın alan tanımlayıcısıyla nitelendirin. Bu sayede hesap türünüzün benzersiz olması sağlanır. Kişiler verileri sunan bir hesap türü genellikle Kişiler Sağlayıcı ile senkronize olan ilişkili bir senkronizasyon adaptörüne sahiptir.
DELETED Bir ham kişi için "silindi" işareti. Bu işaret, kişi sağlayıcının, satırı sunucularından silebilen ve ardından satırı depodan silebilen senkronizasyon bağdaştırıcıları olana kadar satırı dahili olarak korumasına olanak tanır.

Notlar

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

  • Bir ham kişinin adı, ContactsContract.RawContacts'daki satırında depolanmaz. Bunun yerine, ContactsContract.Data tablosunda ContactsContract.CommonDataKinds.StructuredName satırında saklanır. Bir ham kişi ContactsContract.Data tablosunda yalnızca bir satıra sahiptir.
  • Dikkat: Kendi hesap verilerinizi bir ham kişi satırında kullanmak için öncelikle AccountManager ile kaydedilmesi gerekir. Bunu yapmak için kullanıcılardan hesap türünü ve hesap adlarını hesap listesine eklemelerini isteyin. Bu işlemi yapmazsanız Kişiler Sağlayıcı, ham kişi satırınızı otomatik olarak siler.

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

İşlenmemiş kişi verilerinin kaynakları

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

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

Bu kullanıcı, Hesaplar ayarlarında bu üç hesabın tümü için Kişileri Senkronize Et'i etkinleştirmiştir.

Örneğin, Emily Dickinson bir tarayıcı penceresi açıyor, emily.dickinson@gmail.com olarak Gmail'e giriş yapıyor, Kişiler'i açıyor ve "Thomas Higginson"u ekliyor. Daha sonra Gmail'e emilyd@gmail.com olarak giriş yapar ve "Thomas Higginson"a e-posta gönderir. Bu e-posta, Thomas Higginson'ı otomatik olarak kişilere ekler. Ayrıca Twitter'da "colonel_tom" (Thomas Higginson'ın Twitter kimliği) hesabını da takip ediyor.

Contacts Provider, bu çalışma sonucunda üç ham kişi oluşturur:

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

Veri

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

Bu tek tabloda farklı veri türlerinin depolandığını unutmayın. Görünen ad, telefon numarası, e-posta, posta adresi, fotoğraf ve web sitesi ayrıntı satırları ContactsContract.Data tablosunda yer alır. Bunu yönetmeye yardımcı olmak için ContactsContract.Data tablosunda açıklayıcı adlara sahip bazı sütunlar ve genel adlara sahip diğer sütunlar bulunur. Açıklayıcı ad sütunundaki içerikler, satırdaki veri türünden bağımsız olarak aynı anlama gelirken genel ad sütunundaki içerikler, veri türüne bağlı olarak farklı anlamlara gelir.

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

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

RAW_CONTACT_ID
Bu veriler için ham kişinin _ID sütununun değeri.
MIMETYPE
Bu satırda depolanan verilerin türü, özel bir MIME türü olarak ifade edilir. Contacts Provider, 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şiler Sağlayıcı ile çalışan tüm uygulamalar veya senkronizasyon bağdaştırıcıları tarafından kullanılabilir.
IS_PRIMARY
Bu tür bir veri satırı, bir ham kişi için birden fazla kez oluşabilirse IS_PRIMARY sütunu, türle ilgili birincil verileri içeren veri satırını işaretler. Örneğin, kullanıcı bir kişiye ait telefon numarasına uzun basıp Varsayılan olarak ayarla'yı seçerse bu numarayı içeren ContactsContract.Data satırının IS_PRIMARY sütunu sıfır olmayan bir değere ayarlanır.

Genel sütun adları

Genel olarak kullanılabilen DATA1 ile DATA15 arasında adlandırılmış 15 genel sütun ve yalnızca senkronizasyon bağdaştırıcıları tarafından kullanılması gereken SYNC1 ile SYNC4 arasında adlandırılmış dört ek genel sütun vardır. Satırın içerdiği veri türünden bağımsız olarak, genel sütun adı sabitleri her zaman çalışır.

DATA1 sütunu dizine eklenir. Kişiler Sağlayıcı, sağlayıcının sorgunun en sık hedefi olacağını düşündüğü 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.

Geleneksel olarak DATA15 sütunu, fotoğraf küçük resimleri gibi Binary Large Object (BLOB) verilerini depolamak için ayrılmıştır.

Türe özgü sütun adları

Contacts Provider, 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 özgü sütun adı sabitleri de sağlar. Sabitler, aynı sütun adına farklı bir sabit ad verir. Bu da belirli bir türdeki satırda bulunan verilere erişmenize yardımcı olur.

Örneğin, ContactsContract.CommonDataKinds.Email sınıfı, MIME türü Email.CONTENT_ITEM_TYPE olan bir ContactsContract.Data satırı için türe özgü sütun adı sabitlerini tanımlar. Sınıf, e-posta adresi sütunu için ADDRESS sabitini içeriyor. ADDRESS öğesinin gerçek değeri, sütunun genel adıyla aynı olan "data1"dir.

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

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

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

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

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

Tablo 2'de, en sık kullanılan türe özgü sütun adı sınıfları listelenmektedir:

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

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

Kişiler

Kişiler Sağlayıcı, tüm hesap türleri ve hesap adlarındaki ham kişi satırlarını birleştirerek kişi oluşturur. Bu, kullanıcının bir kişi için topladığı tüm verilerin gösterilmesini ve değiştirilmesini kolaylaştırır. Kişiler Sağlayıcı, yeni kişi satırlarının oluşturulmasını ve ham kişilerin mevcut bir kişi satırıyla birleştirilmesini yönetir. Ne uygulamaların ne de senkronizasyon bağdaştırıcılarının kişi eklemesine izin verilir ve bir kişi satırındaki bazı sütunlar salt okunurdur.

Not: Kişiler sağlayıcıya insert() ile bir kişi eklemeye çalışırsanız UnsupportedOperationException istisnası alırsınız. "Salt okunur" olarak listelenen bir sütunu güncellemeye çalışırsanız güncelleme yok sayılır.

Kişiler Sağlayıcı, mevcut kişilerle eşleşmeyen yeni bir ham kişi eklendiğinde yeni bir kişi oluşturur. Sağlayıcı, mevcut bir ham kişinin verileri daha önce bağlı olduğu kişiyle eşleşmeyecek şekilde değiştiğinde de bunu yapar. Bir uygulama veya senkronizasyon bağdaştırıcısı, mevcut bir kişiyle eşleşmeyen yeni bir ham kişi oluşturursa yeni ham kişi, mevcut kişiyle birleştirilir.

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, her ham kişiler satırıyla ilişkili kişiler satırı için _ID değerlerini içerir.

ContactsContract.Contacts tablosunda, kişi satırına "kalıcı" bağlantı olan LOOKUP_KEY sütunu da bulunur. Kişi sağlayıcı, kişileri otomatik olarak koruduğu için bir toplama veya senkronizasyon işlemine yanıt olarak kişi satırının _ID değerini değiştirebilir. Bu durumda bile, içerik URI'si CONTENT_LOOKUP_URI ile birleştirilen LOOKUP_KEY, kişi satırına yönlendirmeye devam eder. Bu nedenle, "favori" kişilere bağlantıları korumak için LOOKUP_KEY kullanabilirsiniz. Bu sütunun, _ID sütununun biçimiyle alakasız kendi biçimi vardır.

Şekil 3'te üç ana tablonun birbiriyle ilişkisi gösterilmektedir.

Contacts Provider 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ümlerin yüklü olduğu bir cihazda bulunuyorsa sınırlı sayıda kişi verileri alanının ve yönteminin kullanımdan kaldırıldığını unutmayın.

Belirtilen koşullar altında sistem, bu veri alanlarına yazılan değerleri düzenli olarak temizler:

Yukarıdaki veri alanlarını ayarlamak için kullanılan API'ler de artık kullanılmamaktadır:

Ayrıca, aşağıdaki alanlar artık sık görüşülen kişileri döndürmüyor. Bu alanlardan bazılarının, kişilerin sıralamalarını yalnızca belirli bir veri türünün parçası olduklarında 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şlevselliğinin bu değişiklikten etkilenmediğini doğrulamak için bu veri alanlarını manuel olarak temizleyebilirsiniz. Bunu yapmak için Android 4.1 (API düzeyi 16) veya sonraki sürümlerin yüklü olduğu 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 gelen veriler

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

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

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

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

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

Şekil 4'te, Kişiler Sağlayıcı'nın kişilerle ilgili veri akışına nasıl uyduğu gösterilmektedir. "Senkronizasyon bağdaştırıcıları" olarak işaretlenen kutuda her bağdaştırıcı, hesap türüne göre etiketlenir.

Kişilerle ilgili verilerin akışı

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

Gerekli izinler

Kişiler sağlayıcısına 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> öğesiyle <uses-permission android:name="android.permission.READ_CONTACTS"> olarak belirtildi.
Bir veya daha fazla tabloya yazma erişimi
WRITE_CONTACTS, AndroidManifest.xml içinde <uses-permission> öğesiyle <uses-permission android:name="android.permission.WRITE_CONTACTS"> olarak belirtildi.

Bu izinler, kullanıcı profili verilerini kapsamaz. Kullanıcı profili ve gerekli izinleri, Kullanıcı profili başlıklı bölümde ele alınmaktadır.

Kullanıcının kişi verilerinin kişisel ve hassas olduğunu unutmayın. Kullanıcılar gizlilikleriyle ilgili endişe duydukları için uygulamaların kendileri veya kişileri hakkında veri toplamasını istemiyor. Kullanıcılar, kişileri verilerine erişmek için neden izne ihtiyacınız olduğunu anlamazsa uygulamanıza düşük puan verebilir veya uygulamayı yüklemeyi reddedebilir.

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 birini değil, cihazın user özelliğini tanımlar. Profil kişileri satırı, profil kullanan her sistem için ham kişi satırına bağlanır. Her profilin ham kişi satırında birden fazla veri satırı olabilir. Kullanıcı profiline erişim için kullanılan sabitler ContactsContract.Profile sınıfında bulunur.

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

Kullanıcı profillerinin hassas olduğunu unutmayın. android.Manifest.permission#READ_PROFILE izni, cihaz kullanıcısının kimliği tanımlayabilecek nitelikteki verilerine erişmenize olanak tanır. Uygulama açıklamanızda kullanıcıya neden kullanıcı profili erişim izinlerine ihtiyacınız olduğunu mutlaka belirtin.

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

Kotlin

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

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

Java

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

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

Not: Birden fazla kişi satırı alı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.

Contacts Provider meta verileri

Contacts Provider, depodaki kişi verilerinin durumunu takip eden verileri yönetir. Depoyla ilgili bu meta veriler, Raw Contacts, Data ve Contacts tablo satırları, ContactsContract.Settings tablosu ve ContactsContract.SyncState tablosu dahil olmak üzere çeşitli yerlerde depolanır. Aşağıdaki tabloda, bu meta verilerin her birinin etkisi gösterilmektedir:

Tablo 3. Contacts Provider'daki meta veriler

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

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

"1": Son senkronizasyondan sonra değiştirildi, sunucuyla tekrar senkronize edilmesi gerekiyor.
ContactsContract.RawContacts VERSION Bu satırın sürüm numarası. Kişiler Sağlayıcı, satır veya ilgili verileri her değiştiğinde bu değeri otomatik olarak artırır.
ContactsContract.Data DATA_VERSION Bu satırın sürüm numarası. Kişiler 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 hesapta benzersiz şekilde tanımlayan bir dize değeri. Bir senkronizasyon bağdaştırıcısı yeni bir ham kişi oluşturduğunda bu sütun, ham kişi için sunucunun benzersiz kimliğine ayarlanmalıdır. Bir Android uygulaması yeni bir ham kişi oluşturduğunda bu sütunu boş bırakmalıdır. Bu, senkronizasyon bağdaştırıcısına sunucuda yeni bir ham kişi oluşturması ve SOURCE_ID için bir değer alması gerektiğini bildirir.

Özellikle kaynak kimliği, her hesap türü için benzersiz olmalı ve senkronizasyonlar arasında sabit kalmalıdır:

  • Benzersiz: Bir hesaptaki her ham kişinin kendi kaynak kimliği olmalıdır. Bu ayarı zorunlu kılmazsanız kişiler uygulamasında sorunlara neden olursunuz. Aynı hesap türündeki iki ham kişinin aynı kaynak kimliğine sahip olabileceğini unutmayın. Örneğin, emily.dickinson@gmail.com hesabındaki "Thomas Higginson" adlı ham kişi, emilyd@gmail.com hesabındaki "Thomas Higginson" adlı ham kişiyle aynı kaynak kimliğine sahip olabilir.
  • Kararlı: Kaynak kimlikleri, ham kişi için online hizmetin verilerinin kalıcı bir parçasıdır. Örneğin, kullanıcı Kişiler Depolama Alanı'nı Uygulamalar ayarlarından temizleyip yeniden senkronize ederse geri yüklenen ham kişilerin kaynak kimlikleri eskisiyle aynı olmalıdır. Bu ayarı zorunlu kılmazsanız kısayollar çalışmayı durdurur.
ContactsContract.Groups GROUP_VISIBLE "0": Bu gruptaki kişiler Android uygulaması kullanıcı arayüzlerinde görünmemelidir. Bu sütun, kullanıcının belirli gruplardaki kişileri gizlemesine olanak tanıyan sunucularla uyumluluk içindir.
"1": Bu gruptaki kişilerin uygulama kullanıcı arayüzlerinde görünmesine izin verilir.
ContactsContract.Settings UNGROUPED_VISIBLE "0": Bu hesap ve hesap türü için bir gruba ait olmayan kişiler, Android uygulaması kullanıcı arayüzlerinde görünmez. Varsayılan olarak, ham kişilerden hiçbiri bir gruba ait değilse kişiler görünmez olur (Bir ham kişinin grup üyeliği, ContactsContract.Data tablosundaki bir veya daha fazla ContactsContract.CommonDataKinds.GroupMembership satırla gösterilir). Bu işareti bir hesap türü ve hesap için ContactsContract.Settings tablo satırında ayarlayarak grupsuz kişilerin görünür olmasını sağlayabilirsiniz. Bu işaretin bir kullanım alanı, grupları kullanmayan sunuculardaki kişileri göstermektir.
"1": Bu hesap ve hesap türü için bir gruba ait olmayan kişiler uygulama kullanıcı arayüzlerinde görünür.
ContactsContract.SyncState (tümü) Senkronizasyon bağdaştırıcınızın meta verilerini depolamak için bu tabloyu kullanın. Bu tabloyu kullanarak senkronizasyon durumunu ve senkronizasyonla ilgili diğer verileri cihazda kalıcı olarak depolayabilirsiniz.

Contacts Provider erişimi

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

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

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

Varlıkları sorgulama

Kişiler sağlayıcı tabloları hiyerarşik olarak düzenlendiğinden, bir satırı ve ona bağlı tüm "alt" satırları almak genellikle yararlıdır. Örneğin, bir kişiyle ilgili tüm bilgileri görüntülemek için tek bir ContactsContract.RawContacts satırına ait tüm ContactsContract.Contacts satırlarını veya tek bir ContactsContract.CommonDataKinds.Email satırına ait tüm ContactsContract.RawContacts satırlarını almak isteyebilirsiniz. Bunu kolaylaştırmak için Kişiler Sağlayıcı, tablolar arasında veritabanı birleştirmeleri gibi davranan varlık yapıları sunar.

Varlık, bir üst tablodan ve alt tablosundan seçilen sütunlardan oluşan bir tabloya benzer. Bir varlığı sorguladığınızda, varlıktan kullanılabilen sütunlara göre bir projeksiyon ve arama ölçütleri sağlarsınız. Sonuç, Cursor içeren bir Cursor olur. Bu Cursor, her bir alt tablo satırı için bir satır içerir. Örneğin, bir kişi adıyla ilgili ContactsContract.Contacts.Entity sorgusu gönderirseniz ve bu adla ilgili 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 bir Cursor yanıtı alırsınız.

Varlıklar sorguları basitleştirir. Bir öğe kullanarak, önce bir kimlik almak için üst tabloyu sorgulayıp ardından bu kimlikle alt tabloyu sorgulamak yerine bir kişi veya ham kişi için tüm kişi verilerini tek seferde alabilirsiniz. Ayrıca, Kişiler Sağlayıcı, tek bir işlemde bir öğeye karşı sorgu işler. Bu da alınan verilerin dahili olarak tutarlı olmasını sağlar.

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

Aşağıdaki snippet'te, bir kişiye ait tüm ham kişi satırlarının nasıl alınacağı gösterilmektedir. Snippet, "main" ve "detail" 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ı birini seçtiğinde etkinlik, kimliğini ayrıntı etkinliğine gönderir. Ayrıntılı etkinlik, seçilen kişiyle ilişkili tüm ham kişilerden gelen tüm veri satırlarını göstermek için ContactsContract.Contacts.Entity simgesini 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 işlemi tamamlandığında LoaderManager, onLoadFinished() için bir geri çağırma işlemi başlatır. Bu yönteme gelen bağımsız değişkenlerden biri, sorgu sonuçlarını içeren bir Cursor'dır. Kendi uygulamanızda, bu Cursor verilerini görüntülemek veya daha fazla kullanmak için alabilirsiniz.

Toplu değişiklik

Mümkün olduğunda, ArrayList nesneleri oluşturup applyBatch() işlevini çağırarak Kişiler Sağlayıcı'daki verileri "toplu modda" eklemeniz, güncellemeniz ve silmeniz gerekir.ContentProviderOperation Kişiler sağlayıcı, applyBatch() içindeki tüm işlemleri tek bir işlemde gerçekleştirdiğinden değişiklikleriniz hiçbir zaman tutarsız bir durumda kişiler deposundan ayrılmaz. Toplu değişiklik, ham bir kişiyi ve ayrıntı verilerini aynı anda eklemeyi de kolaylaştırır.

Not: Tek bir ham kişiyi değiştirmek için değişikliği uygulamanızda işlemek yerine cihazın kişiler uygulamasına bir amaç göndermeyi düşünebilirsiniz. Bu işlem, Amaçlarla alma ve değiştirme bölümünde daha ayrıntılı olarak açıklanmıştır.

Getiri noktaları

Çok sayıda işlem içeren bir toplu değişiklik, diğer işlemleri engelleyerek genel kullanıcı deneyiminin kötü olmasına neden olabilir. Yapmak istediğiniz tüm değişiklikleri mümkün olduğunca az sayıda ayrı listede düzenlemek ve aynı zamanda bu değişikliklerin sistemi engellemesini önlemek için bir veya daha fazla işlem için gelir noktaları belirlemeniz gerekir. Bir getiri noktası, ContentProviderOperation değeri true olarak ayarlanmış bir isYieldAllowed() nesnesidir. Kişiler Sağlayıcı bir verim noktasıyla karşılaştığında diğer işlemlerin çalışmasına izin vermek için çalışmasını duraklatır ve mevcut işlemi kapatır. Sağlayıcı tekrar başladığında ArrayList sırasındaki bir sonraki işlemle devam eder ve yeni bir işlem başlatır.

Getiri puanları, applyBatch() çağrısı başına birden fazla işlemle sonuçlanır. Bu nedenle, bir grup ilgili satır için son işlemde bir getiri noktası belirlemeniz gerekir. Örneğin, ham kişi satırları ve ilişkili veri satırları ekleyen bir gruptaki son işlem veya tek bir kişiyle ilgili bir satır grubundaki son işlem için bir verim noktası ayarlamanız gerekir.

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

Değişiklik geri referansları

Yeni bir ham kişi satırı ve ilişkili veri satırlarını bir dizi ContentProviderOperation nesnesi 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 henüz ContentProviderOperation ContentProviderOperation 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ında withValueBackReference() yöntemi bulunur. Bu yöntem, önceki bir işlemin sonucunu içeren bir sütun eklemenize veya değiştirmenize olanak tanır.

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

key
Anahtar/değer çiftinin anahtarı. Bu bağımsız değişkenin değeri, değiştirdiğiniz tablodaki bir sütunun adı olmalıdır.
previousResult
applyBatch() öğesinden gelen ContentProviderResult nesneleri dizisindeki bir değerin 0 tabanlı dizini. applyBatch(). Toplu işlemler uygulandıkça her işlemin sonucu, ara sonuç dizisinde saklanır. previousResult değeri, bu sonuçlardan birinin dizinidir. Bu dizin, key değeriyle birlikte alınır ve depolanır. Bu sayede yeni bir ham kişi kaydı ekleyebilir ve _ID değerini geri alabilir, ardından ContactsContract.Data satırı eklerken değere "geri referans" oluşturabilirsiniz.

Tüm sonuç dizisi, applyBatch() işlevini ilk kez çağırdığınızda oluşturulur ve sağladığınız ContentProviderOperation nesnelerinin ArrayList boyutuna eşit bir boyuta sahiptir. Ancak sonuç dizisindeki tüm öğeler null olarak ayarlanır ve henüz uygulanmamış bir işlem için sonuca geri referans vermeye çalışırsanız withValueBackReference(), Exception hatası verir.

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

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

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());

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

Kotlin

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

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

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

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

Java

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

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

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

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

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

Her işlem oluşturucu nesnesi, withValueBackReference() kullanarak RAW_CONTACT_ID değerini alır. Referans noktaları, ham kişi satırını ekleyen ve yeni _ID değerini döndüren ilk işlemdeki ContentProviderResult nesnesine geri döner. Sonuç olarak, her veri satırı RAW_CONTACT_ID ContactsContract.RawContacts ile ait olduğu yeni ContactsContract.RawContacts satırına otomatik olarak bağlanır.

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

Kotlin

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

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

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

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

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

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

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

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

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

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

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

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

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

Java

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

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

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

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

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

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

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

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

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

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

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

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

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

Son snippet, 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 depoyu kilitlemek zorunda kalmadan değişiklik işlemlerini uygulamanıza olanak tanıyan bir yöntem olan iyimser eşzamanlılık kontrolünü de uygulamanıza olanak tanır. Bu yöntemi kullanmak için işlemi uygular ve aynı anda yapılmış olabilecek diğer değişiklikleri kontrol edersiniz. Tutarsız bir değişiklik olduğunu fark ederseniz işleminizi geri alıp yeniden deneyebilirsiniz.

İyimser eşzamanlılık kontrolü, aynı anda yalnızca bir kullanıcının bulunduğu ve bir veri deposuna eşzamanlı erişimin nadir olduğu mobil cihazlar için yararlıdır. Kilitleme kullanılmadığından, kilit ayarlamak veya diğer işlemlerin kilitlerini serbest bırakmasını beklemek için zaman harcanmaz.

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

  1. Alınan diğer verilerle birlikte ham kişinin VERSION sütununu alın.
  2. ContentProviderOperation.Builder yöntemini kullanarak bir kısıtlamayı zorunlu kılmaya uygun bir newAssertQuery(Uri) nesnesi oluşturun. İçerik URI'si için, RawContacts.CONTENT_URI ile ham kişinin _ID eklenmiş halini kullanın.
  3. ContentProviderOperation.Builder nesnesi için VERSION sütununu yeni aldığınız sürüm numarasıyla karşılaştırmak üzere withValue() işlevini çağırın.
  4. Aynı ContentProviderOperation.Builder için, bu onaylamayla yalnızca bir satırın test edildiğinden emin olmak üzere withExpectedCount() işlevini çağırın.
  5. build() işlevini çağırarak ContentProviderOperation nesnesini oluşturun, ardından bu nesneyi applyBatch() işlevine ilettiğiniz ArrayList dizisindeki ilk nesne olarak ekleyin.
  6. Toplu işlemi uygulayın.

Satırı okuduğunuz zaman ile satırı değiştirmeye çalıştığınız zaman arasında ham kişi satırı başka bir işlemle güncellenirse "assert" ContentProviderOperation başarısız olur ve tüm işlem grubu geri alınır. Ardından, grubu yeniden denemeyi veya başka bir işlem yapmayı seçebilirsiniz.

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

Kotlin

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

...

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

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

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

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

ops.add(assertOp.build())

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

...

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

Java

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

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

...

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

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

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

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

ops.add(assertOp.build());

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

...

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

    } catch (OperationApplicationException e) {

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

Niyetlerle alma ve değiştirme

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

  • Listeden bir kişi seçip daha fazla işlem yapmak için uygulamaya geri döndürü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 silme

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

Cihazın Kişiler uygulaması üzerinden Kişiler Sağlayıcı'ya erişmek için intent'leri kullandığınızda sağlayıcıya erişmek için kendi kullanıcı arayüzünüzü veya kodunuzu yazmanız gerekmez. Ayrıca, sağlayıcıda okuma veya yazma izni istemeniz de gerekmez. Cihazın Kişiler uygulaması, bir kişi için okuma iznini size devredebilir. Ayrıca, sağlayıcıda başka bir uygulama üzerinden değişiklik yaptığınız için yazma izninizin olması gerekmez.

Bir sağlayıcıya erişim isteği göndermeyle ilgili genel süreç, İçerik sağlayıcılarla ilgili temel bilgiler rehberinin "Amaçlar aracılığıyla veri erişimi" bölümünde ayrıntılı olarak açıklanmıştır. Kullanılabilir görevler için kullandığınız işlem, MIME türü ve veri değerleri Tablo 4'te özetlenirken putExtra() ile kullanabileceğiniz ek değerler ContactsContract.Intents.Insert ile ilgili referans dokümanlarında listelenir:

Tablo 4. Contacts Provider Intents.

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

Seçilen satırın içerik URI'sini döndüren startActivityForResult(), işlevini çağırın. URI'nin biçimi, satırın LOOKUP_ID eklenmiş olduğu tablonun içerik URI'sidir. Cihazın Kişiler uygulaması, etkinliğiniz süresince bu içerik URI'si için okuma ve yazma izinlerini devreder. Daha fazla bilgi için İçerik sağlayıcılarla ilgili temel bilgiler kılavuzunu inceleyin.

Yeni bir 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österir. Niyete eklediğiniz ek değerler gösterilir. startActivityForResult() ile gönderilirse yeni eklenen ham kişinin içerik URI'si, Intent bağımsız değişkenindeki onActivityResult() geri çağırma yöntemine "data" alanında geri iletilir. Değeri almak için getData() numaralı telefonu arayın.
Kişileri düzenleme ACTION_EDIT Kişi için CONTENT_LOOKUP_URI. Düzenleyici etkinliği, kullanıcının bu kişiyle ilişkili verileri düzenlemesine olanak tanır. Contacts.CONTENT_ITEM_TYPE, tek bir kişi. Kişiler uygulamasında Kişiyi Düzenle ekranını gösterir. Niyete eklediğiniz ek değerler gösterilir. Kullanıcı, düzenlemeleri kaydetmek için Bitti'yi tıkladığında etkinliğiniz ön plana döner.
Veri de ekleyebilen bir seçici gösterin. ACTION_INSERT_OR_EDIT Yok CONTENT_ITEM_TYPE Bu amaç her zaman Kişiler uygulamasının seçici ekranını gösterir. Kullanıcı, düzenlemek için 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österilir ve amaçta ilettiğiniz ekstralar verileri 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 amaç filtresini kullanın. kişi,

Not: Kullanıcı her zaman mevcut bir adı seçtiği veya yeni bir ad eklediği için bu amaçla ilgili ekstralarda ad değeri göndermenize gerek yoktur. Ayrıca, bir ad gönderirseniz ve kullanıcı düzenleme yapmayı seçerse Kişiler uygulaması, önceki değerin üzerine yazarak gönderdiğiniz adı gösterir. Kullanıcı bunu fark etmez ve düzenlemeyi kaydederse eski değer kaybolur.

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

Aşağıdaki snippet'te, yeni bir ham kişi ve veri ekleyen bir niyetin nasıl oluşturulup 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şiler deposu, kullanıcıların doğru ve güncel olmasını beklediği önemli ve hassas veriler içerdiğinden Kişiler Sağlayıcı'nın veri bütünlüğü için iyi tanımlanmış kuralları vardır. 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.
Bir ContactsContract.Data satırı ContactsContract.RawContacts ile bağlantılı değilse cihazın kişiler uygulamasında görünmez ve senkronizasyon bağdaştırıcılarıyla ilgili sorunlara neden olabilir.
Yalnızca sahibi olduğunuz ham kişilerin verilerini değiştirin.
Kişiler Sağlayıcı'nın genellikle çeşitli hesap türleri/online hizmetlerden gelen verileri yönettiğini unutmayın. Uygulamanızın yalnızca size ait satırlardaki verileri değiştirdiğinden veya sildiğinden ve yalnızca kontrol ettiğiniz bir hesap türü ve adıyla veri eklediğinden emin olmanız gerekir.
Yetkililer, içerik URI'leri, URI yolları, sütun adları, MIME türleri ve ContactsContract değerleri için her zaman ContactsContract ve alt sınıflarında tanımlanan sabitleri kullanın.TYPE
Bu sabitleri kullanmak hataları önlemenize yardımcı olur. Sabitlerden herhangi biri kullanımdan kaldırılırsa derleyici uyarılarıyla da bilgilendirilirsiniz.

Özel veri satırları

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

Özel verilerinizi göstermek için contacts.xml öğesini ve bu öğenin bir veya daha fazla <ContactsDataKind> alt öğesini içeren bir <ContactsAccountType> 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 edinmek için İçerik Sağlayıcı Oluşturma kılavuzunu inceleyin.

Contacts Provider senkronizasyon adaptörleri

Kişiler Sağlayıcı, özellikle bir cihaz ile bir online hizmet arasındaki kişi verilerinin senkronizasyonunu yönetmek için tasarlanmıştır. Bu sayede kullanıcılar, mevcut verileri yeni bir cihaza indirebilir ve yeni bir hesaba yükleyebilir. Senkronizasyon, eklemelerin ve değişikliklerin kaynağına bakılmaksızın kullanıcıların en son verilere erişmesini de sağlar. Senkronizasyonun bir diğer avantajı da cihaz ağa bağlı olmasa bile kişilerin kullanılabilmesidir.

Senkronizasyonu çeşitli şekillerde uygulayabilirsiniz. Ancak Android sistemi, aşağıdaki görevleri otomatik olarak gerçekleştiren bir eklenti senkronizasyon çerçevesi sağlar:

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

Bu çerçeveyi kullanmak için bir senkronizasyon bağdaştırıcısı eklentisi sağlarsınız. Her senkronizasyon bağdaştırıcısı bir hizmet ve içerik sağlayıcıya özeldir ancak aynı hizmet için birden fazla hesap adını işleyebilir. Çerçeve, aynı hizmet ve sağlayıcı için birden fazla senkronizasyon bağdaştırıcısına da izin verir.

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

Bir senkronizasyon bağdaştırıcısını AbstractThreadedSyncAdapter alt sınıfı olarak uygular ve Android uygulamasının bir parçası olarak yüklersiniz. Sistem, senkronizasyon bağdaştırıcısı hakkında bilgileri uygulama manifestinizdeki öğelerden ve manifestin işaret ettiği özel bir XML dosyasından edinir. XML dosyası, online hizmetin hesap türünü ve içerik sağlayıcının yetkisini tanımlar. Bu iki öğe 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 ekleyip senkronizasyon bağdaştırıcısının senkronize ettiğ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 sağlamak için gerektiğinde bağdaştırıcıyı çağırır.

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

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

  1. Kullanıcının adını, şifresini veya benzer bilgilerini (kullanıcı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 kullanılmak üzere saklayabilir. Eklenti kimlik doğrulayıcı çerçevesi sayesinde AccountManager, kimlik doğrulayıcının desteklediği ve kullanıma sunmayı seçtiği tüm kimlik doğrulama jetonlarına (ör. OAuth2 kimlik doğrulama jetonları) erişim sağlayabilir.

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

Senkronizasyon adaptörü uygulama

Kişi Sağlayıcı için bir senkronizasyon bağdaştırıcısı uygulamak üzere aşağıdaki öğeleri içeren bir Android uygulaması oluşturarak işe başlayın:

Sistemden gelen, senkronizasyon bağdaştırıcısına bağlanma isteklerine yanıt veren bir Service bileşeni.
Sistem bir senkronizasyon çalıştırmak istediğinde, senkronizasyon bağdaştırıcısı için bir IBinder almak üzere hizmetin onBind() yöntemini çağırır. Bu, sistemin bağdaştırıcının yöntemlerine süreçler arası çağrılar yapmasına olanak tanır.
AbstractThreadedSyncAdapter sınıfının somut bir alt sınıfı olarak uygulanan gerçek senkronizasyon adaptörü.
Bu sınıf, sunucudan veri indirme, cihazdan veri yükleme ve çakışmaları çözme işlemlerini yapar. Adaptörün ana işlevi onPerformSync() yönteminde yapılır. Bu sınıf, tekil örnek olarak oluşturulmalıdır.
Application öğesinin alt sınıfı.
Bu sınıf, senkronizasyon adaptörü tekil öğesi için fabrika görevi görür. Senkronizasyon bağdaştırıcısını oluşturmak için onCreate() yöntemini kullanın ve tekil öğeyi 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ı: Sistemden gelen kullanıcı kimlik doğrulama isteklerine yanıt veren bir Service bileşeni.
AccountManager, kimlik doğrulama sürecini başlatmak için bu hizmeti başlatır. Hizmetin onCreate() yöntemi, bir kimlik doğrulayıcı nesnesi oluşturur. Sistem, uygulamanın senkronizasyon bağdaştırıcısı için bir kullanıcı hesabının kimliğini doğrulamak istediğinde, kimlik doğrulayıcı için IBinder almak üzere hizmetin onBind() yöntemini çağırır. Bu, sistemin kimlik doğrulayıcının yöntemlerine süreçler arası çağrı yapmasına olanak tanır.
İsteğe bağlı: Kimlik doğrulama isteklerini işleyen AbstractAccountAuthenticator sınıfının somut bir alt sınıfı.
Bu sınıf, AccountManager tarafından kullanıcının kimlik bilgilerini sunucuyla doğrulamak için çağrılan yöntemler sağlar. Kimlik doğrulama sürecinin ayrıntıları, kullanılan sunucu teknolojisine bağlı olarak büyük ölçüde değişir. Kimlik doğrulama hakkında daha fazla bilgi edinmek için sunucu yazılımınızın belgelerine bakmanız gerekir.
Sisteme senkronizasyon bağdaştırıcısını ve kimlik doğrulayıcıyı tanımlayan XML dosyaları.
Daha önce açıklanan senkronizasyon bağdaştırıcısı ve kimlik doğrulayıcı hizmet bileşenleri, uygulama manifestindeki <service> öğelerinde tanımlanır. Bu öğeler, sisteme belirli veriler sağlayan <meta-data> alt öğelerini içerir:
  • Senkronizasyon bağdaştırıcısı hizmetinin <meta-data> öğesi, res/xml/syncadapter.xml XML dosyasına işaret eder. Bu dosya da sırasıyla Kişiler Sağlayıcı ile senkronize edilecek web hizmetinin URI'sini ve web hizmetinin hesap türünü belirtir.
  • İsteğe bağlı: Kimlik doğrulayıcı için <meta-data> öğesi, res/xml/authenticator.xml adlı XML dosyasına işaret eder. Bu dosya da 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 akış verileri

android.provider.ContactsContract.StreamItems ve android.provider.ContactsContract.StreamItemPhotos tabloları, sosyal ağlardan gelen verileri yönetir. Kendi ağınızdaki akış verilerini bu tablolara ekleyen bir senkronizasyon bağdaştırıcısı yazabilir veya bu tablolardaki akış verilerini okuyup kendi uygulamanızda gösterebilir ya da 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 bir ham kişiyle ilişkilendirilir. android.provider.ContactsContract.StreamItemsColumns#RAW_CONTACT_ID, ham kişi için _ID değerine bağlanır. Ham kişinin hesap türü ve hesap adı da akış öğesi satırında saklanır.

Yayın verilerinizi aşağıdaki sütunlarda saklayın:

android.provider.ContactsContract.StreamItemsColumns#ACCOUNT_TYPE
Zorunlu. Bu akış öğesiyle ilişkili ham kişi için kullanıcının hesap türü. Bir yayın öğesi eklerken bu değeri ayarlamayı unutmayın.
android.provider.ContactsContract.StreamItemsColumns#ACCOUNT_NAME
Zorunlu. Bu akış öğesiyle ilişkili ham kişi için kullanıcının hesap adı. Bir yayın öğesi eklerken bu değeri ayarlamayı unutmayın.
Tanımlayıcı sütunlar
Zorunlu. Bir yayın öğesi eklerken aşağıdaki tanımlayıcı sütunları eklemeniz gerekir:
  • android.provider.ContactsContract.StreamItemsColumns#CONTACT_ID: Bu akış öğesinin ilişkilendirildiği kişinin android.provider.BaseColumns#_ID değeri.
  • android.provider.ContactsContract.StreamItemsColumns#CONTACT_LOOKUP_KEY: Bu akış öğesinin ilişkili olduğu kişinin android.provider.ContactsContract.ContactsColumns#LOOKUP_KEY değeri.
  • android.provider.ContactsContract.StreamItemsColumns#RAW_CONTACT_ID: Bu akış öğesinin ilişkilendirildiği ham kişinin android.provider.BaseColumns#_ID değeri.
android.provider.ContactsContract.StreamItemsColumns#COMMENTS
İsteğe bağlıdır. Bir akış öğesinin başında gösterebileceğiniz özet bilgilerini saklar.
android.provider.ContactsContract.StreamItemsColumns#TEXT
Akış öğesinin metni. Bu metin, öğenin kaynağı tarafından yayınlanan içerik veya akış öğesini oluşturan bir işlemin açıklaması olabilir. Bu sütun, fromHtml() tarafından oluşturulabilen tüm biçimlendirmeleri ve yerleştirilmiş kaynak resimleri içerebilir. Sağlayıcı, uzun içerikleri kısaltabilir veya üç nokta ile gösterebilir ancak etiketleri bozmaktan kaçınmaya çalışır.
android.provider.ContactsContract.StreamItemsColumns#TIMESTAMP
Akış öğesinin eklendiği veya güncellendiği zamanı içeren bir metin dizesi. Bu dize, milisaniye cinsinden ve dönemin başlangıcından itibaren geçen süreyi ifade eder. Akış öğelerini ekleyen veya güncelleyen uygulamalar bu sütunun bakımından sorumludur. Bu sütun, Kişiler Sağlayıcı tarafından otomatik olarak korunmaz.

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

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

Sosyal akış fotoğrafları

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

android.provider.ContactsContract.StreamItemPhotos#PHOTO sütunu (BLOB).
Fotoğrafın, depolama ve görüntüleme için sağlayıcı tarafından yeniden boyutlandırılmış ikili gösterimi. Bu sütun, fotoğrafları depolamak için kullanılan Contacts Provider'ın önceki sürümleriyle geriye dönük uyumluluk için kullanılabilir. Ancak mevcut sürümde fotoğrafları depolamak için bu sütunu kullanmamalısınız. Bunun yerine, fotoğrafları dosyada depolamak için android.provider.ContactsContract.StreamItemPhotosColumns#PHOTO_FILE_ID veya android.provider.ContactsContract.StreamItemPhotosColumns#PHOTO_URI'yi (her ikisi de aşağıdaki noktalarda açıklanmıştır) kullanın. Bu sütunda artık okunabilir durumdaki fotoğrafın küçük resmi yer alıyor.
android.provider.ContactsContract.StreamItemPhotosColumns#PHOTO_FILE_ID
Bir ham kişi için fotoğrafın sayısal tanımlayıcısı. Bu değeri sabite ekleyerek DisplayPhoto.CONTENT_URI tek bir fotoğraf dosyasına işaret eden bir içerik URI'si elde edin ve ardından openAssetFileDescriptor() çağrısını yaparak fotoğraf dosyasının tutamacını alın.
android.provider.ContactsContract.StreamItemPhotosColumns#PHOTO_URI
Bu satırda gösterilen fotoğrafın doğrudan fotoğraf dosyasına yönlendiren bir içerik URI'si. Fotoğraf dosyası için bir tanıtıcı almak üzere bu URI ile openAssetFileDescriptor() işlevini çağırın.

Sosyal akış tablolarını kullanma

Bu tablolar, Kişiler Sağlayıcı'daki diğer ana tablolarla aynı şekilde çalışır ancak:

  • Bu tablolar için ek erişim izinleri gerekiyor. Uygulamanızın bu kaynaklardan okuma yapabilmesi için android.Manifest.permission#READ_SOCIAL_STREAM iznine sahip olması gerekir. Bunları değiştirmek için uygulamanızın android.Manifest.permission#WRITE_SOCIAL_STREAM iznine sahip olması gerekir.
  • android.provider.ContactsContract.StreamItems tablosu için 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şiler Sağlayıcı, en eski android.provider.ContactsContract.StreamItemsColumns#TIMESTAMP değerine 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 sorgu gönderin. İçerik URI'si dışındaki tüm bağımsız değişkenleri null olarak ayarlayabilirsiniz. Sorgu, tek bir satır içeren bir imleç döndürür. Bu satırda, tek sütun android.provider.ContactsContract.StreamItems#MAX_ITEMS bulunur.

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

Sosyal akış etkileşimleri

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

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

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

Sosyal ağ görüntülemelerini 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 için senkronizasyon bağdaştırıcınızı kaydetmek üzere:

  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 varsa bu adımı atlayabilirsiniz.
  3. Kullanıcı, cihazın Kişiler uygulamasında bir kişinin ayrıntılar sayfasını açtığında bildirilen bir hizmeti kaydetmek için öğesine viewContactNotifyService="serviceclass" özelliğini ekleyin. Burada serviceclass, cihazın Kişiler uygulamasından gelen amaçlı iletiyi alması gereken hizmetin tam nitelikli sınıf adıdır. Bildirim hizmeti için, hizmetin amaç almasına izin vermek üzere IntentService sınıfını genişleten bir sınıf kullanın. Gelen amaçtaki veriler, kullanıcının tıkladığı ham kişi URI'sini içerir. Bildirim hizmetinden, senkronizasyon bağdaştırıcınıza bağlanıp ham kişi verilerini güncellemek için onu çağırabilirsiniz.

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

  1. Projenizin res/xml/ dizininde contacts.xml adlı bir dosya oluşturun. Bu dosyaya zaten sahipseniz bu adımı atlayabilirsiniz.
  2. Bu dosyaya <ContactsAccountType xmlns:android="http://schemas.android.com/apk/res/android"> öğesini ekleyin. Bu öğe zaten varsa bu adımı atlayabilirsiniz.
  3. Etkinliklerinizden birini, kullanıcının cihazın Kişiler uygulamasında bir yayın öğesini tıklamasını işleyecek şekilde kaydetmek için öğeye viewStreamItemActivity="activityclass" özelliğini ekleyin. Burada activityclass, cihazın Kişiler uygulamasından gelen amaçlı işlemi alması gereken etkinliğin tam nitelikli sınıf adıdır.
  4. Etkinliklerinizden birini, kullanıcının cihazın Kişiler uygulamasında bir akış fotoğrafını tıklamasını işleyecek şekilde kaydetmek için öğeye viewStreamItemPhotoActivity="activityclass" özelliğini ekleyin. Burada activityclass, cihazın Kişiler uygulamasından gelen amaçlı işlemin alınması gereken etkinliğin tam nitelikli sınıf adıdır.

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

Gelen amaç, kullanıcının tıkladığı öğenin veya fotoğrafın içerik URI'sini içerir. Metin öğeleri ve fotoğraflar için ayrı etkinlikler oluşturmak istiyorsanız 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 çıkması gerekmez. Bunun yerine, cihazın Kişiler uygulamasının, kişiyi etkinliklerinizden birine davet etme amaçlı bir ileti 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 varsa bu adımı atlayabilirsiniz.
  3. Aşağıdaki özellikleri ekleyin:
    • inviteContactActivity="activityclass"
    • inviteContactActionLabel="@string/invite_action_label"
    activityclass değeri, amaca yönelik işlemi 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österilen bir metin dizesidir.

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

contacts.xml referansı

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

<ContactsAccountType> öğesi

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

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

içerdiği:

res/xml/contacts.xml

içerebilir:

<ContactsDataKind>

Açıklama:

Kullanıcıların bir kişisini 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 bildirir.

android: özellik önekinin <ContactsAccountType> özelliklerinde gerekli olmadığını unutmayın.

Özellikler:

inviteContactActivity
Kullanıcı, cihazın kişiler uygulamasından Bağlantı ekle'yi seçtiğinde etkinleştirmek istediğiniz uygulamanızdaki etkinliğin tam sınıf adı.
inviteContactActionLabel
inviteContactActivity içinde belirtilen etkinlik için Bağlantı ekle menüsünde gösterilen bir metin dizesi. Örneğin, "Ağımda takip et" dizesini kullanabilirsiniz. Bu etiket için bir 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 sınıf adı. Bu bildirim, cihazın kişiler uygulaması tarafından gönderilir. Uygulamanızın, veri yoğun işlemlerini ihtiyaç duyulana kadar ertelemesine olanak tanır. Örneğin, uygulamanız bu bildirime, kişinin yüksek çözünürlüklü fotoğrafını ve en son sosyal akış öğelerini okuyup görüntüleyerek yanıt verebilir. Bu özellik, Sosyal medya akışı etkileşimleri bölümünde daha ayrıntılı olarak açıklanmıştır.
viewGroupActivity
Uygulamanızda grup bilgilerini gösterebilen bir etkinliğin tam 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österilir.
viewGroupActionLabel
Kişiler uygulamasının, kullanıcının uygulamanızdaki gruplara bakmasına olanak tanıyan bir kullanıcı arayüzü kontrolü için gösterdiği etiket.

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

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

<ContactsDataKind> öğesi

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

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

içerdiği:

<ContactsAccountType>

Açıklama:

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

Özellikler:

android:mimeType
ContactsContract.Data tablosunda özel veri satırı türlerinizden biri için tanımladığınız özel MIME türü. Örneğin, değer vnd.android.cursor.item/vnd.example.locationstatus, 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 drawable kaynağı. Bunu, verilerin hizmetinizden geldiğini kullanıcıya belirtmek için kullanın.
android:summaryColumn
Veri satırından alınan iki değerden ilkinin sütun adı. Değer, bu veri satırının girişi için ilk satır olarak gösterilir. İlk satır, verilerin özeti olarak kullanılmak üzere tasarlanmıştır ancak bu isteğe bağlıdır. Ayrıca bkz. android:detailColumn.
android:detailColumn
Veri satırından alınan iki değerden ikincisinin sütun adı. Değer, bu veri satırının girişi için ikinci satır olarak gösterilir. Ayrıca android:summaryColumn sayfasına göz atın.

Ek Kişiler Sağlayıcı özellikleri

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

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

Kişi grupları

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

Sunucudan Kişiler Sağlayıcı'ya ham kişi verileri ekleyecek bir senkronizasyon bağdaştırıcısı tasarlıyorsanız ve grupları kullanmıyorsanız sağlayıcıya verilerinizi görünür hale getirmesini söylemeniz gerekir. Kullanıcı cihaza hesap eklediğinde yürütülen kodda, Kişiler 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, grupları kullanmasanız bile Kişiler Sağlayıcı, kişi verilerinizi her zaman görünür hale getirir.

Kişi fotoğrafları

ContactsContract.Data tablosunda fotoğraflar, MIME türü Photo.CONTENT_ITEM_TYPE olan satırlar olarak depolanır. Satırın CONTACT_ID sütunu, ait olduğu ham kişinin _ID sütununa bağlanır. ContactsContract.Contacts.Photo sınıfı, bir kişinin birincil fotoğrafının fotoğraf bilgilerini içeren ContactsContract.Contacts alt tablosunu tanımlar. Bu fotoğraf, kişinin birincil ham kişisinin birincil fotoğrafıdır. Benzer şekilde, ContactsContract.RawContacts.DisplayPhoto sınıfı, bir ham kişinin birincil fotoğrafının fotoğraf bilgilerini içeren ContactsContract.RawContacts alt tablosunu tanımlar.

ContactsContract.Contacts.Photo ve ContactsContract.RawContacts.DisplayPhoto ile ilgili referans dokümanlarında fotoğraf bilgilerini alma örnekleri yer alır. Bir ham kişinin birincil küçük resmini almak için kolaylık sınıfı yoktur ancak ham kişinin birincil fotoğraf satırını bulmak için ContactsContract.Data tablosuna sorgu gönderebilirsiniz. Bu sorguda, ham kişinin _ID, Photo.CONTENT_ITEM_TYPE ve IS_PRIMARY sütunlarını seçmeniz gerekir.

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