Bir kişinin ayrıntılarını alma

Bu derste, bir kişinin e-posta adresi ve telefon numarası gibi ayrıntı verilerinin nasıl alınacağı gösterilmektedir. Bunlar, kullanıcıların bir kişiyi alırken aradıkları ayrıntılardır. Bu kullanıcılara bir kişiyle ilgili tüm ayrıntıları verebilir veya yalnızca belirli bir türdeki ayrıntıları görüntüleyebilirsiniz. e-posta adresleri gibi.

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şi listesini alır.

Bir kişinin tüm ayrıntılarını alma

Bir kişiyle ilgili tüm ayrıntıları almak için ContactsContract.Data kişinin LOOKUP_KEY. Bu sütunun kullanılabildiği yerler: ContactsContract.Data tablosu, çünkü Kişiler Sağlayıcı, ContactsContract.Contacts arasında örtülü birleştirme yapar. tablosunu ve ContactsContract.Data tablosunu seçeceğim. İlgili içeriği oluşturmak için kullanılan LOOKUP_KEY sütunu açıklandı daha ayrıntılı olarak Kişi adlarını alma dersinde bulabilirsiniz.

Not: Bir kişinin tüm ayrıntılarını almak, ContactsContract.Data tablosundaki tüm sütunları alması gerektiğinden cihazın performansını düşürür. Bu tekniği kullanmadan önce performans üzerindeki etkisini düşünün.

İzin iste

Kişiler sağlayıcısından veri okumak için uygulamanızın READ_CONTACTS iznine sahip olması gerekir. Bu izni istemek için aşağıdaki alt öğesini ekleyin: Manifest dosyanıza <manifest> 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ı tahmininize ekleyin. Cursor sonucunu bir ListView ile bağlarken her zaman Data._ID'yi alın. Aksi takdirde bağlama işlemi çalışmaz. Data.MIMETYPE öğesini de al böylece aldığınız her satırın veri türünü tanımlayabilirsiniz. Ö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. 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 değer, seçim bağımsız değişkenlerini tutacak bir dizi ve bir değişkeni kullanabilirsiniz. Tekliflerinizi otomatikleştirmek ve optimize etmek için Contacts.LOOKUP_KEY sütununu bulabilirsiniz. Ö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ığı.

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ı birlikte, tüm telefon satırlarını bir arada gruplandırır ve bu şekilde devam eder. Ö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ürleri alt tür kullanmaz. Bu nedenle, 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. Zaman imleci okumayı bitirdikten sonra, her bir veri türünü alt türe göre sıralayabilir ve sonuç.

Yükleyiciyi Başlatma

Kişi Sağlayıcı'dan (ve diğer tüm içerik sağlayıcılardan) almaları her zaman arka plan ileti dizisi. 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 yükleyici çerçevesini şu şekilde başlatın: initLoader() aranıyor. Yönteme bir tam sayı tanımlayıcısı gönderin. Bu tanımlayıcı, LoaderManager.LoaderCallbacks yöntemlerine iletilir. Tanımlayıcı, İkisini birbirinden ayırt etmenizi sağlayarak uygulamada birden çok yükleyici kullanma.

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. Arama yaptığınız için ContactsContract.Data tablosu için sabiti kullanın Data.CONTENT_URI olarak ayarlayı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() yöntemlerini uygulama

onLoadFinished() yöntemini uygulayın. Yükleyici çerçevesi onLoadFinished(). Kişi Sağlayıcı sorgunun sonuçlarını döndürdüğünde. Ö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 mevcut referansları kaldırın. null değerine ayarlayarak Cursor öğesine ekleyin. Yüklemezseniz, yükleyici çerçeve, eski Cursor aracını yok etmez ve bununla ilgili bir hafıza sızıntısı. Ö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şinin belirli bir veri türünü (ör. tüm e-postalar) alırken aynı kalıp kullanılır. alınan bir dosyadır. Kodda yalnızca bu değişiklikleri yapmanız gerekir Bir kişiyle ilgili tüm ayrıntıları alma bölümünde listelenir:

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
. Şu öğeyi aramak için seçim metnini değiştirin: Şuna özel MIMETYPE değeri: en iyi uygulamaları görelim.
Sıralama şekli
Yalnızca tek bir ayrıntı türü seçtiğiniz için döndürülen Cursor öğelerini Data.MIMETYPE'ye göre 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ımlama

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. MIMETYPE değerini içine alın "'" ekleyerek tek tırnak işareti başına ve sonuna tek tırnak (tek tırnak) karakteri ekleyin sabitin değeri; Aksi takdirde, sağlayıcı sabit değeri yerine bir değişken adı çok daha kolay bulunur. Bu değer için yer tutucu kullanmanız gerekmez; değer yerine sabit bir değer kullanarak doğrulayabilirsiniz. Ö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 ölçütü 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 bu türe göre sıralayın. Örneğin, e-posta verileri için şu ölçütlere göre sıralama yapabilirsiniz: Email.TYPE

Kotlin

private const val SORT_ORDER: String = "${Email.TYPE} ASC"

Java

    private static final String SORT_ORDER = Email.TYPE + " ASC ";