Bu derste, bir kişinin e-posta adresi ve telefon numarası gibi ayrıntı verilerinin nasıl alınacağı gösterilmektedir. Kullanıcıların bir kişiyi alırken aradığı ayrıntılardır. Kişilerle ilgili tüm ayrıntıları paylaşabilir veya yalnızca belirli bir türdeki ayrıntıları (ör. e-posta adresleri) gösterebilirsiniz.
Bu dersteki adımlarda, kullanıcının seçtiği bir kişi için zaten bir ContactsContract.Contacts
satırınız olduğu varsayılır.
Kişi adlarını alma dersinde, kişilerin listesinin nasıl alınacağı gösterilmektedir.
Bir kişinin tüm ayrıntılarını alma
Bir kişinin tüm ayrıntılarını almak için ContactsContract.Data
tablosunda, kişinin LOOKUP_KEY
değerini içeren satırları arayın. Kişi Sağlayıcı, ContactsContract.Contacts
tablosu ile ContactsContract.Data
tablosu arasında implicit bir birleştirme yaptığından bu sütun ContactsContract.Data
tablosunda kullanılabilir. LOOKUP_KEY
sütunu, Kişi adlarını alma dersinde daha ayrıntılı olarak açıklanmıştır.
Not: Bir kişinin tüm ayrıntılarının alınması, ContactsContract.Data
tablosundaki tüm sütunları alması gerekeceğinden
cihazın performansını düşürür. Bu tekniği kullanmadan önce performans üzerindeki etkisini düşünün.
İzin isteme
Kişi Sağlayıcı'dan veri okumak için uygulamanızın READ_CONTACTS
izni olması gerekir.
Bu izni istemek için manifest dosyanıza
<manifest>
öğesinin aşağıdaki alt öğesini ekleyin:
<uses-permission android:name="android.permission.READ_CONTACTS" />
Projeksiyon oluşturma
Bir satırın içerdiği veri türüne bağlı olarak yalnızca birkaç sütun veya çok sayıda sütun kullanabilir. Ayrıca veriler, veri türüne bağlı olarak farklı sütunlarda bulunur.
Olası tüm veri türleri için olası tüm sütunları aldığınızdan emin olmak amacıyla tüm sütun adlarını projenize eklemeniz gerekir. Cursor
sonucunu bir ListView
ile bağlıyorsanız Data._ID
öğesini her zaman alın. Aksi takdirde bağlama çalışmaz. Ayrıca, aldığınız her bir satırın veri türünü tanımlayabilmeniz için Data.MIMETYPE
değerini de alın. Örnek:
Kotlin
private val PROJECTION: Array<out String> = arrayOf( ContactsContract.Data._ID, ContactsContract.Data.MIMETYPE, ContactsContract.Data.DATA1, ContactsContract.Data.DATA2, ContactsContract.Data.DATA3, ContactsContract.Data.DATA4, ContactsContract.Data.DATA5, ContactsContract.Data.DATA6, ContactsContract.Data.DATA7, ContactsContract.Data.DATA8, ContactsContract.Data.DATA9, ContactsContract.Data.DATA10, ContactsContract.Data.DATA11, ContactsContract.Data.DATA12, ContactsContract.Data.DATA13, ContactsContract.Data.DATA14, ContactsContract.Data.DATA15 )
Java
private static final String[] PROJECTION = { ContactsContract.Data._ID, ContactsContract.Data.MIMETYPE, ContactsContract.Data.DATA1, ContactsContract.Data.DATA2, ContactsContract.Data.DATA3, ContactsContract.Data.DATA4, ContactsContract.Data.DATA5, ContactsContract.Data.DATA6, ContactsContract.Data.DATA7, ContactsContract.Data.DATA8, ContactsContract.Data.DATA9, ContactsContract.Data.DATA10, ContactsContract.Data.DATA11, ContactsContract.Data.DATA12, ContactsContract.Data.DATA13, ContactsContract.Data.DATA14, ContactsContract.Data.DATA15 };
Bu projeksiyon, ContactsContract.Data
sınıfında tanımlanan sütun adlarını kullanarak ContactsContract.Data
tablosundaki bir satırın tüm sütunlarını alır.
İsteğe bağlı olarak, ContactsContract.Data
sınıfında tanımlanan veya bu sınıf tarafından devralınan diğer tüm sütun sabitlerini de kullanabilirsiniz. Ancak SYNC1
ile SYNC4
arasındaki sütunların senkronizasyon adaptörleri tarafından kullanılması amaçlandığından bu sütunların verilerinin yararlı olmadığını unutmayın.
Seçim ölçütlerini tanımlama
Seçim ifadeniz için bir sabit, seçim bağımsız değişkenlerini tutacak bir dizi ve seçim değerini tutacak bir değişken tanımlayın. Kişiyi bulmak için Contacts.LOOKUP_KEY
sütununu kullanın. Örnek:
Kotlin
// Defines the selection clause private const val SELECTION: String = "${ContactsContract.Data.LOOKUP_KEY} = ?" ... // Defines the array to hold the search criteria private val selectionArgs: Array<String> = arrayOf("") /* * Defines a variable to contain the selection value. Once you * have the Cursor from the Contacts table, and you've selected * the desired row, move the row's LOOKUP_KEY value into this * variable. */ private var lookupKey: String? = null
Java
// Defines the selection clause private static final String SELECTION = Data.LOOKUP_KEY + " = ?"; // Defines the array to hold the search criteria private String[] selectionArgs = { "" }; /* * Defines a variable to contain the selection value. Once you * have the Cursor from the Contacts table, and you've selected * the desired row, move the row's LOOKUP_KEY value into this * variable. */ private lateinit var lookupKey: String
Seçim metin ifadenizde yer tutucu olarak "?" kullanmak, ortaya çıkan aramanın SQL derlemesi yerine bağlama ile oluşturulmasını sağlar. Bu yaklaşım, kötü amaçlı SQL yerleştirme olasılığını ortadan kaldırır.
Sıralama düzenini tanımlama
Elde edilen Cursor
içinde istediğiniz sıralama düzenini tanımlayın. Belirli bir veri türünün tüm satırlarını birlikte tutmak için Data.MIMETYPE
'ye göre sıralayın. Bu sorgu bağımsız değişkeni, tüm e-posta satırlarını, tüm telefon satırlarını vb. birlikte gruplandırır. Örnek:
Kotlin
/* * Defines a string that specifies a sort order of MIME type */ private const val SORT_ORDER = ContactsContract.Data.MIMETYPE
Java
/* * Defines a string that specifies a sort order of MIME type */ private static final String SORT_ORDER = ContactsContract.Data.MIMETYPE;
Not: Bazı veri türlerinde alt tür kullanılmadığından alt türe göre sıralama yapamazsınız.
Bunun yerine, döndürülen Cursor
öğesini iterasyonla incelemeniz, mevcut satırın veri türünü belirlemeniz ve alt tür kullanan satırlara ait verileri saklamanız gerekir. İmleci okumayı tamamladığınızda her veri türünü alt türe göre sıralayabilir ve sonuçları görüntüleyebilirsiniz.
Yükleyiciyi başlatma
Kişiler Sağlayıcı'dan (ve diğer tüm içerik sağlayıcılardan) veri alma işlemlerini her zaman arka plan iş parçacığında yapın. Arka planda getirme işlemleri yapmak için LoaderManager
sınıfı ve LoaderManager.LoaderCallbacks
arayüzü tarafından tanımlanan Loader çerçevesini kullanın.
Satırları almaya hazır olduğunuzda initLoader()
işlevini çağırarak yükleyici çerçevesini başlatın. Yönteme bir tam sayı tanımlayıcısı gönderin. Bu tanımlayıcı, LoaderManager.LoaderCallbacks
yöntemlerine iletilir. Tanımlayıcı, aralarında bir fark olmasını sağlayarak bir uygulamada birden fazla yükleyici kullanmanıza yardımcı olur.
Aşağıdaki snippet'te, yükleyici çerçevesinin nasıl başlatılacağı gösterilmektedir:
Kotlin
// Defines a constant that identifies the loader private const val DETAILS_QUERY_ID: Int = 0 class DetailsFragment : Fragment(), LoaderManager.LoaderCallbacks<Cursor> { ... override fun onCreate(savedInstanceState: Bundle?) { ... // Initializes the loader framework loaderManager.initLoader(DETAILS_QUERY_ID, null, this)
Java
public class DetailsFragment extends Fragment implements LoaderManager.LoaderCallbacks<Cursor> { ... // Defines a constant that identifies the loader static int DETAILS_QUERY_ID = 0; ... @Override public void onCreate(Bundle savedInstanceState) { ... // Initializes the loader framework getLoaderManager().initLoader(DETAILS_QUERY_ID, null, this);
onCreateLoader() işlevini uygulama
initLoader()
çağrısından hemen sonra yükleyici çerçevesi tarafından çağrılan onCreateLoader()
yöntemini uygulayın. Bu yöntemden bir CursorLoader
döndürür. ContactsContract.Data
tablosunu aradığınız için içerik URI'si olarak Data.CONTENT_URI
sabit değerini kullanın.
Örnek:
Kotlin
override fun onCreateLoader(loaderId: Int, args: Bundle?): Loader<Cursor> { // Choose the proper action mLoader = when(loaderId) { DETAILS_QUERY_ID -> { // Assigns the selection parameter selectionArgs[0] = lookupKey // Starts the query activity?.let { CursorLoader( it, ContactsContract.Data.CONTENT_URI, PROJECTION, SELECTION, selectionArgs, SORT_ORDER ) } } ... } return mLoader }
Java
@Override public Loader<Cursor> onCreateLoader(int loaderId, Bundle args) { // Choose the proper action switch (loaderId) { case DETAILS_QUERY_ID: // Assigns the selection parameter selectionArgs[0] = lookupKey; // Starts the query CursorLoader mLoader = new CursorLoader( getActivity(), ContactsContract.Data.CONTENT_URI, PROJECTION, SELECTION, selectionArgs, SORT_ORDER ); }
onLoadFinished() ve onLoaderReset() işlevlerini uygulama
onLoadFinished()
yöntemini uygulayın. Yükleyici çerçevesi, Kişi Sağlayıcı sorgunun sonuçlarını döndürdüğünde onLoadFinished()
işleyicisini çağırır. Örnek:
Kotlin
override fun onLoadFinished(loader: Loader<Cursor>, data: Cursor) { when(loader.id) { DETAILS_QUERY_ID -> { /* * Process the resulting Cursor here. */ } ... } }
Java
@Override public void onLoadFinished(Loader<Cursor> loader, Cursor cursor) { switch (loader.getId()) { case DETAILS_QUERY_ID: /* * Process the resulting Cursor here. */ } break; ... } }
Yükleyici çerçevesi, Cursor
sonucunu destekleyen verilerin değiştiğini algıladığında onLoaderReset()
yöntemi çağrılır. Bu noktada, Cursor
'ye yapılan mevcut referansları null olarak ayarlayarak kaldırın. Aksi takdirde, yükleyici çerçevesi eski Cursor
öğesini yok etmez ve bellek sızıntısı yaşarsınız. Örnek:
Kotlin
override fun onLoaderReset(loader: Loader<Cursor>) { when (loader.id) { DETAILS_QUERY_ID -> { /* * If you have current references to the Cursor, * remove them here. */ } ... } }
Java
@Override public void onLoaderReset(Loader<Cursor> loader) { switch (loader.getId()) { case DETAILS_QUERY_ID: /* * If you have current references to the Cursor, * remove them here. */ } break; }
Bir kişiyle ilgili belirli ayrıntıları alma
Bir kişi için belirli bir veri türünü (ör. tüm e-postalar) almak, tüm ayrıntıları almayla aynı kalıbı izler. Bir kişinin tüm ayrıntılarını alma bölümünde listelenen kodda yapmanız gereken tek değişiklikler şunlardır:
- Projeksiyon
-
Projeksiyonunuzu, veri türüne özgü sütunları almak için değiştirin. Ayrıca, projeksiyonu veri türüne karşılık gelen
ContactsContract.CommonDataKinds
alt sınıfında tanımlanan sütun adı sabitlerini kullanacak şekilde değiştirin. - Seçim
-
Seçim metnini, veri türünüze özgü
MIMETYPE
değerini aramak için değiştirin. - Sıralama şekli
-
Yalnızca tek bir ayrıntı türü seçtiğiniz için döndürülen
Cursor
öğesiniData.MIMETYPE
ile gruplandırmayın.
Bu değişiklikler aşağıdaki bölümlerde açıklanmıştır.
Projeksiyon tanımlama
Veri türü için ContactsContract.CommonDataKinds
alt sınıfındaki sütun adı sabitlerini kullanarak almak istediğiniz sütunları tanımlayın.
Cursor
öğenizi bir ListView
öğesine bağlamayı planlıyorsanız _ID
sütununu aldığınızdan emin olun. Örneğin, e-posta verilerini almak için aşağıdaki projeksiyonu tanımlayın:
Kotlin
private val PROJECTION: Array<String> = arrayOf( ContactsContract.CommonDataKinds.Email._ID, ContactsContract.CommonDataKinds.Email.ADDRESS, ContactsContract.CommonDataKinds.Email.TYPE, ContactsContract.CommonDataKinds.Email.LABEL )
Java
private static final String[] PROJECTION = { ContactsContract.CommonDataKinds.Email._ID, ContactsContract.CommonDataKinds.Email.ADDRESS, ContactsContract.CommonDataKinds.Email.TYPE, ContactsContract.CommonDataKinds.Email.LABEL };
Bu projeksiyonda, ContactsContract.Data
sınıfında tanımlanan sütun adları yerine ContactsContract.CommonDataKinds.Email
sınıfında tanımlanan sütun adlarının kullanıldığını unutmayın. E-postaya özgü sütun adlarını kullanmak, kodu daha okunaklı hale getirir.
Projeksiyonda, ContactsContract.CommonDataKinds
alt sınıfında tanımlanan diğer sütunlardan herhangi birini de kullanabilirsiniz.
Seçim ölçütlerini tanımlayın
Belirli bir kişinin LOOKUP_KEY
ve istediğiniz ayrıntıların Data.MIMETYPE
için satırları döndüren bir arama metni ifadesi tanımlayın. Sabitin başına ve sonuna "'
" (tek tırnak) karakteri ekleyerek MIMETYPE
değerini tek tırnak içine alın. Aksi takdirde sağlayıcı, sabit değeri dize değeri olarak değil, değişken adı olarak yorumlar. Kullanıcı tarafından sağlanan bir değer yerine sabit bir değer kullandığınız için bu değer için yer tutucu kullanmanız gerekmez. Örnek:
Kotlin
/* * Defines the selection clause. Search for a lookup key * and the Email MIME type */ private const val SELECTION = "${ContactsContract.Data.LOOKUP_KEY} = ? AND " + "${ContactsContract.Data.MIMETYPE} = '${Email.CONTENT_ITEM_TYPE}'" ... // Defines the array to hold the search criteria private val selectionArgs: Array<String> = arrayOf("")
Java
/* * Defines the selection clause. Search for a lookup key * and the Email MIME type */ private static final String SELECTION = Data.LOOKUP_KEY + " = ?" + " AND " + Data.MIMETYPE + " = " + "'" + Email.CONTENT_ITEM_TYPE + "'"; // Defines the array to hold the search criteria private String[] selectionArgs = { "" };
Sıralama düzeni tanımlama
Döndürülen Cursor
için bir sıralama düzeni tanımlayın. Belirli bir veri türünü döndürdüğünüz için MIMETYPE
üzerinde sıralamayı çıkarın.
Bunun yerine, aradığınız ayrıntı verisi türü bir alt tür içeriyorsa, buna göre sıralama yapın.
Örneğin, e-posta verileri için şuna göre sıralayabilirsiniz:
Email.TYPE
:
Kotlin
private const val SORT_ORDER: String = "${Email.TYPE} ASC"
Java
private static final String SORT_ORDER = Email.TYPE + " ASC ";