Bu derste, aşağıdaki teknikleri kullanarak verileri bir arama dizesinin tamamı veya bir kısmıyla eşleşen kişilerin listesini nasıl alabileceğiniz gösterilmektedir:
- Kişi adlarını eşleştir
- Arama dizesini kişi adı verilerinin tamamıyla veya bir kısmıyla eşleştirerek kişi listesini alın. Kişi Sağlayıcı, aynı adın birden fazla örneğine izin verdiğinden bu teknik, bir eşleşme listesi döndürebilir.
- Telefon numarası gibi belirli bir veri türüyle eşleştirme
- Arama dizesini e-posta adresi gibi belirli bir ayrıntı veri türüyle eşleştirerek kişi listesini alın. Örneğin, bu teknik, e-posta adresleri arama dizesiyle eşleşen tüm kişileri listelemenize olanak tanır.
- Her veri türünü eşleştir
- Arama dizesini ad, telefon numarası, açık adres, e-posta adresi vb. herhangi bir ayrıntı verisiyle eşleştirerek kişilerin listesini alın. Örneğin, bu teknik, bir arama dizesi için her tür veriyi kabul etmenize ve ardından verilerin dizeyle eşleştiği kişileri listelemenize olanak tanır.
Not: Bu dersteki tüm örneklerde, Kişiler Sağlayıcı'dan veri almak için CursorLoader
kullanılmıştır. CursorLoader
, sorgusunu kullanıcı arayüzü iş parçacığından ayrı bir iş parçacığında çalıştırır. Bu, sorgunun kullanıcı arayüzü yanıt sürelerini yavaşlatıp kötü bir kullanıcı deneyimine neden olmamasını sağlar. Daha fazla bilgi için
Arka Planda Veri Yükleme konulu Android eğitim sınıfına göz atın.
Sağlayıcıyı okuma izni iste
Kişi Sağlayıcıda herhangi bir türde arama yapmak için uygulamanızın READ_CONTACTS
iznine sahip olması gerekir.
Bunu istemek için bu <uses-permission>
öğesini manifest dosyanıza <manifest>
alt öğesi olarak ekleyin:
<uses-permission android:name="android.permission.READ_CONTACTS" />
Bir kişiyi adına göre eşleştirme ve sonuçları listeleme
Bu teknik, bir arama dizesini Kişi Sağlayıcının ContactsContract.Contacts
tablosundaki bir kişinin veya kişilerin adıyla eşleştirmeye çalışır. Kullanıcının eşleşen kişiler arasından seçim yapabilmesi için sonuçları genellikle ListView
biçiminde de göstermek istersiniz.
ListView'u ve öğe düzenlerini tanımlama
Arama sonuçlarını bir ListView
içinde görüntülemek için ListView
dahil kullanıcı arayüzünün tamamını tanımlayan bir ana düzen dosyasına ve bir ListView
satırını tanımlayan öğe düzen dosyasına ihtiyacınız vardır. Örneğin, aşağıdaki XML ile res/layout/contacts_list_view.xml
ana düzen dosyasını 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ı
android:id/list
kullanır.
Aşağıdaki XML ile contacts_list_item.xml
öğe düzen dosyasını 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ı
android:text1
kullanır.
Not: Dizeyi dolaylı olarak almak isteyebileceğinizden bu derste, kullanıcıdan arama dizesi almak için kullanılacak kullanıcı arayüzü açıklanmamaktadır. Örneğin, kullanıcıya, adı gelen kısa mesajdaki bir dizeyle eşleşen kişileri arama seçeneği sunabilirsiniz.
Yazdığınız iki düzen dosyası, ListView
gösteren bir kullanıcı arayüzü tanımlar. Sonraki adım, kişiler listesini görüntülemek için bu kullanıcı arayüzünü kullanan bir kod yazmaktır.
Kişi listesini görüntüleyen bir Parça tanımlayın
Kişiler listesini görüntülemek için Activity
tarafından yüklenen bir Fragment
tanımlayarak başlayın. Fragment
kullanmak daha esnek bir tekniktir. Bunun nedeni, listeyi görüntülemek için bir Fragment
ve kullanıcının listeden seçtiği bir kişinin ayrıntılarını görüntülemek için ikinci bir Fragment
kullanmaktır. Bu yaklaşımı kullanarak bu derste sunulan tekniklerden birini,
Bir kişinin ayrıntılarını alma dersindeki bir teknikle birleştirebilirsiniz.
Activity
öğesinden bir veya daha fazla Fragment
nesnesini nasıl kullanacağınızı öğrenmek için
Fragments ile dinamik kullanıcı arayüzü oluşturma eğitim sınıfını okuyun.
Android çerçevesi, Kişi Sağlayıcı'ya karşı sorgu yazmanıza yardımcı olmak için ContactsContract
adlı bir sözleşme sınıfı sağlar. Bu sınıf, sağlayıcıya erişmek için faydalı sabitleri ve yöntemleri tanımlar. Bu sınıfı kullandığınızda içerik URI'leri, tablo adları veya sütunlar için kendi sabit değerlerinizi tanımlamanız gerekmez. Bu sınıfı kullanmak için aşağıdaki ifadeyi ekleyin:
Kotlin
import android.provider.ContactsContract
Java
import android.provider.ContactsContract;
Kod, sağlayıcıdan veri almak için bir CursorLoader
kullandığından, LoaderManager.LoaderCallbacks
yükleyici arayüzünü uyguladığını belirtmeniz gerekir. Ayrıca, kullanıcının arama sonuçları listesinden hangi kişiyi seçtiğini tespit etmeye yardımcı olması için AdapterView.OnItemClickListener
bağdaştırıcı arayüzünü uygulayın. Örneğin:
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: Contacts.DISPLAY_NAME_PRIMARY
, Android 3.0 (API sürümü 11) veya sonraki sürümleri gerektirdiğinden uygulamanızın minSdkVersion
değeri 10 veya daha düşük bir sürüme ayarlandığında Android Studio'da Android Lint uyarısı oluşturulur. Bu uyarıyı kapatmak için FROM_COLUMNS
tanımından önce @SuppressLint("InlinedApi")
ek açıklamasını ekleyin.
Parçayı Başlat
Fragment
öğesini başlatın. Android sisteminin gerektirdiği boş, herkese açık oluşturucuyu ekleyin ve onCreateView()
geri çağırma yönteminde Fragment
nesnesinin kullanıcı arayüzünü şişirin.
Örneğin:
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
öğesine bağlayan SimpleCursorAdapter
öğesini ayarlayın. Kişileri görüntüleyen ListView
nesnesini almak için Fragment
üst etkinliğini kullanarak Activity.findViewById()
yöntemini çağırmanız gerekir. setAdapter()
numaralı telefonu aradığınızda ebeveyn etkinliğinin Context
özelliğini kullanın.
Örneğin:
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 dinleyiciyi ayarla
Bir aramanın sonuçlarını görüntülediğinizde genellikle kullanıcının daha fazla işlem için tek bir kişi seçmesine izin vermek istersiniz. Örneğin, kullanıcı bir kişiyi tıkladığında bu kişinin adresini haritada görüntüleyebilirsiniz. Bu özelliği sağlamak için öncelikle, Kişiler listesini gösteren bir Parça tanımlama bölümünde gösterildiği gibi, sınıfın AdapterView.OnItemClickListener
öğesini uyguladığını belirterek geçerli Fragment
öğesini tıklama işleyici olarak tanımladınız.
İşleyiciyi ayarlamaya devam etmek için onActivityCreated()
ürününde setOnItemClickListener()
yöntemini çağırarak onu ListView
'a bağlayın. Örneğin:
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); ... }
Geçerli Fragment
öğesinin ListView
için OnItemClickListener
olduğunu belirttiğinizden tıklama etkinliğini işleyen onItemClick()
adlı gerekli yöntemi uygulamanız gerekiyor. Bu, 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 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
, ondan önceki sürümlerde ise Contacts.DISPLAY_NAME
şeklindedir.
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 üzere 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 };
İmleç sütunu dizinleri için sabit değerler tanımlama
Bir Cursor
içindeki tek bir sütundan veri almak için sütunun Cursor
içinde bulunan dizinine ihtiyacınız vardır. Dizinler projeksiyonunuzdaki sütun adlarının sıralamasıyla aynı olduğundan Cursor
sütunlarının dizinleri için sabit değerler tanımlayabilirsiniz. Örneğin:
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 sağlayıcıya veri sütunlarının aranacağını ve bulunacak değerleri bildiren metin ifadeleri ve değişkenlerin bir kombinasyonunu oluşturun.
Metin ifadesi için arama sütunlarını listeleyen bir sabit değer tanımlayın. Bu ifade değerler de içerebilir ancak tercih edilen uygulama, değerlerin "?" yer tutucusuyla temsil edilmesidir. Alma sırasında, yer tutucu bir diziden gelen 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 yerleştirme ihtimalini ortadan kaldırır. Örneğin:
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 işleyiciyi ayarladınız.
Şimdi AdapterView.OnItemClickListener.onItemClick()
yöntemini tanımlayarak işlemi işleyici için uygulayın:
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şlatın
Veri almak için CursorLoader
kullandığınızdan, arka plan iş parçacığını ve eşzamansız almayı kontrol eden diğer değişkenleri başlatmanız gerekir. onCreate()
içinde başlatmayı aşağıdaki örnekte gösterildiği gibi 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()
çağrısından hemen sonra yükleyici çerçevesi tarafından çağrılan onCreateLoader()
yöntemini uygulayın.
onCreateLoader()
sayfasında arama dizesi kalıbını ayarlayın. Bir kalıba bir dize eklemek için, sıfır veya daha fazla karakterden oluşan bir diziyi temsil etmek üzere "%" (yüzde) karakterlerini, tek bir karakteri temsil etmek için "_" (alt çizgi) karakterlerini ya da her ikisini birden ekleyin. Örneğin, "%Cemil%" kalıbı hem "Tuğçe Hakan" hem de "Ali Demir" ile eşleşir.
Yöntemden yeni bir CursorLoader
döndürür. İçerik URI'si için Contacts.CONTENT_URI
kullanın.
Bu URI, aşağıdaki örnekte gösterildiği gibi tablonun tamamını belirtir:
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şlevini uygulayın
onLoadFinished()
yöntemini uygulayın. Kişi Sağlayıcısı sorgunun sonuçlarını döndürdüğünde yükleyici çerçevesi onLoadFinished()
işlevini çağırır. Bu yöntemde, Cursor
sonucunu SimpleCursorAdapter
içine yerleştirin. Bu işlem, ListView
öğesini 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); }
Yükleyici çerçevesi Cursor
sonucunun eski veri içerdiğini algıladığında onLoaderReset()
yöntemi çağrılır. Mevcut Cursor
için SimpleCursorAdapter
referansını silin. Aksi takdirde yükleyici çerçevesi, Cursor
öğesini geri dönüştürmez ve bu da bellek sızıntısına neden olur. Örneğin:
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ıyla eşleşen ve sonucu ListView
ile döndüren önemli parçalarına sahipsiniz. Kullanıcı, kişi adını tıklayarak bu kişiyi seçebilir.
Bu, kişinin verileriyle daha ayrıntılı çalışabileceğiniz bir işleyiciyi tetikler. Örneğin,
kişinin bilgilerini alabilirsiniz. Bunu nasıl yapacağınızı öğrenmek için Bir kişinin ayrıntılarını alma başlıklı sonraki dersle devam edin.
Arama kullanıcı arayüzleri hakkında daha fazla bilgi edinmek için Arama arayüzü oluşturma API kılavuzunu okuyun.
Bu dersin kalan bölümlerinde, Kişi Sağlayıcı'da kişi bulmanın diğer yolları gösterilmektedir.
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. Ada göre alma işlemi, bu tür bir sorguya özel bir örnektir. Ancak bunu bir kişiyle ilişkili herhangi bir ayrıntı verisi türü için de yapabilirsiniz. Ö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 tür alma işlemini uygulamak için önce önceki bölümlerde listelenen aşağıdaki kodu uygulayın:
- Sağlayıcı'yı Okuma İzni İsteme.
- ListView'u ve öğe düzenlerini tanımlayın.
- Kişi listesini görüntüleyen bir Parça tanımlayın.
- Genel değişkenleri tanımlama.
- Parçayı başlatın.
- ListView için CursorAdapter'ı ayarlayın.
- Seçilen kişi dinleyiciyi ayarlayın.
-
İmleç sütunu dizinleri için sabit değerler tanımlayın.
Farklı bir tablodan veri alıyor olsanız bile, projeksiyondaki sütunların sırası aynıdır. Bu nedenle, İmleç için aynı dizinleri kullanabilirsiniz.
- onItemClick() yöntemini tanımlayın.
- Yükleyiciyi başlatın.
- onLoadFinished() ve onLoaderReset() uygulamalarını 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ı veri türünü aramak için veri türünün özel MIME türü değerini bilmeniz gerekir. Her veri türü, 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ğerine sahiptir.
Alt sınıfların adları, veri türlerini gösteren adlara sahiptir. Örneğin, e-posta verileri için alt sınıf ContactsContract.CommonDataKinds.Email
, e-posta verileri için özel MIME türü ise sabit Email.CONTENT_ITEM_TYPE
değeriyle tanımlanır.
Aramanızda ContactsContract.Data
tablosunu kullanın. Projeksiyon, seçim koşulu ve sıralama düzeniniz için ihtiyacınız olan tüm sabit değerler, bu tabloda tanımlanır veya bu tablo tarafından devralınır.
Projeksiyon tanımlama
Bir projeksiyon tanımlamak için ContactsContract.Data
içinde tanımlanan sütunlardan birini veya daha fazlasını ya da devraldığı sınıfları seçin. Kişi Sağlayıcısı, satırları döndürmeden önce ContactsContract.Data
ile diğer tablolar arasında dolaylı bir birleştirme işlemi gerçekleştirir. Örneğin:
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ımlayın
Belirli bir veri türünde dize aramak için aşağıdakilerden bir seçim ifadesi oluşturun:
-
Arama dizenizi içeren sütunun adı. Bu ad veri türüne göre değiştiğinden, veri türüne karşılık gelen
ContactsContract.CommonDataKinds
alt sınıfını bulmanız ve ardından bu alt sınıftan sütun adını seçmeniz gerekir. Örneğin, e-posta adreslerini aramak içinEmail.ADDRESS
sütununu kullanın. - Seçim yan tümcesinde "?" karakteri olarak gösterilen arama dizesinin kendisi.
-
Özel MIME türü değerini içeren sütunun adı. Bu ad her zaman
Data.MIMETYPE
olur. -
Veri türünün özel MIME türü değeri. Daha önce açıklandığı gibi bu,
ContactsContract.CommonDataKinds
alt sınıfındakiCONTENT_ITEM_TYPE
sabittir. Örneğin, e-posta verileri için MIME türü değeriEmail.CONTENT_ITEM_TYPE
şeklindedir. "'
" (tek tırnak) karakterini sabit değerin başında ve sonunda birleştirerek değeri tek tırnak içine alın. Aksi takdirde sağlayıcı, değeri dize değeri yerine değişken adı olarak yorumlar. Kullanıcı tarafından sağlanan değer yerine sabit bir değer kullandığınızdan bu değer için yer tutucu kullanmanız gerekmez.
Örneğin:
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 bunları nasıl bulacağınızı belirlediğinize göre onCreateLoader()
uygulamanızda bir sorgu tanımlayın.
Projeksiyonunuzu, seçim metni 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
kullanın. Örneğin:
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 e-postalar gibi belirli bir veri türüne odaklanıyorsa ve kullanıcıların bir veri parçasıyla ilişkili adları almalarına izin vermek istiyorsanız kullanılacak en iyi teknik budur.
Bir kişiyi herhangi bir veri türüne göre eşleştirme
Herhangi bir veri türüne dayalı olarak bir kişi alınması; ad, e-posta adresi, posta adresi, telefon numarası gibi verilerden herhangi biri arama dizesiyle eşleşirse kişileri döndürür. Bunun sonucunda geniş bir arama sonuçları kümesi elde edilir. Örneğin, arama dizesi "Doğan" ise herhangi bir veri türü için yapılan arama "Can Doğru" kişisini döndürür; ayrıca "Doğa Sokak"ta yaşayan kişileri de döndürür.
Bu tür alma işlemini uygulamak için önce önceki bölümlerde listelenen aşağıdaki kodu uygulayın:
- Sağlayıcı'yı Okuma İzni İsteme.
- ListView'u ve öğe düzenlerini tanımlayın.
- Kişi listesini görüntüleyen bir Parça tanımlayın.
- Genel değişkenleri tanımlama.
- Parçayı başlatın.
- ListView için CursorAdapter'ı ayarlayın.
- Seçilen kişi dinleyiciyi ayarlayın.
- Projeksiyon tanımlayın.
-
İmleç sütunu dizinleri için sabit değerler tanımlayın.
Bu alma türü için Bir kişiyi ada göre eşleştirme ve sonuçları listeleme bölümünde kullandığınız tabloyu kullanırsınız. Aynı sütun dizinlerini de kullanın.
- onItemClick() yöntemini tanımlayın.
- Yükleyiciyi başlatın.
- onLoadFinished() ve onLoaderReset() uygulamalarını 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
sabitlerini veya mSelectionArgs
değişkenini tanımlamayın.
Bunlar, bu tür alma işleminde kullanılmaz.
onCreateLoader() işlevini uygulama
Yeni bir CursorLoader
döndürerek onCreateLoader()
yöntemini uygulayın.
Kişi Sağlayıcısı bunu otomatik olarak yaptığından, arama dizesini bir kalıba dönüştürmenize gerek yoktur. Temel URI olarak Contacts.CONTENT_FILTER_URI
kullanın ve Uri.withAppendedPath()
yöntemini çağırarak arama dizenizi buna ekleyin. Bu URI'nın kullanılması, aşağıdaki örnekte gösterildiği gibi otomatik olarak herhangi bir veri türünü aramayı 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şi Sağlayıcı'da kapsamlı arama yapan bir uygulamanın temelini oluşturur. Teknik, Kişiler uygulamasının kişi listesi ekranına benzer işlevler uygulamak isteyen uygulamalar için yararlıdır.