このレッスンでは、連絡先の全部または一部とデータが一致する連絡先のリストを取得する方法を説明します。 次の手法を使用します。
- 連絡先の名前を照合する
- 検索文字列を連絡先の名前データの全部または一部と照合して、連絡先のリストを取得します。連絡先プロバイダでは同じ名前の複数のインスタンスを許容しているため、 一致のリストを返すことができます。
- 特定の種類のデータ(電話番号など)を照合する
- 検索文字列を特定の種類の詳細データ(メールアドレスなど)と照合して、連絡先のリストを取得します。たとえば、メールアドレスが検索文字列と一致するすべての連絡先を一覧表示できます。
- すべての種類のデータを照合する
- 検索文字列を任意のタイプの詳細データと照合して、連絡先のリストを取得します。 名前、電話番号、住所、メールアドレスなどが含まれますたとえば、検索文字列に任意の型のデータを受け入れ、データが文字列に一致する連絡先を一覧表示できます。
注: このレッスンのすべての例では、CursorLoader
を使用して連絡先プロバイダからデータを取得します。CursorLoader
は、UI スレッドとは別のスレッドでクエリを実行します。これにより、クエリによって UI が遅くなることが
ユーザーエクスペリエンスの低下につながります詳しくは、Android トレーニング クラスのバックグラウンドでのデータの読み込みをご覧ください。
プロバイダの読み取り権限をリクエストする
連絡先プロバイダでなんらかの種類の検索を行うには、アプリに READ_CONTACTS
権限が必要です。この権限をリクエストするには、<uses-permission>
要素を <manifest>
の子要素としてマニフェスト ファイルに追加します。
<uses-permission android:name="android.permission.READ_CONTACTS" />
連絡先を名前で照合して結果を一覧表示する
この手法では、検索文字列を、連絡先プロバイダの ContactsContract.Contacts
テーブル内にある連絡先の名前と照合します。通常は
結果を ListView
に表示して、ユーザーが選択できるようにします。
表示されます。
ListView とアイテム レイアウトを定義する
検索結果を ListView
に表示するには、メイン レイアウト ファイルが必要です。
(ListView
を含む UI 全体と、アイテム レイアウトを定義する)
このファイルで ListView
の 1 行を定義します。たとえば、スペースを作成して
メイン レイアウト ファイル res/layout/contacts_list_view.xml
を、
次の XML を使用します。
<?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"/>
この XML は、組み込みの Android ListView
ウィジェットを使用します。
android:id/list
。
次の XML を使用して、アイテム レイアウト ファイル contacts_list_item.xml
を定義します。
<?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"/>
この XML は、組み込みの Android TextView
ウィジェットを使用します。
android:text1
。
注: このレッスンでは、ユーザーから検索文字列を取得するための UI については説明しません。ユーザーから間接的に文字列を取得した方がよいからです。たとえば、ユーザーに 受信したテキスト メッセージの文字列と名前が一致する連絡先を検索するオプション。
作成した 2 つのレイアウト ファイルは、ListView
を表示するユーザー インターフェースを定義します。次のステップでは、この UI を使用して
連絡先のリストを表示します。
連絡先のリストを表示するフラグメントを定義する
連絡先のリストを表示するには、まず Fragment
を定義します。
Activity
によって読み込まれます。使用
Fragment
は、より柔軟な手法です。
1 つFragment
でリストを表示し、もう 1 つ
Fragment
を使用して、ユーザーがアクセスした連絡先の詳細を表示します。
選択します。このアプローチを使用すると、このレッスンで紹介した手法のいずれかと、連絡先の詳細を取得するで紹介する手法を組み合わせることができます。
Activity
から 1 つまたは複数の Fragment
オブジェクトを使用する方法については、トレーニング クラスのフラグメントを使って動的 UI を作成するをご覧ください。
連絡先プロバイダに対するクエリを作成できるように、Android フレームワークには
ContactsContract
というコントラクト クラスを使用します。このクラスは、
定数とメソッドを定義します。このクラスを使用すれば、
コンテンツ URI、テーブル名、列に独自の定数を定義できます。このクラスを使用するには、次のステートメントを含めます。
Kotlin
import android.provider.ContactsContract
Java
import android.provider.ContactsContract;
コードは CursorLoader
を使用してプロバイダからデータを取得するため、ローダ インターフェース LoaderManager.LoaderCallbacks
を実装するように指定する必要があります。また どの連絡先が
ユーザーが検索結果のリストから選択し、アダプタ インターフェースを実装する
AdapterView.OnItemClickListener
。次に例を示します。
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 {
グローバル変数を定義する
コードの他の部分で使用されるグローバル変数を定義します。
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; ...
注: Contacts.DISPLAY_NAME_PRIMARY
を使用するには、Android 3.0(API バージョン 11)以降が必要です。アプリの minSdkVersion
を 10 以下に設定すると、Android Studio で Android Lint 警告が生成されます。この警告をオフにするには、アノテーションを
FROM_COLUMNS
の定義の前に @SuppressLint("InlinedApi")
。
フラグメントを初期化する
Fragment
を初期化します。Android システムに必要な空のパブリック コンストラクタを追加し、コールバック メソッド onCreateView()
で Fragment
オブジェクトの UI をインフレートします。次に例を示します。
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 の CursorAdapter を設定する
検索結果を ListView
にバインドする SimpleCursorAdapter
を設定します。ListView
オブジェクトを取得する
では、次の親アクティビティを使用して Activity.findViewById()
を呼び出す必要があります。
Fragment
。setAdapter()
を呼び出すときには、親アクティビティの Context
を使用します。次に例を示します。
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); }
選択した連絡先リスナーを設定する
検索結果を表示するとき、通常はユーザーが検索結果を
1 つの連絡先だけを渡して処理を続行します。たとえば、ユーザーが連絡先をクリックすると
連絡先の住所を地図上に表示する。この機能を提供するには、まず現在の
クリック リスナーとして Fragment
を使用するクラスを指定します。
セクションに示すように、AdapterView.OnItemClickListener
を実装しています。
連絡先のリストを表示する Fragment を定義する。
リスナーの設定を続けるには、次のコマンドを使用して ListView
にバインドします。
onActivityCreated()
の setOnItemClickListener()
メソッドを呼び出す。次に例を示します。
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); ... }
現在の Fragment
を
OnItemClickListener
:
ListView
の必要なメソッドを実装する必要があります。
onItemClick()
、これは
クリック イベントを処理します。これについては、次のセクションで説明します。
プロジェクションを定義する
クエリから返す列を含む定数を定義します。ListView
の各項目には、連絡先の表示名が表示されます。これには、連絡先の名前のメインフォームが含まれます。この列の名前は、Android 3.0(API バージョン 11)以降では Contacts.DISPLAY_NAME_PRIMARY
、それより前のバージョンでは Contacts.DISPLAY_NAME
です。
列 Contacts._ID
は、
SimpleCursorAdapter
バインディング プロセス。
Contacts._ID
、
LOOKUP_KEY
を併用することで、以下のことが可能になります。
ユーザーが選択した連絡先のコンテンツ URI を作成します。
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 };
Cursor 列のインデックスの定数を定義する
Cursor
内の各列からデータを取得するには、Cursor
内の列のインデックスが必要です。インデックスはプロジェクションの列名の順序と同じであるため、Cursor
列のインデックスに定数を定義できます。次に例を示します。
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;
選択基準を指定する
必要なデータを指定するには、テキスト式と変数の組み合わせを作成します 検索対象のデータ列と検索する値をプロバイダに指示します。
テキスト表現には、検索列をリストする定数を定義します。この式には値を含めることもできますが、値をプレースホルダ「?」で表すことをおすすめします。取得時に、プレースホルダは あります。「?」の使用プレースホルダとして使用することで、バインディングによって検索仕様が生成される SQL のコンパイルではなくこれにより、悪意のある SQL インジェクションの可能性が排除されます。次に例を示します。
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() メソッドを定義する
前のセクションでは、ListView
のアイテム クリック リスナーを設定しました。
次に、メソッド 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. */ }
ローダを初期化する
CursorLoader
を使用してデータを取得するため、非同期的な取得を制御するバックグラウンド スレッドとその他の変数を初期化する必要があります。次のように初期化します。
として onCreate()
例を示しています。
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() を実装する
メソッドを実装する
onCreateLoader()
、
このメソッドは、
initLoader()
。
onCreateLoader()
で検索文字列のパターンを設定します。文字列をパターンにするには、ゼロ個以上の一連の文字を表す「%(パーセント)」記号と、単一の文字を表す「_(アンダースコア)」記号のいずれかまたは両方を挿入します。たとえば、パターン「%Jefferson%」は、
「Thomas Jefferson」と“Jefferson Davis”です
メソッドから新しい CursorLoader
を返します。コンテンツ URI には Contacts.CONTENT_URI
を使用します。次の例に示すように、この URI はテーブル全体を参照します。
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() と onLoaderReset() を実装する
onLoadFinished()
メソッドを実装します。ローダー フレームワークは、
onLoadFinished()
連絡先プロバイダがクエリの結果を返したとき。この方法では、
結果 Cursor
SimpleCursorAdapter
。これにより、
ListView
と検索結果:
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()
メソッドは、結果の Cursor
に古いデータが含まれていることをローダ フレームワークが検出したときに呼び出されます。削除
SimpleCursorAdapter
参照で既存の
Cursor
。そうでない場合、ローダー フレームワークは
Cursor
をリサイクルするため、メモリリークが発生します。次に例を示します。
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); }
これで、検索文字列を連絡先の名前と照合し、結果を ListView
に返すアプリの重要な部分ができました。ユーザーは連絡先名をクリックして選択できます。
これによりリスナーがトリガーされ、連絡先のデータをさらに操作できます。たとえば
連絡先の詳細を取得できます。この方法については、次のレッスン連絡先の詳細を取得するをご覧ください。
検索ユーザー インターフェースについて詳しくは、API ガイド検索インターフェースを作成するをご覧ください。
このレッスンの残りのセクションでは、連絡先プロバイダで連絡先を見つけるその他の方法を示します。
特定の種類のデータで連絡先を照合する
この手法では、照合するデータの種類を指定できます。このようなクエリの具体的な例として、名前による取得が挙げられます。ただし、このようなクエリは、連絡先に関連付けられているすべての種類の詳細データに対して実行できます。たとえば、特定の郵便番号を持つ連絡先を取得できます。この場合、検索文字列は郵便番号行に格納されているデータと一致する必要があります。
このタイプの取得を実装するには、まず次のコードを実装してください: (前のセクションまで):
- プロバイダの読み取り権限をリクエストします。
- ListView とアイテム レイアウトを定義します。
- 連絡先のリストを表示するフラグメントを定義します。
- グローバル変数を定義します。
- フラグメントを初期化する。
- ListView の CursorAdapter を設定する。
- 選択した連絡先リスナーを設定する。
-
Cursor 列のインデックスの定数を定義します。
別のテーブルからデータを取得しても、プロジェクションの列の順序は同じであるため、Cursor に同じインデックスを使用できます。
- onItemClick() メソッドを定義します。
- ローダを初期化します。
- onLoadFinished() と onLoaderReset() を実装します。
次の手順では、検索文字列との照合に必要な追加のコードを示します。 結果を表示します
データの種類とテーブルを選択する
特定の種類の詳細データを検索するには、そのデータ型のカスタム MIME タイプの値を確認する必要があります。データの種類ごとに、一意の MIME タイプの値があります。この値は、データの種類に関連付けられている ContactsContract.CommonDataKinds
のサブクラスにある定数 CONTENT_ITEM_TYPE
で定義されます。サブクラスには、データ型を示す名前が付けられています。たとえば email のサブクラスは
データが ContactsContract.CommonDataKinds.Email
、カスタム MIME
メールデータの型は、定数値によって定義されます。
Email.CONTENT_ITEM_TYPE
。
検索には ContactsContract.Data
テーブルを使用します。こちらの
射影、選択句、並べ替え順序に必要な定数は、
継承されます。
プロジェクションを定義する
プロジェクションを定義するには、ContactsContract.Data
または継承元のクラスで定義されている 1 つ以上の列を選択します。連絡先プロバイダは、行を返す前に ContactsContract.Data
とその他のテーブル間で暗黙的な結合を行います。次に例を示します。
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 };
検索条件を定義する
特定の種類のデータ内で文字列を検索するには、以下のものから選択句を作成します。
-
検索文字列を含む列の名前。この名前はデータ型によって異なるため、データの種類に対応する
ContactsContract.CommonDataKinds
のサブクラスを見つけ、そのサブクラスから列名を選択する必要があります。たとえば、 使用する場合は、この列のEmail.ADDRESS
。 - 「?」で表される検索文字列自体選択句の任意の文字が含まれています。
-
カスタム MIME タイプの値を含む列の名前。この名前は常に
Data.MIMETYPE
。 -
データの種類のカスタム MIME タイプの値。前述のとおり、これは
ContactsContract.CommonDataKinds
サブクラス内にある定数CONTENT_ITEM_TYPE
です。たとえば、メールデータの MIME タイプの値はEmail.CONTENT_ITEM_TYPE
です。値を一重引用符で囲むには、 「'
」定数の先頭と末尾には(単一引用符)文字を追加します。それ以外の場合 プロバイダはその値を文字列値ではなく変数名として解釈します。 この値には、定数を使用するためプレースホルダを使用する必要はありません。 使用できます。
次に例を示します。
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 + "'";
次に、selection 引数を格納する変数を定義します。
Kotlin
private var searchString: String? = null private val selectionArgs: Array<String> = arrayOf("")
Java
String searchString; String[] selectionArgs = { "" };
onCreateLoader() を実装する
必要なデータとその検索方法を指定したら、次は
onCreateLoader()
の実装。
プロジェクション、選択したテキスト表現、選択配列を引数として使用して、このメソッドから新しい CursorLoader
を返します。コンテンツ URI には、次のコマンドを使用します。
Data.CONTENT_URI
。次に例を示します。
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 ); }
これらのコード スニペットは、特定の種類の詳細情報に基づく単純な逆引き参照に基づいています 分析できますアプリが特定の種類のデータに特化している場合に最適な手法です。 データに関連付けられた名前をユーザーが取得できるようにする場合です。
すべての種類のデータで連絡先を照合する
どのタイプのデータでも連絡先を取得すると、いずれかのデータが 名前、メールアドレス、住所、電話番号を含む検索文字列。 これにより、幅広い検索結果が得られます。たとえば、検索文字列が が「Doe」の場合、任意のデータ型を検索すると連絡先「John Doe」が返されます。また、 「Doe Street」に住んでいる連絡先を検索できます。
このタイプの取得を実装するには、まず次のコードを実装してください: (前のセクションまで):
- プロバイダの読み取り権限をリクエストします。
- ListView とアイテム レイアウトを定義します。
- 連絡先のリストを表示するフラグメントを定義します。
- グローバル変数を定義します。
- フラグメントを初期化する。
- ListView の CursorAdapter を設定する。
- 選択した連絡先リスナーを設定する。
- 射影を定義します。
-
Cursor 列のインデックスの定数を定義します。
このタイプの取得では、連絡先を名前で照合して結果を一覧表示するで使用したのと同じテーブルを使用します。こちらの 同じ列インデックスを使用します。
- onItemClick() メソッドを定義します。
- ローダを初期化します。
- onLoadFinished() と onLoaderReset() を実装します。
次の手順では、検索文字列との照合に必要な追加のコードを示します。 結果を表示します
選択基準を削除する
SELECTION
定数や mSelectionArgs
変数は定義しないでください。
これらは、このタイプの取得では使用されません。
onCreateLoader() を実装する
onCreateLoader()
メソッドを実装して、新しい CursorLoader
を返します。検索文字列をパターンに変換する必要はありません。連絡先プロバイダによって自動的に変換されます。Contacts.CONTENT_FILTER_URI
をベース URI として使用し、Uri.withAppendedPath()
を呼び出して検索文字列を付加します。この URI を使用すると、次の例に示すように、すべてのデータの種類の検索が自動的にトリガーされます。
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 ); }
次のコード スニペットは、連絡先プロバイダの幅広い検索を行うアプリの基礎となります。 この手法は、アプリ People の連絡先リスト画面に似た機能を実装するアプリで役立ちます。