Kişiler listesini alma

Bu derste, verileri bir grubun tamamı veya bir kısmıyla eşleşen kişilerin listesini nasıl arama dizesini girin:

Kişi adlarını eşleştir
Arama dizesini, kişi adı verilerinin tamamı veya bir kısmıyla eşleştirerek kişilerin listesini alın. Kişi Sağlayıcı aynı adın birden çok örneğine izin verir. Bu nedenle teknik bir eşleşme listesi döndürebilir.
Telefon numarası gibi belirli bir veri türüyle eşleştirme
. Arama dizesini belirli bir ayrıntı türüyle eşleştirerek bir kişi listesi alın bir e-posta adresi gibi verilerdir. Örneğin, bu teknik sayesinde e-posta adresi arama dizesine eşleşen tüm kişileri listeleyebilirsiniz.
Herhangi bir veri türüyle eşleşir
Arama dizesini ad, telefon numarası, açık adres, e-posta adresi vb. dahil olmak üzere herhangi bir ayrıntı veri türüyle eşleştirerek kişilerin listesini alın. Örneğin, bu teknik, bir arama dizesi için her tür veriyi kabul etmenize ve daha sonra Verilerin dizeyle eşleştiği kişiler.

Not: Bu dersteki tüm örneklerde, Contacts Provider'dan veri almak için bir CursorLoader kullanılır. CursorLoader, sorgusunu kullanıcı arayüzü mesaj dizisinden ayrı bir mesaj dizisinde çalıştırır. Bu, sorgunun kullanıcı arayüzünü yavaşlatmamasını sağlar. ve olumsuz bir kullanıcı deneyimine yol açabilir. Daha fazla bilgi için bkz. Android eğitim dersi Arka Planda Veri Yükleme.

Sağlayıcıyı okuma izni iste

Kişi Sağlayıcı'da herhangi bir arama yapmak için uygulamanızın READ_CONTACTS izni. Bunu istemek için şunu ekleyin: <uses-permission>. öğesini manifest dosyanıza şunun alt öğesi olarak ekleyin: <manifest>:

    <uses-permission android:name="android.permission.READ_CONTACTS" />

Bir kişiyi ada göre eşleştirme ve sonuçları listeleme

Bu teknik, arama dizesini yer alan kişi veya kişilerin adıyla eşleştirmeye çalışır. Kişi Sağlayıcının ContactsContract.Contacts tablosu. Genellikle kullanıcının eşleşen kişiler arasından seçim yapmasına izin vermek için sonuçları bir ListView içinde görüntülemek istersiniz.

ListView'u ve öğe düzenlerini tanımlama

Arama sonuçlarını ListView içinde görüntülemek için ListView dahil olmak üzere kullanıcı arayüzünün tamamını tanımlayan bir ana düzen dosyasına ve ListView'nin bir satırını tanımlayan bir öğe düzeni dosyasına ihtiyacınız vardır. Örneğin, aşağıdaki XML ile ana düzen dosyasını res/layout/contacts_list_view.xml oluşturabilirsiniz:

<?xml version="1.0" encoding="utf-8"?>
<ListView xmlns:android="http://schemas.android.com/apk/res/android"
          android:id="@android:id/list"
          android:layout_width="match_parent"
          android:layout_height="match_parent"/>

Bu XML, yerleşik Android ListView widget'ını kullanır android:id/list.

contacts_list_item.xml öğe düzen dosyasını aşağıdaki XML ile tanımlayın:

<?xml version="1.0" encoding="utf-8"?>
<TextView xmlns:android="http://schemas.android.com/apk/res/android"
          android:id="@android:id/text1"
          android:layout_width="match_parent"
          android:layout_height="wrap_content"
          android:clickable="true"/>

Bu XML, yerleşik Android TextView widget'ını kullanır android:text1.

Not: Bu derste, kullanıcıdan arama dizesi almak için kullanılan kullanıcı arayüzü açıklanmaz. Bunun nedeni, dizeyi dolaylı olarak almak istemenizdir. Örneğin, kullanıcıya adı, gelen kısa mesajdaki bir dizeyle eşleşen kişileri arama seçeneği.

Yazdığınız iki düzen dosyası, ListView gösteren bir kullanıcı arayüzü tanımlar. Sıradaki adım, bir web sitesini ziyaret etmek için bu kullanıcı arayüzünü kullanan kişi listesi.

Kişilerin listesini görüntüleyen bir Parça tanımlayın

Kişi listesini görüntülemek için bir Fragment tanımlayarak başlayın bir Activity tarafından yüklenir. Bir Fragment daha esnek bir tekniktir çünkü Listeyi görüntülemek için bir Fragment, ikincisi Kullanıcının görüntülediği kişinin bilgilerini görüntülemek için Fragment seçim yapar. Bu yaklaşımı kullanarak, bu derste sunulan tekniklerden birini Bir kişinin ayrıntılarını alma dersindeki bir teknikle birleştirebilirsiniz.

