Bu derste, aşağıdaki teknikleri kullanarak verileri bir arama dizesinin tamamıyla veya bir kısmıyla eşleşen kişilerin listesini nasıl alacağınız gösterilmektedir:
- Kişi adlarını eşleştirme
- Arama dizesini kişi adı verilerinin tamamıyla veya bir kısmıyla eşleştirerek kişi listesi alma. Contacts Provider, aynı adın birden fazla örneğine izin verdiğinden bu teknik, eşleşmelerin listesini döndürebilir.
- Telefon numarası gibi belirli bir veri türünü eşleştirme
- Arama dizesini e-posta adresi gibi belirli bir ayrıntı veri türüyle eşleştirerek kişi listesini alma. Örneğin, bu teknik, e-posta adresi arama dizesiyle eşleşen tüm kişileri listelemenize olanak tanır.
- Herhangi bir veri türüyle eşleştirme
- Arama dizesini ad, telefon numarası, açık adres, e-posta adresi gibi her türlü ayrıntı verisiyle eşleştirerek kişi listesi alma Örneğin, bu teknik sayesinde bir arama dizesi için her tür veriyi kabul edebilir ve ardından verilerin dizeyle eşleştiği kişileri listeleyebilirsiniz.
Not: Bu dersteki tüm örneklerde, Contacts Provider'dan veri almak için CursorLoader kullanılır. CursorLoader, sorgusunu kullanıcı arayüzü iş parçacığından ayrı bir iş parçacığında çalıştırır. Bu sayede sorgu, kullanıcı arayüzü yanıt sürelerini yavaşlatmaz ve kötü bir kullanıcı deneyimine neden olmaz. Daha fazla bilgi için
Arka Planda Veri Yükleme başlıklı Android eğitim sınıfına bakın.
Sağlayıcıyı okuma izni isteyin
Contacts Provider'da herhangi bir arama yapmak için uygulamanızın
READ_CONTACTS iznine sahip olması gerekir.
Bunu talep etmek için şu öğeyi:
<uses-permission>
manifest dosyanıza <manifest> öğesinin alt öğesi olarak ekleyin:
<uses-permission android:name="android.permission.READ_CONTACTS" />
Kişileri ada 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 veya daha fazla kişinin 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 bir ListView içinde göstermek istersiniz.
ListView ve öğe düzenlerini tanımlama
Arama sonuçlarını bir ListView içinde görüntülemek için ListView dahil olmak üzere tüm kullanıcı arayüzünü tanımlayan bir ana düzen dosyasına ve ListView öğesinin bir satırını tanımlayan bir öğe düzeni 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ı kullanır
android:id/list.
Öğe düzeni dosyasını contacts_list_item.xml 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çıklanmamaktadır. Bunun nedeni, dizeyi dolaylı olarak almak isteyebilmenizdir. Örneğin, kullanıcıya, adı gelen bir kısa mesajdaki 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. Bir sonraki adım, kişi listesini görüntülemek için bu kullanıcı arayüzünü kullanan bir kod yazmaktır.
Kişi listesini gösteren bir Fragment tanımlama
Kişi listesini görüntülemek için öncelikle Fragment tarafından yüklenen bir Activity tanımlayarak başlayın. Fragment kullanmak daha esnek bir tekniktir. Çünkü listeyi göstermek için bir Fragment, kullanıcının listeden seçtiği bir kişinin ayrıntılarını göstermek için ise ikinci bir Fragment kullanabilirsiniz. Bu yaklaşımı kullanarak bu derste sunulan tekniklerden birini
Kişi ayrıntılarını alma dersindeki tekniklerden biriyle birleştirebilirsiniz.
Bir Fragment nesnesinden bir veya daha fazla Activity nesnesini nasıl kullanacağınızı öğrenmek için
Parçalarla dinamik kullanıcı arayüzü oluşturma adlı eğitim sınıfını inceleyin.
Android çerçevesi, Contacts Provider'a yönelik sorgular yazmanıza yardımcı olmak için ContactsContract adlı bir ilişkili sınıf sağlar. Bu sınıf, sağlayıcıya erişmek için kullanışlı 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 sabitlerinizi 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 CursorLoader kullandığından, yükleyici arayüzünü LoaderManager.LoaderCallbacks uyguladığını belirtmeniz gerekir. 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. Ö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 için Android 3.0 (API sürümü 11) veya sonraki bir sürüm gerektiğinden uygulamanızın minSdkVersion değerini 10 veya daha düşük bir değere ayarladığınızda Android Studio'da Android Lint uyarısı oluşturulur. Bu uyarıyı devre dışı bırakmak için FROM_COLUMNS tanımından önce @SuppressLint("InlinedApi") ek açıklamasını ekleyin.
Fragment'ı başlatma
Fragment başlatın. Android sisteminin gerektirdiği boş, herkese açık kurucuyu ekleyin ve geri çağırma yönteminde (onCreateView()) Fragment nesnesinin kullanıcı arayüzünü genişletin.
Ö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
Aramanın sonuçlarını ListView öğesine bağlayan SimpleCursorAdapter öğesini ayarlayın. Kişileri gösteren ListView nesnesini almak için Fragment öğesinin üst etkinliğini kullanarak Activity.findViewById() yöntemini çağırmanız gerekir. setAdapter() yöntemini çağırırken üst etkinliğin Context değerini 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 dinleyicisini ayarlama
Bir aramanın sonuçlarını gösterdiğ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 kişinin adresini haritada gösterebilirsiniz. Bu özelliği sağlamak için öncelikle Kişi listesini gösteren bir Fragment 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 dinleyicisi olarak tanımladınız.
Dinleyiciyi ayarlamaya devam etmek için onActivityCreated() içinde setOnItemClickListener() yöntemini çağırarak ListView öğesine 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öntemini uygulamanız gerekir. Bu durum sonraki bir bölümde açıklanmıştır.
Projeksiyon tanımlama
Sorgunuzdan döndürmek istediğiniz sütunları içeren bir sabit tanımlayın. ListView içindeki her öğe, kişinin görünen adını gösterir. Bu ad, kişinin adının ana biçimini içerir. Android 3.0 (API sürümü 11) ve sonraki sürümlerde bu sütunun adı Contacts.DISPLAY_NAME_PRIMARY, önceki sürümlerde ise Contacts.DISPLAY_NAME'dir.
Contacts._ID sütunu, SimpleCursorAdapter bağlama sürecinde kullanılır.
Contacts._ID ve
LOOKUP_KEY, kullanıcının seçtiği kişi için
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 sabitler tanımlama
Cursor içindeki tek bir sütundan veri almak için sütunun Cursor içindeki dizinine ihtiyacınız vardır. Dizinler, projeksiyonunuzdaki sütun adlarının sırasıyla aynı olduğundan Cursor sütunlarının dizinleri için sabitler 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 aranacak veri sütunlarını ve bulunacak değerleri bildiren metin ifadeleri ile değişkenlerin bir kombinasyonunu oluşturun.
Metin ifadesi için arama sütunlarını listeleyen bir sabit tanımlayın. Bu ifade değerler de içerebilse de tercih edilen yöntem, değerleri "?" yer tutucusuyla temsil etmektir. Alma sırasında yer tutucu, bir dizideki değerlerle değiştirilir. Yer tutucu olarak "?" kullanıldığında arama spesifikasyonu SQL derlemesi yerine bağlama yoluyla oluşturulur. Bu uygulama, kötü amaçlı SQL yerleştirme olasılığını 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 dinleyicisini ayarlamıştınız.
Şimdi AdapterView.OnItemClickListener.onItemClick() yöntemini tanımlayarak dinleyici için işlemi 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şlatma
Verileri 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 ilk kullanıma hazırlamanız gerekir. Başlatma işlemini, aşağıdaki örnekte gösterildiği gibi onCreate() içinde 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() yöntemini uygulama
Yükleyici çerçevesi tarafından initLoader() çağrıldıktan hemen sonra çağrılan onCreateLoader() yöntemini uygulayın.
onCreateLoader() içinde,
arama dizesi kalıbını ayarlayın. Bir dizeyi kalıba dönüştürmek için sıfır veya daha fazla karakterden oluşan bir diziyi temsil eden "%" (yüzde) karakterlerini ya da tek bir karakteri temsil eden "_" (alt çizgi) karakterlerini veya her ikisini birden ekleyin. Ö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 URI'si için Contacts.CONTENT_URI 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, Kişiler Sağlayıcı sorgu sonuçlarını döndürdüğünde onLoadFinished()
çağrısını yapar. Bu yöntemde, sonucu Cursor
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 veriler 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 arama dizesini kişi adlarıyla eşleştiren ve sonucu ListView olarak döndüren bir uygulamanın temel parçalarına sahipsiniz. Kullanıcı, seçmek için bir kişi adını tıklayabilir.
Bu işlem, kişinin verileriyle daha fazla işlem yapabileceğiniz bir dinleyiciyi tetikler. Örneğin,
kişinin ayrıntılarını alabilirsiniz. Bunu nasıl yapacağınızı öğrenmek için sonraki ders olan Kişi bilgilerini alma ile devam edin.
Arama kullanıcı arayüzleri hakkında daha fazla bilgi edinmek için API kılavuzundaki Arama arayüzü oluşturma başlıklı makaleyi inceleyin.
Bu dersteki diğer bölümlerde, Contacts Provider'da kişileri bulmanın diğer yolları gösterilmektedir.
Kişileri 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, bu tür sorguların özel bir örneğidir ancak bunu bir kişiyle ilişkili ayrıntılı veri türlerinden herhangi biri 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 bir alma işlemini uygulamak için önce önceki bölümlerde listelenen aşağıdaki kodu uygulayın:
- Sağlayıcıyı okuma izni isteyin.
- ListView ve öğe düzenlerini tanımlayın.
- Kişi listesini gösteren bir Fragment 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.
-
İmleç sütun dizinleri için sabitler tanımlayın.
Verileri farklı bir tablodan alıyor olsanız da projeksiyondaki sütunların sırası aynıdır. Bu nedenle, imleç 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ı verisi türüyle eşleştirmek ve sonuçları görüntülemek için gereken 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ındaki bir sabit CONTENT_ITEM_TYPE tarafından tanımlanan benzersiz bir MIME türü değeri vardır.
Alt sınıfların adları, veri türlerini gösterir. Ö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. Yansıtma, seçim yan tümcesi ve sıralama ölçütü için ihtiyacınız olan tüm sabitler bu tabloda tanımlanır veya bu tablo tarafından devralınır.
Tahmin tanımlama
Bir projeksiyon tanımlamak için ContactsContract.Data içinde tanımlanan sütunlardan veya devraldığı sınıflardan birini ya da daha fazlasını seçin. Kişiler sağlayıcı, satırları döndürmeden önce ContactsContract.Data ile diğer tablolar arasında örtülü bir birleştirme işlemi yapar. Ö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ımlama
Belirli bir veri türü içinde 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şir.
Bu nedenle, veri türüne karşılık gelen
ContactsContract.CommonDataKindsalt 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.ADDRESSsütununu kullanın. - Seçim yan tümcesinde "?" karakteriyle temsil edilen arama dizesinin kendisi.
-
Özel MIME türü değerini içeren sütunun adı. Bu ad her zaman
Data.MIMETYPEolur. -
Veri türü için özel MIME türü değeri. Daha önce açıklandığı gibi bu,
ContactsContract.CommonDataKindsalt sınıfındakiCONTENT_ITEM_TYPEsabitidir. Örneğin, e-posta verileri için MIME türü değeriEmail.CONTENT_ITEM_TYPEşeklindedir. Sabitin başına ve sonuna "'" (tek tırnak) karakteri ekleyerek 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 bir değer yerine sabit bir değer kullandığınız için 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() yöntemini uygulama
İstediğiniz verileri ve bunları nasıl bulacağınızı belirttikten sonra onCreateLoader() uygulamanızda bir sorgu tanımlayın.
Bu yöntemde, projeksiyonunuzu, seçim metni ifadenizi ve seçim dizinizi bağımsız değişken olarak kullanarak 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ı verisi türüne dayalı temel bir ters aramanın temelini oluşturur. Uygulamanız e-posta gibi belirli bir veri türüne odaklanıyorsa ve kullanıcıların bir veri parçasıyla ilişkili adları almasına izin vermek istiyorsanız bu teknik en iyi yöntemdir.
Kişileri herhangi bir veri türüne göre eşleştirme
Herhangi bir veri türüne göre kişi alma işlemi, verilerinden herhangi biri (ad, e-posta adresi, posta adresi, telefon numarası vb.) arama dizesiyle eşleşen kişileri döndürür. Bu durumda, geniş bir arama sonuçları kümesi elde edilir. Örneğin, arama dizesi "Doe" ise herhangi bir veri türü için yapılan arama, "John Doe" kişisini ve "Doe Caddesi"nde yaşayan kişileri döndürür.
Bu tür bir alma işlemini uygulamak için önce önceki bölümlerde listelenen aşağıdaki kodu uygulayın:
- Sağlayıcıyı okuma izni isteyin.
- ListView ve öğe düzenlerini tanımlayın.
- Kişi listesini gösteren bir Fragment 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.
- Bir projeksiyon tanımlayın.
-
İmleç sütun dizinleri için sabitler tanımlayın.
Bu tür bir alma işlemi için 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() 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östermek için gereken ek kod gösterilmektedir.
Seçim ölçütlerini kaldırma
SELECTION sabitlerini veya mSelectionArgs değişkenini tanımlamayın.
Bu tür alma işleminde bunlar kullanılmaz.
onCreateLoader() yöntemini uygulama
Yeni bir CursorLoader döndüren onCreateLoader() yöntemini uygulayın.
Kişiler sağlayıcı bunu otomatik olarak yaptığından arama dizesini kalıba dönüştürmeniz gerekmez. Temel URI olarak Contacts.CONTENT_FILTER_URI kullanın ve Uri.withAppendedPath() çağrısı yaparak arama dizenizi buna ekleyin. Bu URI'yi kullanmak, aşağıdaki örnekte gösterildiği gibi herhangi bir veri türü için 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ı bir arama yapan bir uygulamanın temelini oluşturur. Bu teknik, Kişiler uygulamasının kişi listesi ekranına benzer bir işlev uygulamak isteyen uygulamalar için kullanışlıdır.