MapActivityを使っているときに、地名検索ができるといいのになぁと。その際にGoogleが提供しているMapアプリのように検索ボタンを押したら画面上部に検索フォームが出てきて、さらにボイス検索まで出来たら素晴らしいのだろうが、これは一体どうやてやるのだろうか?と思って色々と検索していたら、わかりやすく紹介されている方がおられたので、それを参考にした。
searchableを使用する方法 – haruserのめもちょ
なお、今回は検索フォームで入力された内容をToastで表示するまでをやります。
さらにさらに、今書いている環境が実際に作業した環境ではないので、かなりうろ覚えで書いてます。多分大丈夫だと思うけれど、間違っていたらすみません。ご指摘お願いします。
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:imeOptions="actionSearch" android:searchMode="showSearchLabelAsBadge" android:inputType="text" android:voiceSearchMode="showVoiceSearchButton|launchRecognizer" />
android:voiceSearchModeを上記のように設定しておくだけで、音声検索対象言語は端末に設定されている言語になるようなので、日本語を選択している場合はこのままでいいし、外国語の場合でも勝手に外国語になってくれるっぽいです。固定にしたい場合はほかのパラメータを追加していくことになりそうですが、今回は必要ないので設定していません。また、音声検索できない端末の場合は、音声検索ボタン自体が表示されません(Nexus One, Desireで表示されたが、HT-03Aで表示されなかったことを確認)。
2.次に呼び出し元のActivityの設定を行うためにマニフェストを修正します。
今回は検索フォームに入力された内容を自分自身のアクティビティに渡します。
違うアクティビティに渡したい場合は、上のほうに書いたURLのほうをご参照ください。
<activity android:name="Map" android:label="@string/app_name" android:launchMode="singleTop"> <intent-filter> <action android:name="com.example.VIEW_SEARCH" /> <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="Map" /> <meta-data android:name="android.app.searchable" android:resource="@xml/searchable" /> </activity>
3.onSearchRequestedメソッドを呼び出します。
検索キーが押されたらコールされますが、メニューなどに検索を付けている場合は、メニューボタンが押されたらonSearchRequestedを呼び出すようにしておきましょう!
4.Activityに、onNewIntentを実装しましょう。
検索と結果が同じ画面でandroid:launchMode=”singleTop”が指定されていれば、onNewIntentメソッドが呼び出されるので、そこで検索処理を実行します。
@Override protected void onNewIntent(Intent intent) { if (Intent.ACTION_SEARCH.equals(intent.getAction())) { String query = intent.getStringExtra(SearchManager.QUERY); // 検索処理を実行 今回はToastを表示 Toast.makeText(this, query, Toast.LENGTH_LONG).show(); // 自分がやった実装ではGeoCoderで地名検索させて、Addressに変換させた。 } }
1つのアクティビティ内で完結する検索フォームの実装方法は、思ったよりも簡単でよかったです。searchableを使わない場合は、もうひとつ検索用ActivityをかませてIntent経由で結果を取得して、となるので、検索用Activityのレイアウトを実装しなければならなかったりと、面倒なことが多そうなので、こちらのほうがスマートかなと思います。
今回の実装はあんまりコード書いてないのに音声検索までできてしまうので、人に見せたら「スゴイ!!」と言われてちょっと嬉しかったりする。。。(^_^;)