Bir veya daha fazla Fragment nesnesinin nasıl kullanılacağını öğrenmek için Activity, eğitim kursunu okuyun Parçalar ile dinamik bir kullanıcı arayüzü oluşturun.

Kişi Sağlayıcısı'na göre sorgu yazmanıza yardımcı olmak için Android çerçevesi yararlı tanımlayan ContactsContract adlı bir sözleşme sınıfı sabit değerleri ve sağlayıcıya erişme yöntemleridir. Bu sınıfı kullanırken şunları yapmanız gerekmez: içerik URI'leri, tablo adları veya sütunlar için kendi sabit değerlerinizi tanımlayın. Bu sınıfı kullanmak için aşağıdaki beyanı ekleyin:

Kotlin

import android.provider.ContactsContract

Java

import android.provider.ContactsContract;

Kod, verileri almak için CursorLoader kullandığından API'nin yükleyici arayüzünü uyguladığını belirtmeniz gerekir LoaderManager.LoaderCallbacks. Ayrıca, kullanıcının arama sonuçları listesinden hangi kişiyi seçtiğini tespit etmek için AdapterView.OnItemClickListener bağdaştırıcı arayüzünü uygulayın. Örnek:

Kotlin

...
import android.support.v4.app.Fragment
import android.support.v4.app.LoaderManager
import android.widget.AdapterView
...
class ContactsFragment :
        Fragment(),
        LoaderManager.LoaderCallbacks<Cursor>,
        AdapterView.OnItemClickListener {

Java

...
import android.support.v4.app.Fragment;
import android.support.v4.app.LoaderManager.LoaderCallbacks;
import android.widget.AdapterView;
...
public class ContactsFragment extends Fragment implements
        LoaderManager.LoaderCallbacks<Cursor>,
        AdapterView.OnItemClickListener {

Genel değişkenleri tanımlama

Kodun diğer bölümlerinde kullanılan genel değişkenleri tanımlayın:

Kotlin

...
/*
 * Defines an array that contains column names to move from
 * the Cursor to the ListView.
 */
@SuppressLint("InlinedApi")
private val FROM_COLUMNS: Array<String> = arrayOf(
        if ((Build.VERSION.SDK_INT >= Build.VERSION_CODES.HONEYCOMB)) {
            ContactsContract.Contacts.DISPLAY_NAME_PRIMARY
        } else {
            ContactsContract.Contacts.DISPLAY_NAME
        }
)
/*
 * Defines an array that contains resource ids for the layout views
 * that get the Cursor column contents. The id is pre-defined in
 * the Android framework, so it is prefaced with "android.R.id"
 */
private val TO_IDS: IntArray = intArrayOf(android.R.id.text1)
...
class ContactsFragment :
        Fragment(),
        LoaderManager.LoaderCallbacks<Cursor>,
        AdapterView.OnItemClickListener {
    ...
    // Define global mutable variables
    // Define a ListView object
    lateinit var contactsList: ListView
    // Define variables for the contact the user selects
    // The contact's _ID value
    var contactId: Long = 0
    // The contact's LOOKUP_KEY
    var contactKey: String? = null
    // A content URI for the selected contact
    var contactUri: Uri? = null
    // An adapter that binds the result Cursor to the ListView
    private val cursorAdapter: SimpleCursorAdapter? = null

Java

    ...
    /*
     * Defines an array that contains column names to move from
     * the Cursor to the ListView.
     */
    @SuppressLint("InlinedApi")
    private final static String[] FROM_COLUMNS = {
            Build.VERSION.SDK_INT
                    >= Build.VERSION_CODES.HONEYCOMB ?
                    ContactsContract.Contacts.DISPLAY_NAME_PRIMARY :
                    ContactsContract.Contacts.DISPLAY_NAME
    };
    /*
     * Defines an array that contains resource ids for the layout views
     * that get the Cursor column contents. The id is pre-defined in
     * the Android framework, so it is prefaced with "android.R.id"
     */
    private final static int[] TO_IDS = {
           android.R.id.text1
    };
    // Define global mutable variables
    // Define a ListView object
    ListView contactsList;
    // Define variables for the contact the user selects
    // The contact's _ID value
    long contactId;
    // The contact's LOOKUP_KEY
    String contactKey;
    // A content URI for the selected contact
    Uri contactUri;
    // An adapter that binds the result Cursor to the ListView
    private SimpleCursorAdapter cursorAdapter;
    ...

Not: Şu tarihten beri: Contacts.DISPLAY_NAME_PRIMARY, Android 3.0 (API sürümü 11) veya sonraki bir sürümü gerektirir. minSdkVersion ile 10 arasındaki veya daha eski sürümler şurada Android Lint uyarısı oluşturur: Android Studio'ya gidin. Bu uyarıyı devre dışı bırakmak için FROM_COLUMNS tanımının önüne @SuppressLint("InlinedApi") ek açıklamasını ekleyin.

Parçayı İlk Kullanıma Hazırlama

Fragment öğesini başlatın. Boş, genel oluşturucuyu ekleyin ve Fragment nesnesinin onCreateView() geri çağırma yöntemindeki kullanıcı arayüzü. Örnek:

Kotlin

    // A UI Fragment must inflate its View
    override fun onCreateView(
            inflater: LayoutInflater,
            container: ViewGroup?,
            savedInstanceState: Bundle?
    ): View? {
        // Inflate the fragment layout
        return inflater.inflate(R.layout.contact_list_fragment, container, false)
    }

Java

    // Empty public constructor, required by the system
    public ContactsFragment() {}

    // A UI Fragment must inflate its View
    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container,
            Bundle savedInstanceState) {
        // Inflate the fragment layout
        return inflater.inflate(R.layout.contact_list_fragment,
            container, false);
    }

ListView için CursorAdapter'ı ayarlama

Arama sonuçlarını ListView ile bağlayan SimpleCursorAdapter öğesini ayarlayın. Kişileri gösteren ListView nesnesini almak için Fragment öğesinin üst etkinliğini kullanarak Activity.findViewById()'i çağırmanız gerekir. setAdapter()'u çağırırken Context üst etkinliğinin Örnek:

Kotlin

    override fun onActivityCreated(savedInstanceState: Bundle?) {
        super.onActivityCreated(savedInstanceState)
        ...
        // Gets the ListView from the View list of the parent activity
        activity?.also {
            contactsList = it.findViewById<ListView>(R.id.contact_list_view)
            // Gets a CursorAdapter
            cursorAdapter = SimpleCursorAdapter(
                    it,
                    R.layout.contact_list_item,
                    null,
                    FROM_COLUMNS, TO_IDS,
                    0
            )
            // Sets the adapter for the ListView
            contactsList.adapter = cursorAdapter
        }
    }

Java

    public void onActivityCreated(Bundle savedInstanceState) {
        super.onActivityCreated(savedInstanceState);
        ...
        // Gets the ListView from the View list of the parent activity
        contactsList =
            (ListView) getActivity().findViewById(R.layout.contact_list_view);
        // Gets a CursorAdapter
        cursorAdapter = new SimpleCursorAdapter(
                getActivity(),
                R.layout.contact_list_item,
                null,
                FROM_COLUMNS, TO_IDS,
                0);
        // Sets the adapter for the ListView
        contactsList.setAdapter(cursorAdapter);
    }

Seçilen kişi işleyiciyi ayarlayın

Bir aramanın sonuçlarını görüntülediğinizde, genellikle kullanıcının bir arama seçmesine izin vermek tek bir kişi ile ilişkilendirilebilir. Örneğin, kullanıcı bir kişiyi tıkladığında Kişinin adresini bir harita üzerinde görüntüle. Bu özelliği sağlamak için öncelikle mevcut Tıklama işleyici olarak Fragment ve bölümünde gösterildiği gibi, AdapterView.OnItemClickListener uygular Kişilerin listesini görüntüleyen bir Parça tanımlayın.

Dinleyiciyi kurmaya devam etmek için ListView öğesine bağlayın: onActivityCreated() içinde setOnItemClickListener() yöntemi çağrılıyor. Örnek:

Kotlin

    fun onActivityCreated(savedInstanceState:Bundle) {
        ...
        // Set the item click listener to be the current fragment.
        contactsList.onItemClickListener = this
        ...
    }

Java

    public void onActivityCreated(Bundle savedInstanceState) {
        ...
        // Set the item click listener to be the current fragment.
        contactsList.setOnItemClickListener(this);
        ...
    }

Mevcut Fragment değerinin Şu tarih için OnItemClickListener: ListView, artık zorunlu yöntemini uygulamanız gerekiyor onItemClick(), ve tıklama etkinliğini işler. Bu konu sonraki bir bölümde açıklanmıştır.

Projeksiyon tanımlama

Sorgunuzdan döndürmek istediğiniz sütunları içeren bir sabit değer tanımlayın. ListView içindeki her öğe, kişinin adının ana biçimini içeren kişinin görünen adını gösterir. Android 3.0 (API sürümü 11) ve sonraki sürümlerde, bu sütunun adı Contacts.DISPLAY_NAME_PRIMARY; sürümünde ise adı şu şekildedir: Contacts.DISPLAY_NAME.

Contacts._ID sütunu, SimpleCursorAdapter bağlama işlemi tarafından kullanılır. Contacts._ID ve LOOKUP_KEY, kullanıcının seçtiği kişi için bir içerik URI'si oluşturmak amacıyla birlikte kullanılır.

Kotlin

...
@SuppressLint("InlinedApi")
private val PROJECTION: Array<out String> = arrayOf(
        ContactsContract.Contacts._ID,
        ContactsContract.Contacts.LOOKUP_KEY,
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.HONEYCOMB)
            ContactsContract.Contacts.DISPLAY_NAME_PRIMARY
        else
            ContactsContract.Contacts.DISPLAY_NAME
)

Java

...
@SuppressLint("InlinedApi")
private static final String[] PROJECTION =
        {
            Contacts._ID,
            Contacts.LOOKUP_KEY,
            Build.VERSION.SDK_INT
                    >= Build.VERSION_CODES.HONEYCOMB ?
                    ContactsContract.Contacts.DISPLAY_NAME_PRIMARY :
                    ContactsContract.Contacts.DISPLAY_NAME

        };

İşaretçi sütun dizinleri için sabit değerler tanımlama

Cursor içindeki tek bir sütundan veri almak için şunlara ihtiyacınız vardır: Cursor içindeki dizin. Dizinler, projenizdeki sütun adlarının sırasıyla aynı olduğundan Cursor sütunlarının dizinleri için sabitler tanımlayabilirsiniz. Örnek:

Kotlin

// The column index for the _ID column
private const val CONTACT_ID_INDEX: Int = 0
// The column index for the CONTACT_KEY column
private const val CONTACT_KEY_INDEX: Int = 1

Java

// The column index for the _ID column
private static final int CONTACT_ID_INDEX = 0;
// The column index for the CONTACT_KEY column
private static final int CONTACT_KEY_INDEX = 1;

Seçim ölçütlerini belirtin

İstediğiniz verileri belirtmek için metin ifadelerinin ve değişkenlerin bir kombinasyonunu oluşturun , sağlayıcıya veri sütunlarına arama yapmasını ve bulunacak değerleri bildirir.

Metin ifadesi için arama sütunlarını listeleyen bir sabit değer tanımlayın. Bu ifade değerler de içerebilse de tercih edilen yöntem, değerleri "?" yer tutucusuyla temsil etmektir. Yer tutucu, getirme sırasında bir dizideki değerlerle değiştirilir. Yer tutucu olarak "?" kullanılması, arama spesifikasyonunun SQL derlemesi yerine bağlama ile oluşturulmasını sağlar. Bu uygulama, kötü amaçlı SQL olasılığını ortadan kaldırır. yerleştirme. Örnek:

Kotlin

// Defines the text expression
@SuppressLint("InlinedApi")
private val SELECTION: String =
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.HONEYCOMB)
            "${ContactsContract.Contacts.DISPLAY_NAME_PRIMARY} LIKE ?"
        else
            "${ContactsContract.Contacts.DISPLAY_NAME} LIKE ?"
