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ı veya bir kısmıyla eşleştirerek bir kişi listesi alın. Kişi Sağlayıcı, aynı adın birden çok örneğine izin verdiğinden bu teknik, eşleşmelerin listesini döndürebilir.
- Belirli bir veri türüyle (ör. telefon numarası) eşleştirme
- Arama dizesini e-posta adresi gibi belirli bir ayrıntı veri türüyle eşleştirerek kişilerin listesini alın. Ö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ştirilebilir.
- 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 sayesinde bir arama dizesi için her tür veriyi kabul edebilir ve ardından verilerin diziyle eşleştiği kişileri listeleyebilirsiniz.
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 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 Android eğitim sınıfı
Arka Planda Veri Yükleme'ye bakın.
Sağlayıcıyı okuma izni isteme
Kişiler sağlayıcısında herhangi bir türde arama yapmak için uygulamanızın READ_CONTACTS
iznine sahip olması gerekir.
Bu özelliği talep etmek için şu <uses-permission>
öğesini manifest dosyanıza <manifest>
öğesinin alt öğesi olarak ekleyin:
<uses-permission android:name="android.permission.READ_CONTACTS" />
Bir kişiyi 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örüntülemek isteyebilirsiniz.
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
.
Öğ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ı
android:text1
kullanır.
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 gelen kısa mesajdaki bir dizeyle eşleşen adlara sahip 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 kod yazmaktır.
Kişi listesini gösteren bir Fragment tanımlama
Kişi listesini görüntülemek için bir Activity
tarafından yüklenen bir Fragment
tanımlayarak başlayın. Fragment
kullanmak daha esnek bir tekniktir. Çünkü 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
kullanabilirsiniz. Bu yaklaşımı kullanarak, bu derste sunulan tekniklerden birini
Bir kişinin ayrıntılarını alma dersindeki bir teknikle birleştirebilirsiniz.
Bir Activity
içinden bir veya daha fazla Fragment
nesnesini nasıl kullanacağınızı öğrenmek için
Parçalarla dinamik kullanıcı arayüzü oluşturma başlıklı eğitim sınıfını okuyun.
Android çerçevesi, Kişi Sağlayıcısı'na göre sorgu yazmanıza yardımcı olmak amacıyla, sağlayıcıya erişmek için kullanışlı sabit değerler ve yöntemleri tanımlayan ContactsContract
adlı bir sözleşme sınıfı sağlar. 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 beyanı ekleyin:
Kotlin
import android.provider.ContactsContract
Java
import android.provider.ContactsContract;
Kod, sağlayıcıdan veri almak için 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 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: Contacts.DISPLAY_NAME_PRIMARY
, Android 3.0 (API sürümü 11) veya sonraki sürümleri gerektirdiğinden, uygulamanızın minSdkVersion
değerini 10 veya önceki bir sürüme ayarlamak Android Studio'da bir Android Lint uyarısı oluşturur. 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ı ilk kullanıma hazırlama
Fragment
öğesini başlatın. Android sisteminin gerektirdiği boş, herkese açık bir kurucu ekleyin ve onCreateView()
geri çağırma yönteminde Fragment
nesnesinin kullanıcı arayüzünü şişirin.
Ö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
öğesine bağlayan SimpleCursorAdapter
özelliğini ayarlayın. Kişileri gösteren ListView
nesnesini almak için Fragment
üst etkinliğini kullanarak Activity.findViewById()
öğesini çağırmanız gerekir. setAdapter()
adlı kişiyi çağırdığınızda ebeveyn etkinliğinin Context
kadarını kullanın.
Ö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 dinleyicisini ayarlama
Bir aramanın sonuçlarını görüntülerken 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
'ı uyguladığını belirterek mevcut Fragment
öğesini tıklama dinleyicisi olarak tanımladınız.
Dinleyiciyi ayarlamaya devam etmek için onActivityCreated()
içinde setOnItemClickListener()
yöntemini çağırarak dinleyiciyi ListView
'e bağlayın. Ö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); ... }
Geçerli Fragment
değerinin ListView
için OnItemClickListener
olduğunu belirttiğinizden, şimdi tıklama etkinliğini işleyen zorunlu onItemClick()
yöntemini uygulamanız gerekiyor. 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 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 11 sürümü) ve sonraki sürümlerde bu sütunun adı Contacts.DISPLAY_NAME_PRIMARY
, önceki sürümlerde ise Contacts.DISPLAY_NAME
'dur.
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 };
İmleç sütunu dizinleri için sabit değerler tanımlayın
Cursor
içindeki tek bir sütundan veri almak için sütunun Cursor
içindeki dizini gerekir. 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 sağlayıcıya aranacak veri sütunlarını ve bulunacak değerleri bildiren metin ifadeleri ile değişkenlerden oluşan bir kombinasyon oluşturun.
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. Alma işlemi sırasında yer tutucunun yerini bir dizideki değerlerle değiştirir. 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 olasılığını ortadan kaldırır. Ö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ımlama
Önceki bir bölümde, ListView
için öğe tıklama dinleyicisini ayarlamıştınız.
Şimdi, AdapterView.OnItemClickListener.onItemClick()
yöntemini tanımlayarak işleyici 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
Veri almak için CursorLoader
kullandığınızdan arka plan iş parçacığı ve asenkron almayı kontrol eden diğer değişkenleri başlatmanız gerekir. Aşağıdaki örnekte gösterildiği gibi onCreate()
içinde ilklendirmeyi 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()
işlevini çağırdıktan hemen sonra yükleyici çerçevesi tarafından çağrılan onCreateLoader()
işlevini uygulayın.
onCreateLoader()
içinde arama dizesi kalıbını ayarlayın. Bir dizeyi kalıp haline getirmek için sıfır veya daha fazla karakterden oluşan bir diziyi temsil etmek üzere "%" (yüzde) karakterleri ya da tek bir karakteri temsil etmek üzere "_" (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ürme. İç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() yöntemlerini uygulama
onLoadFinished()
yöntemini uygulayın. Kişi Sağlayıcı, sorgunun sonuçlarını döndürdüğünde yükleyici çerçevesi onLoadFinished()
yöntemini çağırır. Bu yöntemde, Cursor
sonucunu SimpleCursorAdapter
içine yerleştirin. 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); }
Yükleyici çerçevesi, Cursor
sonucunun eski veriler içerdiğini tespit ettiğinde onLoaderReset()
yöntemi çağrılır. Mevcut Cursor
öğesine yönelik 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. Ö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 arama dizesini kişi adlarıyla eşleştiren ve sonucu ListView
olarak döndüren uygulamanın temel parçalarına sahipsiniz. Kullanıcı, bir kişi adını tıklayarak seçebilir.
Bu işlem, kişi verilerini daha ayrıntılı şekilde işleyebileceğiniz bir dinleyiciyi tetikler. Örneğin, kullanıcının bilgilerini alabilirsiniz. Bunu nasıl yapacağınızı öğrenmek için Kişi ayrıntılarını alma adlı bir sonraki derse geçin.
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, Kişiler sağlayıcısında kişileri 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. Adla getirme, bu tür bir sorgunun özel bir örneğidir ancak bir kişiyle ilişkili ayrıntı veri türlerinin herhangi biri için de bu işlemi 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 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'u ve öğe düzenlerini tanımlayın.
- Kişilerin 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.
-
İşaretçi sütun dizinleri için sabit değerler tanımlayın.
Farklı bir tablodan veri alsanı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ı 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ırları döndürmeden önce ContactsContract.Data
ile diğer tablolar arasında örtülü 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 kriterlerini tanımlayın
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ş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 temsil edilen arama dizesinin kendisi.
-
Ö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
ContactsContract.CommonDataKinds
alt sınıfındaki sabitCONTENT_ITEM_TYPE
değeridir. Örneğin, e-posta verileri için MIME türü değeriEmail.CONTENT_ITEM_TYPE
'tür. 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ızdan 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ı belirledikten sonra onCreateLoader()
uygulamanızda bir sorgu tanımlayın.
Projeksiyonunuzu, seçtiğiniz metin ifadesini ve seçim dizisini 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
değerini kullanın. Ö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 e-postalar 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, kullanılabilecek en iyi tekniktir.
Bir kişiyi herhangi bir veri türüne göre 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şirse kişileri döndürür. Bu, geniş bir arama sonucu grubuyla 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'u ve öğe düzenlerini tanımlayın.
- Kişilerin 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 işleyiciyi ayarlayın.
- Projeksiyon tanımlayın.
-
İmleç sütunu dizinleri için sabit değerler tanımlayın.
Bu tür bir getirme işlemi 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() yöntemlerini 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ırma
SELECTION
sabitlerini veya mSelectionArgs
değişkenini tanımlamayın.
Bu bilgi alma işleminde bunlar kullanılmaz.
onCreateLoader() işlevini uygulama
onCreateLoader()
yöntemini uygulayın ve yeni bir CursorLoader
döndürü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'nin kullanılması, 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ı 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.