searchableを使用する方法
Androidで検索処理を実装しようと思って、標準アプリの動作を見てみると、メニューや検索ボタン(エミュレータではF5キー)で検索機能を呼び出し、画面上部からにょろっと検索窓が出現して検索処理を実行する。というのが標準的な動作となっているようだ。Marketのアプリの中には独自の動作をしているものもあったが、とりあえず標準的な方法について調べてみた。
API Demosの中にサンプル(App>Search)があったが、使えるまでに結構、遠回りしてしまったので、今後のためにメモ。
searchableを使用するまでの手順
1./res/xml に "searchable.xml" ファイルを作成
<searchable xmlns:android="http://schemas.android.com/apk/res/android" android:label="@string/search_label" android:hint="@string/search_hint" android:searchMode="showSearchLabelAsBadge" android:imeOptions="actionSearch" android:inputType="textPersonName"/>
2.AndroidManifest.xml に 追加
呼出元のActivity定義
<activity android:name=".SearchActivity" android:label="@string/app_name"> <intent-filter> <action android:name="android.intent.action.VIEW" /> <category android:name="android.intent.category.DEFAULT" /> </intent-filter> <!-- android:value には結果を表示するActivityを指定 --> <meta-data android:name="android.app.default_searchable" android:value=".ResultActivity" /> </activity>
※ android:name="android.app.default_searchable" の値の意味は不明
※ Activityタグの外側で宣言すれば、全画面から呼び出し可
結果表示先のActivity定義
<activity android:name=".ResultActivity" android:label="@string/app_name"> <!-- 検索BOXにて検索されたときは"Intent.ACTION_SEARCH"のIntentが飛ぶ --> <intent-filter> <action android:name="android.intent.action.SEARCH" /> <category android:name="android.intent.category.DEFAULT" /> </intent-filter> <!-- searchable.xmlのリソース指定 --> <meta-data android:name="android.app.searchable" android:resource="@xml/searchable" /> </activity>
※ searchable.xmlのリソース指定は結果表示のActivityで宣言でよい?
※ 検索と結果が同じ画面なら以下のように指定
<activity android:name=".SearchActivity" android:label="@string/app_name" android:launchMode="singleTop"> <intent-filter> <action android:name="android.intent.action.VIEW" /> <category android:name="android.intent.category.DEFAULT" /> </intent-filter> <intent-filter> <action android:name="android.intent.action.SEARCH" /> <category android:name="android.intent.category.DEFAULT" /> </intent-filter> <meta-data android:name="android.app.default_searchable" android:value=".SearchActivity" /> <meta-data android:name="android.app.searchable" android:resource="@xml/searchable" /> </activity>
※ android:launchMode="singleTop" でタスクが積み重ならない
3.Activityで検索窓の呼び出し
Activityで検索窓を呼び出すには以下のメソッドを呼べばよい。
メニュー押下時に呼び出すか、F5キーで呼び出される。
Activity#onSearchRequested();
4.検索文字列取得
検索窓は入力された文字列をIntentに設定して次のActivityに送るだけなので、結果表示ActivityではIntentからその文字列を取り出して検索処理を実行する。
if (Intent.ACTION_SEARCH.equals(intent.getAction())) {
String query = intent.getStringExtra(SearchManager.QUERY);
検索処理(query);
}
}
検索と結果が同じ画面でandroid:launchMode="singleTop"が指定されていれば、onNewIntentメソッドが呼び出されるので、そこで検索処理を実行する
@Override protected void onNewIntent(Intent intent) { if (Intent.ACTION_SEARCH.equals(intent.getAction())) { String query = intent.getStringExtra(SearchManager.QUERY); 検索処理(query); } }
で、とりあえず動く状態。
細かい定義などについては調査中。
SuggestやVoice検索も出来るようだが、詳細不明。
※Suggest機能についてメモ
searchable.xmlにSuggest指定android:searchSuggestAuthority="コンテントプロバイダのUri" android:searchSuggestSelection=" ? " android:searchSuggestIntentAction="android.intent.action.SEARCH"Suggestで表示された候補を選択したときは"Intent.ACTION_SEARCH"以外のActionも指定できる
入力履歴のSuggestは標準で"SearchRecentSuggestionsProviderクラス"がやってくれるみたい
独自のSuggestを使用する場合の注意点
Providerクラスの定義
URI_MATCHER.addURI(AUTHORITY, SearchManager.SUGGEST_URI_PATH_QUERY, 10);
Cursorのカラム名に_id, suggest_text_1,suggest_intent_queryは必須