...
    // Defines a variable for the search string
    private val searchString: String = ...
    // Defines the array to hold values that replace the ?
    private val selectionArgs = arrayOf<String>(searchString)

Java

    // Defines the text expression
    @SuppressLint("InlinedApi")
    private static final String SELECTION =
            Build.VERSION.SDK_INT >= Build.VERSION_CODES.HONEYCOMB ?
            Contacts.DISPLAY_NAME_PRIMARY + " LIKE ?" :
            Contacts.DISPLAY_NAME + " LIKE ?";
    // Defines a variable for the search string
    private String searchString;
    // Defines the array to hold values that replace the ?
    private String[] selectionArgs = { searchString };

onItemClick() yöntemini tanımlayın

Önceki bir bölümde, ListView için öğe tıklama dinleyicisini ayarlamıştınız. Şimdi de kullanacağınız yöntemi tanımlayarak AdapterView.OnItemClickListener.onItemClick():

Kotlin

    override fun onItemClick(parent: AdapterView<*>, view: View?, position: Int, id: Long) {
        // Get the Cursor
        val cursor: Cursor? = (parent.adapter as? CursorAdapter)?.cursor?.apply {
            // Move to the selected contact
            moveToPosition(position)
            // Get the _ID value
            contactId = getLong(CONTACT_ID_INDEX)
            // Get the selected LOOKUP KEY
            contactKey = getString(CONTACT_KEY_INDEX)
            // Create the contact's content Uri
            contactUri = ContactsContract.Contacts.getLookupUri(contactId, mContactKey)
            /*
             * You can use contactUri as the content URI for retrieving
             * the details for a contact.
             */
        }
    }

Java

    @Override
    public void onItemClick(
        AdapterView<?> parent, View item, int position, long rowID) {
        // Get the Cursor
        Cursor cursor = parent.getAdapter().getCursor();
        // Move to the selected contact
        cursor.moveToPosition(position);
        // Get the _ID value
        contactId = cursor.getLong(CONTACT_ID_INDEX);
        // Get the selected LOOKUP KEY
        contactKey = cursor.getString(CONTACT_KEY_INDEX);
        // Create the contact's content Uri
        contactUri = Contacts.getLookupUri(contactId, mContactKey);
        /*
         * You can use contactUri as the content URI for retrieving
         * the details for a contact.
         */
    }

Yükleyiciyi başlatma

Verileri almak için CursorLoader kullandığınızdan arka plan iş parçacığını ve eşzamansız kontrol yapan diğer değişkenleri başlatmanız gerekir içerir. Aşağıdaki örnekte gösterildiği gibi onCreate() içinde başlatma işlemini yapın:

Kotlin

class ContactsFragment :
        Fragment(),
        LoaderManager.LoaderCallbacks<Cursor> {
    ...
    override fun onCreate(savedInstanceState: Bundle?) {
        // Always call the super method first
        super.onCreate(savedInstanceState)
        ...
        // Initializes the loader
        loaderManager.initLoader(0, null, this)

Java

public class ContactsFragment extends Fragment implements
        LoaderManager.LoaderCallbacks<Cursor> {
    ...
    // Called just before the Fragment displays its UI
    @Override
    public void onCreate(Bundle savedInstanceState) {
        // Always call the super method first
        super.onCreate(savedInstanceState);
        ...
        // Initializes the loader
        getLoaderManager().initLoader(0, null, this);

onCreateLoader() işlevini uygulama

initLoader() yöntemini çağırdıktan hemen sonra yükleyici çerçevesi tarafından çağrılan onCreateLoader() yöntemini uygulayın.

onCreateLoader() ayında, arama dizesi modelini ayarlama. Bir dizeyi kalıp haline getirmek için "%" değerini girin (yüzde) karakter sayısı sıfır veya daha fazla karakterden oluşan bir diziyi temsil eder veya "_" (alt çizgi) karakterleri kullanabilirsiniz. Örneğin, "%Jefferson%" kalıbı hem "Thomas Jefferson" hem de "Jefferson Davis" ile eşleşir.

Yöntemden yeni bir CursorLoader döndürün. İçerik için URI, Contacts.CONTENT_URI değerini kullanın. Bu URI, aşağıdaki örnekte gösterildiği gibi, tablonun tamamını ifade eder:

Kotlin

    ...
    override fun onCreateLoader(loaderId: Int, args: Bundle?): Loader<Cursor> {
        /*
         * Makes search string into pattern and
         * stores it in the selection array
         */
        selectionArgs[0] = "%$mSearchString%"
        // Starts the query
        return activity?.let {
            return CursorLoader(
                    it,
                    ContactsContract.Contacts.CONTENT_URI,
                    PROJECTION,
                    SELECTION,
                    selectionArgs,
                    null
            )
        } ?: throw IllegalStateException()
    }

Java

    ...
    @Override
    public Loader<Cursor> onCreateLoader(int loaderId, Bundle args) {
        /*
         * Makes search string into pattern and
         * stores it in the selection array
         */
        selectionArgs[0] = "%" + searchString + "%";
        // Starts the query
        return new CursorLoader(
                getActivity(),
                ContactsContract.Contacts.CONTENT_URI,
                PROJECTION,
                SELECTION,
                selectionArgs,
                null
        );
    }

onLoadFinished() ve onLoaderReset() işlevlerini uygulama

onLoadFinished() yöntemini uygulayın. Yükleyici çerçevesi onLoadFinished(). Kişi Sağlayıcı sorgunun sonuçlarını döndürdüğünde. Bu yöntemde, sonuç Cursor SimpleCursorAdapter. Bu işlem, ListView'ü arama sonuçlarıyla otomatik olarak günceller:

Kotlin

    override fun onLoadFinished(loader: Loader<Cursor>, cursor: Cursor) {
        // Put the result Cursor in the adapter for the ListView
        cursorAdapter?.swapCursor(cursor)
    }

Java

    @Override
    public void onLoadFinished(Loader<Cursor> loader, Cursor cursor) {
        // Put the result Cursor in the adapter for the ListView
        cursorAdapter.swapCursor(cursor);
    }

onLoaderReset() yöntemi, yükleyici çerçevesinin sonuç Cursor eski veri içeriyor. Mevcut SimpleCursorAdapter referansı Cursor. Yüklemezseniz yükleyici çerçevesi Cursor cihazını geri dönüştürebilir, bu da bellek sızıntısına neden olur. Örnek:

Kotlin

    override fun onLoaderReset(loader: Loader<Cursor>) {
        // Delete the reference to the existing Cursor
        cursorAdapter?.swapCursor(null)
    }

Java

    @Override
    public void onLoaderReset(Loader<Cursor> loader) {
        // Delete the reference to the existing Cursor
        cursorAdapter.swapCursor(null);

    }

Artık bir uygulamanın, kişi adları ve iadeler ile arama dizesini eşleştiren temel parçalarına sahipsiniz sonuç ListView içindedir. Kullanıcı, bir kişi adını seçmek için tıklayabilir. Bu işlem, kişi verilerini daha ayrıntılı bir şekilde işleyebileceğiniz bir dinleyiciyi tetikler. Örneğin, kişinin ayrıntılarını alabilirsiniz. Bunu nasıl yapacağınızı öğrenmek için Kişi ayrıntılarını alma başlıklı makaleyi inceleyin.

Arama kullanıcı arayüzleri hakkında daha fazla bilgi edinmek için Arama arayüzü oluşturma başlıklı API kılavuzunu okuyun.

Bu dersin geri kalan bölümlerinde, Google Haritalar'da kişi bulmanın diğer yolları Kişi Sağlayıcı.

Bir kişiyi belirli bir veri türüne göre eşleştirme

Bu teknik, eşleştirmek istediğiniz veri türünü belirtmenize olanak tanır. Alınıyor ada göre arama bu tür sorgulara özel bir örnektir, ancak bunu tüm türler için de bir kişiyle ilişkili ayrıntı verilerinin toplamıdır. Örneğin, belirli bir posta koduna sahip kişileri alabilirsiniz. Bu durumda, arama dizesinin posta kodu satırında depolanan verilerle eşleşmesi gerekir.

Bu alma türünü uygulamak için önce aşağıdaki kodu uygulayın: önceki bölümler:

  • Sağlayıcıyı Okuma İzni İsteyin.
  • ListView ve öğe düzenlerini tanımlayın.
  • Kişilerin listesini görüntüleyen bir Parça tanımlayın.
  • Genel değişkenleri tanımlayın.
  • Parçayı başlatın.
  • ListView için CursorAdapter'ı ayarlayın.
  • Seçilen kişi işleyiciyi ayarlayın.
  • İmleç sütunu dizinleri için sabit değerler tanımlayın.

    Farklı bir tablodan veri alıyor olsanız bile, projeksiyon aynı olduğundan İmleç için aynı dizinleri kullanabilirsiniz.

  • onItemClick() yöntemini tanımlayın.
  • Yükleyiciyi başlatın.
  • onLoadFinished() ve onLoaderReset() yöntemlerini uygulayın.

Aşağıdaki adımlarda, bir arama dizesini belirli bir ayrıntı veri türüyle eşleştirmek ve sonuçları görüntülemek için ihtiyacınız olan ek kod gösterilmektedir.

Veri türünü ve tabloyu seçin

Belirli bir ayrıntı verisi türünü aramak için veri türünün özel MIME türü değerini bilmeniz gerekir. Her veri türünün, veri türüyle ilişkili ContactsContract.CommonDataKinds alt sınıfında sabit bir CONTENT_ITEM_TYPE ile tanımlanan benzersiz bir MIME türü değeri vardır. Alt sınıfların adları, veri türlerini belirtir. Örneğin, e-posta verilerinin alt sınıfı ContactsContract.CommonDataKinds.Email, e-posta verilerinin özel MIME türü ise Email.CONTENT_ITEM_TYPE sabitiyle tanımlanır.

Aramanız için ContactsContract.Data tablosunu kullanın. Projeksiyon, seçim ifadesi ve sıralama düzeniniz için ihtiyaç duyduğunuz tüm sabitler bu tabloda tanımlanır veya bu tablodan devralınır.

Projeksiyon tanımlama

Bir projeksiyon tanımlamak için ContactsContract.Data içinde tanımlanan sütunlardan veya devraldığı sınıflardan bir veya daha fazlasını seçin. Kişi Sağlayıcı, satır döndürmeden önce ContactsContract.Data ile diğer tablolar arasında implicit bir birleştirme yapar. Örnek:

Kotlin

@SuppressLint("InlinedApi")
private val PROJECTION: Array<out String> = arrayOf(
        /*
         * The detail data row ID. To make a ListView work,
         * this column is required.
         */
        ContactsContract.Data._ID,
        // The primary display name
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.HONEYCOMB)
            ContactsContract.Data.DISPLAY_NAME_PRIMARY
        else
            ContactsContract.Data.DISPLAY_NAME,
        // The contact's _ID, to construct a content URI
        ContactsContract.Data.CONTACT_ID,
        // The contact's LOOKUP_KEY, to construct a content URI
        ContactsContract.Data.LOOKUP_KEY
)

Java

    @SuppressLint("InlinedApi")
    private static final String[] PROJECTION =
        {
            /*
             * The detail data row ID. To make a ListView work,
             * this column is required.
             */
            ContactsContract.Data._ID,
            // The primary display name
            Build.VERSION.SDK_INT >= Build.VERSION_CODES.HONEYCOMB ?
                    ContactsContract.Data.DISPLAY_NAME_PRIMARY :
                    ContactsContract.Data.DISPLAY_NAME,
            // The contact's _ID, to construct a content URI
            ContactsContract.Data.CONTACT_ID,
            // The contact's LOOKUP_KEY, to construct a content URI
            ContactsContract.Data.LOOKUP_KEY // A permanent link to the contact
        };

Arama ölçütlerini tanımlama

Belirli bir veri türü içinde bir dizeyi aramak için şu:

  • Arama dizenizi içeren sütunun adı. Bu ad veri türüne göre değişiklik gösterir. Bu nedenle, Veri türüne karşılık gelen ContactsContract.CommonDataKinds ve bu alt sınıftan sütun adını seçin. Örneğin, e-posta adreslerini aramak için Email.ADDRESS sütununu kullanın.
  • Arama dizesinin kendisi ("?" karakterini eklemeniz gerekir.
  • Özel MIME türü değerini içeren sütunun adı. Bu ad her zaman Data.MIMETYPE olur.
  • Veri türü için özel MIME türü değeri. Daha önce açıklandığı gibi bu, CONTENT_ITEM_TYPE ContactsContract.CommonDataKinds alt sınıf. Örneğin, e-posta verileri için MIME türü değeri Email.CONTENT_ITEM_TYPE'tür. Bir "'" (tek tırnak) karakteri ekleyin ve bunu sabit değerin başına ve sonuna ekleyin. aksi takdirde sağlayıcı değeri bir 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

/*
 * Constructs search criteria from the search string
 * and email MIME type
 */
private val SELECTION: String =
        /*
         * Searches for an email address
         * that matches the search string
         */
        "${Email.ADDRESS} LIKE ? AND " +
        /*
         * Searches for a MIME type that matches
         * the value of the constant
         * Email.CONTENT_ITEM_TYPE. Note the
         * single quotes surrounding Email.CONTENT_ITEM_TYPE.
         */
        "${ContactsContract.Data.MIMETYPE } = '${Email.CONTENT_ITEM_TYPE}'"

Java

    /*
     * Constructs search criteria from the search string
     * and email MIME type
     */
    private static final String SELECTION =
            /*
             * Searches for an email address
             * that matches the search string
             */
            Email.ADDRESS + " LIKE ? " + "AND " +
            /*
             * Searches for a MIME type that matches
             * the value of the constant
             * Email.CONTENT_ITEM_TYPE. Note the
             * single quotes surrounding Email.CONTENT_ITEM_TYPE.
             */
            ContactsContract.Data.MIMETYPE + " = '" + Email.CONTENT_ITEM_TYPE + "'";

Ardından, seçim bağımsız değişkenini içerecek değişkenleri tanımlayın:

Kotlin

    private var searchString: String? = null
    private val selectionArgs: Array<String> = arrayOf("")

Java

    String searchString;
    String[] selectionArgs = { "" };

onCreateLoader() işlevini uygulama

İstediğiniz verileri ve bu verileri nasıl bulacağınızı belirttiğinize göre onCreateLoader() uygulanması. Projeksiyonunuzu, seçim metin ifadenizi ve seçim dizinizi bağımsız değişken olarak kullanarak bu yöntemden yeni bir CursorLoader döndürün. İçerik URI'si için Data.CONTENT_URI Örnek:

Kotlin

    override fun onCreateLoader(id: Int, args: Bundle?): Loader<Cursor> {
        // OPTIONAL: Makes search string into pattern
        searchString = "%$mSearchString%"

        searchString?.also {
            // Puts the search string into the selection criteria
            selectionArgs[0] = it
        }
        // Starts the query
        return activity?.let {
            CursorLoader(
                    it,
                    ContactsContract.Data.CONTENT_URI,
                    PROJECTION,
                    SELECTION,
                    selectionArgs,
                    null
            )
        } ?: throw IllegalStateException()
    }

Java

@Override
    public Loader<Cursor> onCreateLoader(int loaderId, Bundle args) {
        // OPTIONAL: Makes search string into pattern
        searchString = "%" + searchString + "%";
        // Puts the search string into the selection criteria
        selectionArgs[0] = searchString;
        // Starts the query
        return new CursorLoader(
                getActivity(),
                Data.CONTENT_URI,
                PROJECTION,
                SELECTION,
                selectionArgs,
                null
        );
    }

Bu kod snippet'leri, belirli bir ayrıntı veri türüne dayalı basit bir ters aramanın temelini oluşturur. Uygulamanız belirli veri türüne odaklanıyorsa kullanılabilecek en iyi tekniktir: e-postalar olarak iletiyorsanız ve kullanıcıların, bir veri parçasıyla ilişkili adları almalarına izin vermek istiyorsanız.

Herhangi bir veri türüne göre bir kişiyle eşleştirme

Herhangi bir veri türüne göre kişi almak, ad, e-posta adresi, posta adresi, telefon numarası vb. dahil olmak üzere verilerinden herhangi biri arama dizesine eşleşiyorsa kişileri döndürür. Bu durum, çok sayıda arama sonucuyla sonuçlanır. Örneğin, arama dizesi "Doe" ise herhangi bir veri türü için arama yaptığınızda "Can Doğru" adlı kişiyi ve "Doe Caddesi"nde yaşayan kişileri de döndürür.

Bu tür bir getirme işlemini uygulamak için önce önceki bölümlerde listelenen aşağıdaki kodu uygulayın:

  • Sağlayıcıyı Okuma İzni İsteyin.
  • ListView ve öğe düzenlerini tanımlayın.
  • Kişilerin listesini görüntüleyen bir Parça tanımlayın.
  • Genel değişkenleri tanımlayın.
  • Parçayı başlatın.
  • ListView için CursorAdapter'ı ayarlayın.
  • Seçilen kişi dinleyicisini ayarlayın.
  • Projeksiyon tanımlayın.
  • İmleç sütunu dizinleri için sabit değerler tanımlayın.

    Bu alma türü için bölümde kullandığınız tabloyu kullanırsınız Kişileri ada göre eşleştirin ve sonuçları listeleyin. Aynı sütun dizinlerini de kullanın.

  • onItemClick() yöntemini tanımlayın.
  • Yükleyiciyi başlatın.
  • onLoadFinished() ve onLoaderReset() işlevlerini uygulayın.

Aşağıdaki adımlarda, bir arama dizesini herhangi bir veri türüyle eşleştirmek ve sonuçları görüntülemek için ihtiyacınız olan ek kod gösterilmektedir.

Seçim ölçütlerini kaldır

SELECTION sabit değerlerini veya mSelectionArgs değişkenini tanımlamayın. Bu tür bir getirme işleminde bunlar kullanılmaz.

onCreateLoader() işlevini uygulama

Yeni bir CursorLoader döndürerek onCreateLoader() yöntemini uygulayın. Kişi Sağlayıcı bunu otomatik olarak yaptığından arama dizesini bir kalıba dönüştürmeniz gerekmez. Temel URI olarak Contacts.CONTENT_FILTER_URI kullanın ve Uri.withAppendedPath()'ü çağırarak arama dizenizi buna ekleyin. Bu URI kullanılıyor aşağıdaki örnekte gösterildiği gibi, herhangi bir veri türünü aramayı otomatik olarak tetikler:

Kotlin

    override fun onCreateLoader(loaderId: Int, args: Bundle?): Loader<Cursor> {
        /*
         * Appends the search string to the base URI. Always
         * encode search strings to ensure they're in proper
         * format.
         */
        val contentUri: Uri = Uri.withAppendedPath(
                ContactsContract.Contacts.CONTENT_FILTER_URI,
                Uri.encode(searchString)
        )
        // Starts the query
        return activity?.let {
            CursorLoader(
                    it,
                    contentUri,
                    PROJECTION2,
                    null,
                    null,
                    null
            )
        } ?: throw IllegalStateException()
    }

Java

    @Override
    public Loader<Cursor> onCreateLoader(int loaderId, Bundle args) {
        /*
         * Appends the search string to the base URI. Always
         * encode search strings to ensure they're in proper
         * format.
         */
        Uri contentUri = Uri.withAppendedPath(
                Contacts.CONTENT_FILTER_URI,
                Uri.encode(searchString));
        // Starts the query
        return new CursorLoader(
                getActivity(),
                contentUri,
                PROJECTION,
                null,
                null,
                null
        );
    }

Bu kod snippet'leri, Kişiler Sağlayıcı'da geniş kapsamlı arama yapan bir uygulamanın temelini oluşturur. Bu teknik, Kişiler uygulamasının kişi listesi ekranına benzer işlevler uygulamak isteyen uygulamalar için kullanışlıdır.