1page.title=Creating a Search Interface 2page.tags=searchview 3@jd:body 4 5<div id="qv-wrapper"> 6<div id="qv"> 7 8 9<h2>In this document</h2> 10<ol> 11 <li><a href="#TheBasics">The Basics</a></li> 12 <li><a href="#SearchableConfiguration">Creating a Searchable Configuration</a></li> 13 <li><a href="#SearchableActivity">Creating a Searchable Activity</a> 14 <ol> 15 <li><a href="#DeclaringSearchableActivity">Declaring a searchable activity</a></li> 16 <li><a href="#PerformingSearch">Performing a search</a></li> 17 </ol> 18 </li> 19 <li><a href="#SearchDialog">Using the Search Dialog</a> 20 <ol> 21 <li><a href="#InvokingTheSearchDialog">Invoking the search dialog</a></li> 22 <li><a href="#LifeCycle">The impact of the search dialog on your activity lifecycle</a></li> 23 <li><a href="#SearchContextData">Passing search context data</a></li> 24 </ol> 25 </li> 26 <li><a href="#UsingSearchWidget">Using the Search Widget</a> 27 <ol> 28 <li><a href="#ConfiguringWidget">Configuring the search widget</a></li> 29 <li><a href="#WidgetFeatures">Other search widget features</a></li> 30 <li><a href="#UsingBoth">Using both the widget and the dialog</a></li> 31 </ol> 32 </li> 33 <li><a href="#VoiceSearch">Adding Voice Search</a></li> 34 <li><a href="#SearchSuggestions">Adding Search Suggestions</a></li> 35</ol> 36 37<h2>Key classes</h2> 38<ol> 39<li>{@link android.app.SearchManager}</li> 40<li>{@link android.widget.SearchView}</li> 41</ol> 42 43<h2>Related samples</h2> 44<ol> 45<li><a href="{@docRoot}resources/samples/SearchableDictionary/index.html">Searchable 46Dictionary</a></li> 47<li><a href="{@docRoot}resources/samples/ApiDemos/src/com/example/android/apis/view/SearchViewActionBar.html">SearchView 48 in the Action Bar</a></li> 49<li><a href="{@docRoot}resources/samples/ApiDemos/src/com/example/android/apis/view/SearchViewFilterMode.html">SearchView 50 filter mode</a></li> 51</ol> 52 53<h2>Downloads</h2> 54<ol> 55<li><a href="{@docRoot}design/downloads/index.html#action-bar-icon-pack">Action Bar 56Icon Pack</a></li> 57</ol> 58 59</div> 60</div> 61 62<p>When you're ready to add search functionality to your application, Android helps you implement 63the user interface with either a search dialog that appears at the top of the activity window or a 64search widget that you can insert in your layout. Both the search dialog and the widget can deliver 65the user's search query to a specific activity in your application. This way, the user can initiate 66a search from any activity where the search dialog or widget is available, and the system starts the 67appropriate activity to perform the search and present results.</p> 68 69<p>Other features available for the search dialog and widget include:</p> 70 71<ul> 72 <li>Voice search</li> 73 <li>Search suggestions based on recent queries</li> 74 <li>Search suggestions that match actual results in your application data</li> 75</ul> 76 77<p>This guide shows you how to set up your application to provide a search interface 78that's assisted by the Android system to deliver search queries, using either the 79search dialog or the search widget.</p> 80 81 82<h2 id="TheBasics">The Basics</h2> 83 84<div class="figure" style="width:250px"> 85<img src="{@docRoot}images/search/search-ui.png" alt="" height="417" /> 86<p class="img-caption"><strong>Figure 1.</strong> Screenshot of an application's search dialog.</p> 87</div> 88 89<p>Before you begin, you should decide whether you'll implement your search interface using the 90search dialog or the search widget. Both provide the same search features, but in slightly different 91ways:</p> 92 93<ul> 94 <li>The <strong>search dialog</strong> is a UI component that's controlled by the Android system. 95When activated by the user, the search dialog appears at the top of the activity, as shown in figure 961. 97 <p>The Android system controls all events in the search dialog. When the user 98submits a query, the system delivers the query to the activity that you specify to 99handle searches. The dialog can also provide search suggestions while the user types.</p></li> 100 101 <li>The <strong>search widget</strong> is an instance of {@link android.widget.SearchView} that 102you can place anywhere in your layout. By default, the search widget behaves like a standard {@link 103android.widget.EditText} widget and doesn't do anything, but you can configure it so that the 104Android system handles all input events, delivers queries to the appropriate activity, and provides 105search suggestions (just like the search dialog). However, the search widget is available only in 106Android 3.0 (API Level 11) and higher. 107 108<p class="note"><strong>Note:</strong> If you want, you can handle all user input into the 109search widget yourself, using various callback methods and listeners. This document, however, 110focuses on how to integrate the search widget with the system for an assisted search 111implementation. If you want to handle all user input yourself, read the reference documentation for 112{@link android.widget.SearchView} and its nested interfaces. </p></li> 113</ul> 114 115<p>When the user executes a search from the search dialog or a search widget, the system creates an 116{@link android.content.Intent} and stores the user query in it. The system then starts the activity 117that you've declared to handle searches (the "searchable activity") and delivers it the intent. To 118set up your application for this kind of assisted search, you need the following:</p> 119 120<ul> 121 <li>A searchable configuration 122 <p>An XML file that configures some settings for the search dialog or widget. It includes settings 123for features such as voice search, search suggestion, and hint text for the search box.</p></li> 124 <li>A searchable activity 125 <p>The {@link android.app.Activity} that receives the search query, searches your 126data, and displays the search results.</p></li> 127 <li>A search interface, provided by either: 128 <ul> 129 <li>The search dialog 130 <p>By default, the search dialog is hidden, but appears at the top of the screen when 131 you call {@link android.app.Activity#onSearchRequested()} (when the user presses your 132 Search button).</p> 133 </li> 134 <li>Or, a {@link android.widget.SearchView} widget 135 <p>Using the search widget allows you to put the search box anywhere in your activity. 136Instead of putting it in your activity layout, you should usually use 137{@link android.widget.SearchView} as an 138<a href="{@docRoot}guide/topics/ui/actionbar.html#ActionView">action view in the Action Bar</a>.</p> 139 </li> 140 </ul> 141 </li> 142</ul> 143 144<p>The rest of this document shows you how to create the searchable configuration, searchable 145activity, and implement a search interface with either the search dialog or search widget.</p> 146 147 148<h2 id="SearchableConfiguration">Creating a Searchable Configuration</h2> 149 150<p>The first thing you need is an XML file called the searchable configuration. It configures 151certain UI aspects of the search dialog or widget and defines how features such as suggestions and 152voice search behave. This file is traditionally named {@code searchable.xml} and must be saved in 153the {@code res/xml/} project directory.</p> 154 155<p class="note"><strong>Note:</strong> The system uses this file to instantiate a {@link 156android.app.SearchableInfo} object, but you cannot create this object yourself at 157runtime—you must declare the searchable configuration in XML.</p> 158 159<p>The searchable configuration file must include the <a 160href="{@docRoot}guide/topics/search/searchable-config.html#searchable-element">{@code 161<searchable>}</a> element as the root node and specify one 162or more attributes. For example:</p> 163 164<pre> 165<?xml version="1.0" encoding="utf-8"?> 166<searchable xmlns:android="http://schemas.android.com/apk/res/android" 167 android:label="@string/app_label" 168 android:hint="@string/search_hint" > 169</searchable> 170</pre> 171 172<p>The {@code android:label} attribute is the only required attribute. It points to a string 173resource, which should be the application name. This label isn't actually visible to the 174user until you enable search suggestions for Quick Search Box. At that point, this label is visible 175in the list of Searchable items in the system Settings.</p> 176 177<p>Though it's not required, we recommend that you always include the {@code android:hint} 178attribute, which provides a hint string in the search box before users 179enters a query. The hint is important because it provides important clues to users about what 180they can search.</p> 181 182<p class="note"><strong>Tip:</strong> For consistency among other 183Android applications, you should format the string for {@code android:hint} as "Search 184<content-or-product>". For example, "Search songs and artists" or "Search 185YouTube".</p> 186 187<p>The <a 188href="{@docRoot}guide/topics/search/searchable-config.html#searchable-element">{@code 189<searchable>}</a> element accepts several other attributes. However, you don't need 190most attributes until you add features such as <a href="#SearchSuggestions">search suggestions</a> 191and <a href="#VoiceSearch">voice search</a>. For detailed information about the searchable 192configuration file, see the <a 193href="{@docRoot}guide/topics/search/searchable-config.html">Searchable Configuration</a> reference 194document.</p> 195 196 197 198<h2 id="SearchableActivity">Creating a Searchable Activity</h2> 199 200<p>A searchable activity is the {@link android.app.Activity} in your application that performs 201searches based on a query string and presents the search results.</p> 202 203<p>When the user executes a search in the search dialog or widget, the system starts your 204searchable activity and delivers it the search query in an {@link 205android.content.Intent} with the {@link android.content.Intent#ACTION_SEARCH} action. Your 206searchable activity retrieves the query from the intent's {@link android.app.SearchManager#QUERY 207QUERY} extra, then searches your data and presents the results.</p> 208 209<p>Because you may include the search dialog or widget in any other activity in your application, 210the system must know which activity is your searchable activity, so it can properly deliver the 211search query. So, you must first declare your searchable activity in the Android manifest file.</p> 212 213 214<h3 id="DeclaringSearchableActivity">Declaring a searchable activity</h3> 215 216<p>If you don't have one already, create an {@link android.app.Activity} that will perform 217searches and present results. You don't need to implement the search functionality yet—just 218create an activity that you can declare in the manifest. Inside the manifest's <a 219href="{@docRoot}guide/topics/manifest/activity-element.html">{@code <activity>}</a> 220element:</p> 221<ol> 222 <li>Declare the activity to accept the {@link android.content.Intent#ACTION_SEARCH} intent, in an 223<a href="{@docRoot}guide/topics/manifest/intent-filter-element.html">{@code 224<intent-filter>}</a> 225element.</li> 226 <li>Specify the searchable configuration to use, in a <a 227href="{@docRoot}guide/topics/manifest/meta-data-element.html">{@code <meta-data>}</a> 228element.</li> 229</ol> 230 231<p>For example:</p> 232 233<pre> 234<application ... > 235 <activity android:name=".SearchableActivity" > 236 <intent-filter> 237 <action android:name="android.intent.action.SEARCH" /> 238 </intent-filter> 239 <meta-data android:name="android.app.searchable" 240 android:resource="@xml/searchable"/> 241 </activity> 242 ... 243</application> 244</pre> 245 246<p>The {@code <meta-data>} element must include the {@code android:name} attribute with a 247value of {@code "android.app.searchable"} and the {@code android:resource} attribute with a 248reference to the searchable configuration file (in this example, it 249refers to the {@code res/xml/searchable.xml} file).</p> 250 251<p class="note"><strong>Note:</strong> The <a 252href="{@docRoot}guide/topics/manifest/intent-filter-element.html">{@code 253<intent-filter>}</a> does not need a <a 254href="{@docRoot}guide/topics/manifest/category-element.html">{@code <category>}</a> with the 255{@code DEFAULT} value (which you usually see in <a 256href="{@docRoot}guide/topics/manifest/activity-element.html">{@code <activity>}</a> elements), 257because the system delivers the {@link android.content.Intent#ACTION_SEARCH} intent explicitly to 258your searchable activity, using its component name.</p> 259 260 261 262<h3 id="PerformingSearch">Performing a search</h3> 263 264<p>Once you have declared your searchable activity in the manifest, performing a search in your 265searchable activity involves three steps:</p> 266 267<ol> 268 <li><a href="#ReceivingTheQuery">Receiving the query</a></li> 269 <li><a href="#SearchingYourData">Searching your data</a></li> 270 <li><a href="#PresentingTheResults">Presenting the results</a></li> 271</ol> 272 273<p>Traditionally, your search results should be presented in a {@link android.widget.ListView}, so 274you might want your searchable activity to extend {@link android.app.ListActivity}. It includes 275a default layout with a single {@link android.widget.ListView} and provides several 276convenience methods for working with the {@link android.widget.ListView}.</p> 277 278 279<h4 id="ReceivingTheQuery">Receiving the query</h4> 280 281<p>When a user executes a search from the search dialog or widget, the system starts your 282searchable activity and sends it a {@link android.content.Intent#ACTION_SEARCH} intent. This intent 283carries the search query in the 284{@link android.app.SearchManager#QUERY QUERY} string extra. You must check for 285this intent when the activity starts and extract the string. For example, here's how you can get the 286search query when your searchable activity starts:</p> 287 288<pre> 289@Override 290public void onCreate(Bundle savedInstanceState) { 291 super.onCreate(savedInstanceState); 292 setContentView(R.layout.search); 293 294 // Get the intent, verify the action and get the query 295 Intent intent = getIntent(); 296 if (Intent.ACTION_SEARCH.equals(intent.getAction())) { 297 String query = intent.getStringExtra(SearchManager.QUERY); 298 doMySearch(query); 299 } 300} 301</pre> 302 303<p>The {@link android.app.SearchManager#QUERY QUERY} string is always included with 304the {@link android.content.Intent#ACTION_SEARCH} intent. In this example, the query is 305retrieved and passed to a local {@code doMySearch()} method where the actual search operation 306is done.</p> 307 308 309<h4 id="SearchingYourData">Searching your data</h4> 310 311<p>The process of storing and searching your data is unique to your application. 312You can store and search your data in many ways, but this guide does not show you how to store your 313data and search it. Storing and searching your data is something you should carefully consider in 314terms of your needs and your data format. However, here are some tips you might be able to 315apply:</p> 316 317 <ul> 318 <li>If your data is stored in a SQLite database on the device, performing a full-text search 319(using FTS3, rather than a {@code LIKE} query) can provide a more robust search across text data and 320can produce results significantly faster. See <a href="http://sqlite.org/fts3.html">sqlite.org</a> 321for information about FTS3 and the {@link android.database.sqlite.SQLiteDatabase} class for 322information about SQLite on Android. Also look at the <a 323href="{@docRoot}resources/samples/SearchableDictionary/index.html">Searchable Dictionary</a> sample 324application to see a complete SQLite implementation that performs searches with FTS3.</li> 325 <li>If your data is stored online, then the perceived search performance might be 326inhibited by the user's data connection. You might want to display a spinning progress wheel until 327your search returns. See {@link android.net} for a reference of network APIs and <a 328href="{@docRoot}guide/topics/ui/dialogs.html#ProgressDialog">Creating a Progress Dialog</a> 329for information about how to display a progress wheel.</li> 330 </ul> 331 332 333<div class="sidebox-wrapper"> 334<div class="sidebox"> 335<h2>About Adapters</h2> 336<p>An {@link android.widget.Adapter} binds each item from a set of data into a 337{@link android.view.View} object. When the {@link android.widget.Adapter} 338is applied to a {@link android.widget.ListView}, each piece of data is inserted as an individual 339view into the list. {@link 340android.widget.Adapter} is just an interface, so implementations such as {@link 341android.widget.CursorAdapter} (for binding data from a {@link android.database.Cursor}) are needed. 342If none of the existing implementations work for your data, then you can implement your own from 343{@link android.widget.BaseAdapter}. Install the SDK Samples package for API Level 4 to see the 344original version of the Searchable Dictionary, which creates a custom adapter to read data from 345a file.</p> 346</div> 347</div> 348 349<p>Regardless of where your data lives and how you search it, we recommend that you return search 350results to your searchable activity with an {@link android.widget.Adapter}. This way, you can easily 351present all the search results in a {@link android.widget.ListView}. If your data comes from a 352SQLite database query, you can apply your results to a {@link android.widget.ListView} 353using a {@link android.widget.CursorAdapter}. If your data comes in some other type of format, then 354you can create an extension of {@link android.widget.BaseAdapter}.</p> 355 356 357<h4 id="PresentingTheResults">Presenting the results</h4> 358 359<p>As discussed above, the recommended UI for your search results is a {@link 360android.widget.ListView}, so you might want your searchable activity to extend {@link 361android.app.ListActivity}. You can then call {@link 362android.app.ListActivity#setListAdapter(ListAdapter) setListAdapter()}, passing it an {@link 363android.widget.Adapter} that is bound to your data. This injects all the 364search results into the activity {@link android.widget.ListView}.</p> 365 366<p>For more help presenting your results in a list, see the {@link android.app.ListActivity} 367documentation.</p> 368 369<p>Also see the <a 370href="{@docRoot}resources/samples/SearchableDictionary/index.html">Searchable Dictionary</a> sample 371for an a complete demonstration of how to search an SQLite database and use an 372{@link android.widget.Adapter} to provide results in a {@link android.widget.ListView}.</p> 373 374 375 376 377 378<h2 id="SearchDialog">Using the Search Dialog</h2> 379 380<div class="sidebox-wrapper"> 381<div class="sidebox"> 382 <h2>Should I use the search dialog or the widget?</h2> 383 <p>The answer depends mostly on whether you are developing for Android 3.0 (API Level 11 or 384higher), because the {@link android.widget.SearchView} widget was introduced in Android 3.0. So, 385if you are developing your application for a version of Android lower than 3.0, the search widget is 386not an option and you should use the search dialog to implement your search interface.</p> 387 <p>If you <em>are</em> developing for Android 3.0 or higher, then the decision depends more on 388your needs. In most cases, we recommend that you use the search widget as an "action view" in the 389Action Bar. However, it might not be an option for you to put the search 390widget in the Action Bar for some reason (perhaps there's not enough space or you don't use the 391Action Bar). So, you might instead want to put the search widget somewhere in your activity layout. 392And if all else fails, you can still use the search dialog if you prefer to keep the search box 393hidden. In fact, you might want to offer both the dialog and the widget in some cases. For more 394information about the widget, skip to <a href="#UsingSearchWidget">Using the Search Widget</a>.</p> 395</div> 396</div> 397 398<p>The search dialog provides a floating search box at the top of the screen, with the application 399icon on the left. The search dialog can provide search suggestions as the user types and, when 400the user executes a search, the system sends the search query to a 401searchable activity that performs the search. However, if you are developing 402your application for devices running Android 3.0, you should consider using the search widget 403instead (see the side box).</p> 404 405<p>The search dialog is always hidden by default, until the user activates it. Your application 406can activate the search dialog by calling {@link 407android.app.Activity#onSearchRequested onSearchRequested()}. However, this method doesn't work 408until you enable the search dialog for the activity.</p> 409 410<p>To enable the search dialog, you must indicate to the system which searchable activity should 411receive search queries from the search dialog, in order to perform searches. For example, in the 412previous section about <a href="#SearchableActivity">Creating a Searchable Activity</a>, a 413searchable activity named {@code SearchableActivity} was created. If you want a separate activity, 414named {@code OtherActivity}, to show the search dialog and deliver searches to {@code 415SearchableActivity}, you must declare in the manifest that {@code SearchableActivity} is the 416searchable activity to use for the search dialog in {@code OtherActivity}.</p> 417 418<p>To declare the searchable activity for an activity's search dialog, 419add a <a href="{@docRoot}guide/topics/manifest/meta-data-element.html">{@code <meta-data>}</a> 420element inside the respective activity's <a 421href="{@docRoot}guide/topics/manifest/activity-element.html">{@code <activity>}</a> element. 422The <a href="{@docRoot}guide/topics/manifest/meta-data-element.html">{@code <meta-data>}</a> 423element must include the {@code android:value} attribute that specifies the searchable activity's 424class name and the {@code android:name} attribute with a value of {@code 425"android.app.default_searchable"}.</p> 426 427<p>For example, here is the declaration for 428both a searchable activity, {@code SearchableActivity}, and another activity, {@code 429OtherActivity}, which uses {@code SearchableActivity} to perform searches executed from its 430search dialog:</p> 431 432<pre> 433<application ... > 434 <!-- this is the searchable activity; it performs searches --> 435 <activity android:name=".SearchableActivity" > 436 <intent-filter> 437 <action android:name="android.intent.action.SEARCH" /> 438 </intent-filter> 439 <meta-data android:name="android.app.searchable" 440 android:resource="@xml/searchable"/> 441 </activity> 442 443 <!-- this activity enables the search dialog to initiate searches 444 in the SearchableActivity --> 445 <activity android:name=".OtherActivity" ... > 446 <!-- enable the search dialog to send searches to SearchableActivity --> 447 <b><meta-data android:name="android.app.default_searchable" 448 android:value=".SearchableActivity" /></b> 449 </activity> 450 ... 451</application> 452</pre> 453 454<p>Because the {@code OtherActivity} now includes a <a 455href="{@docRoot}guide/topics/manifest/meta-data-element.html">{@code <meta-data>}</a> 456element to declare which searchable activity to use for searches, the activity has enabled the 457search dialog. 458While the user is in this activity, the {@link 459android.app.Activity#onSearchRequested onSearchRequested()} method activates the search dialog. 460When the user executes the search, the system starts {@code SearchableActivity} and delivers it 461the {@link android.content.Intent#ACTION_SEARCH} intent.</p> 462 463<p class="note"><strong>Note:</strong> The searchable activity itself provides the search dialog 464by default, so you don't need to add this declaration to {@code SearchableActivity}.</p> 465 466<p>If you want every activity in your application to provide the search dialog, insert the above <a 467href="{@docRoot}guide/topics/manifest/meta-data-element.html">{@code <meta-data>}</a> 468element as a child of the <a 469href="{@docRoot}guide/topics/manifest/application-element.html">{@code <application>}</a> 470element, instead of each <a 471href="{@docRoot}guide/topics/manifest/activity-element.html">{@code <activity>}</a>. This 472way, every activity inherits the value, provides the search dialog, and delivers searches to 473the same searchable activity. (If you have multiple searchable activities, you can override the 474default searchable activity by placing a different <a 475href="{@docRoot}guide/topics/manifest/meta-data-element.html">{@code <meta-data>}</a> 476declaration inside individual activities.)</p> 477 478<p>With the search dialog now enabled for your activities, your application is ready to perform 479searches.</p> 480 481 482<h3 id="InvokingTheSearchDialog">Invoking the search dialog</h3> 483 484<p>Although some devices provide a dedicated Search button, the behavior of the button may vary 485between devices and many devices do not provide a Search button at all. So when using the search 486dialog, you <strong>must provide a search button in your UI</strong> that activates the search 487dialog by calling {@link android.app.Activity#onSearchRequested()}.</p> 488 489<p>For instance, you should add a Search button in your <a 490href="{@docRoot}guide/topics/ui/menus.html#options-menu">Options Menu</a> or UI 491layout that calls {@link android.app.Activity#onSearchRequested()}. For consistency with 492the Android system and other apps, you should label your button with the Android Search icon that's 493available from the <a href="{@docRoot}design/downloads/index.html#action-bar-icon-pack">Action Bar 494Icon Pack</a>.</p> 495 496<p class="note"><strong>Note:</strong> If your app uses the <a 497href="{@docRoot}guide/topics/ui/actionbar.html">action bar</a>, then you should not use 498the search dialog for your search interface. Instead, use the <a href="#UsingSearchWidget">search 499widget</a> as a collapsible view in the action bar.</p> 500 501<p>You can also enable "type-to-search" functionality, which activates the search dialog when the 502user starts typing on the keyboard—the keystrokes are inserted into the search dialog. You can 503enable type-to-search in your activity by calling 504{@link android.app.Activity#setDefaultKeyMode(int) setDefaultKeyMode}({@link 505android.app.Activity#DEFAULT_KEYS_SEARCH_LOCAL}) during your activity's 506{@link android.app.Activity#onCreate(Bundle) onCreate()} method.</p> 507 508 509<h3 id="LifeCycle">The impact of the search dialog on your activity lifecycle</h3> 510 511<p>The search dialog is a {@link android.app.Dialog} that floats at the top of the 512screen. It does not cause any change in the activity stack, so when the search dialog appears, no 513lifecycle methods (such as {@link android.app.Activity#onPause()}) are called. Your activity just 514loses input focus, as input focus is given to the search dialog. 515</p> 516 517<p>If you want to be notified when the search dialog is activated, override the {@link 518android.app.Activity#onSearchRequested()} method. When the system calls this method, it is an 519indication that your activity has lost input focus to the search dialog, so you can do any 520work appropriate for the event (such as pause 521a game). Unless you are <a 522href="#SearchContextData">passing search context data</a> 523(discussed below), you should end the method by calling the super class implementation. For 524example:</p> 525 526<pre> 527@Override 528public boolean onSearchRequested() { 529 pauseSomeStuff(); 530 return super.onSearchRequested(); 531} 532</pre> 533 534<p>If the user cancels search by pressing the <em>Back</em> button, the search dialog closes and the 535activity 536regains input focus. You can register to be notified when the search dialog is 537closed with {@link android.app.SearchManager#setOnDismissListener(SearchManager.OnDismissListener) 538setOnDismissListener()} 539and/or {@link android.app.SearchManager#setOnCancelListener(SearchManager.OnCancelListener) 540setOnCancelListener()}. You 541should need to register only the {@link android.app.SearchManager.OnDismissListener 542OnDismissListener}, because it is called every time the search dialog closes. The {@link 543android.app.SearchManager.OnCancelListener OnCancelListener} only pertains to events in which the 544user explicitly exited the search dialog, so it is not called when a search is executed (in which 545case, the search dialog naturally disappears).</p> 546 547<p>If the current activity is not the searchable activity, then the normal activity lifecycle 548events are triggered once the user executes a search (the current activity receives {@link 549android.app.Activity#onPause()} and so forth, as 550described in the <a 551href="{@docRoot}guide/components/activities.html#Lifecycle">Activities</a> 552document). If, however, the current activity is the searchable activity, then one of two 553things happens:</p> 554 555<ol type="a"> 556 <li>By default, the searchable activity receives the {@link 557android.content.Intent#ACTION_SEARCH} intent with a call to {@link 558android.app.Activity#onCreate(Bundle) onCreate()} and a new instance of the 559activity is brought to the top of the activity stack. There are now two instances of your 560searchable activity in the activity stack (so pressing the <em>Back</em> button goes back to the 561previous 562instance of the searchable activity, rather than exiting the searchable activity).</li> 563 <li>If you set {@code android:launchMode} to <code>"singleTop"</code>, then the 564searchable activity receives the {@link android.content.Intent#ACTION_SEARCH} intent with a call 565to {@link android.app.Activity#onNewIntent(Intent)}, passing the new {@link 566android.content.Intent#ACTION_SEARCH} intent here. For example, here's how you might handle 567this case, in which the searchable activity's launch mode is <code>"singleTop"</code>: 568<pre> 569@Override 570public void onCreate(Bundle savedInstanceState) { 571 super.onCreate(savedInstanceState); 572 setContentView(R.layout.search); 573 handleIntent(getIntent()); 574} 575 576@Override 577protected void onNewIntent(Intent intent) { 578 setIntent(intent); 579 handleIntent(intent); 580} 581 582private void handleIntent(Intent intent) { 583 if (Intent.ACTION_SEARCH.equals(intent.getAction())) { 584 String query = intent.getStringExtra(SearchManager.QUERY); 585 doMySearch(query); 586 } 587} 588</pre> 589 590<p>Compared to the example code in the section about <a href="#PerformingSearch">Performing a 591Search</a>, all the code to handle the 592search intent is now in the {@code handleIntent()} method, so that both {@link 593android.app.Activity#onCreate(Bundle) 594onCreate()} and {@link android.app.Activity#onNewIntent(Intent) onNewIntent()} can execute it.</p> 595 596<p>When the system calls {@link android.app.Activity#onNewIntent(Intent)}, the activity has 597not been restarted, so the {@link android.app.Activity#getIntent()} method 598returns the same intent that was received with {@link 599android.app.Activity#onCreate(Bundle) onCreate()}. This is why you should call {@link 600android.app.Activity#setIntent(Intent)} inside {@link 601android.app.Activity#onNewIntent(Intent)} (so that the intent saved by the activity is updated in 602case you call {@link android.app.Activity#getIntent()} in the future).</p> 603 604</li> 605</ol> 606 607<p>The second scenario using <code>"singleTop"</code> launch mode is usually ideal, because chances 608are good that once a search is done, the user will perform additional searches and it's a bad 609experience if your application creates multiple instances of the searchable activity. So, we 610recommend that you set your searchable activity to <code>"singleTop"</code> launch mode in the 611application manifest. For example:</p> 612 613<pre> 614<activity android:name=".SearchableActivity" 615 <b>android:launchMode="singleTop"</b> > 616 <intent-filter> 617 <action android:name="android.intent.action.SEARCH" /> 618 </intent-filter> 619 <meta-data android:name="android.app.searchable" 620 android:resource="@xml/searchable"/> 621 </activity> 622</pre> 623 624 625 626<h3 id="SearchContextData">Passing search context data</h3> 627 628<p>In some cases, you can make necessary refinements to the search query inside the searchable 629activity, for every search made. However, if you want to refine your search criteria based on the 630activity from which the user is performing a search, you can provide additional data in the intent 631that the system sends to your searchable activity. You can pass the additional data in the {@link 632android.app.SearchManager#APP_DATA} {@link android.os.Bundle}, which is included in the {@link 633android.content.Intent#ACTION_SEARCH} intent.</p> 634 635<p>To pass this kind of data to your searchable activity, override the {@link 636android.app.Activity#onSearchRequested()} method for the activity from which the user can perform a 637search, create a {@link android.os.Bundle} with the additional data, and call {@link 638android.app.Activity#startSearch startSearch()} to activate the search dialog. 639For example:</p> 640 641<pre> 642@Override 643public boolean onSearchRequested() { 644 Bundle appData = new Bundle(); 645 appData.putBoolean(SearchableActivity.JARGON, true); 646 startSearch(null, false, appData, false); 647 return true; 648 } 649</pre> 650 651<p>Returning "true" indicates that you have successfully handled this callback event and 652called {@link android.app.Activity#startSearch startSearch()} to activate 653the search dialog. Once the user submits a query, it's delivered to your 654searchable activity along with the data you've added. You can extract the extra data from the {@link 655android.app.SearchManager#APP_DATA} {@link android.os.Bundle} to refine the search. For example:</p> 656 657<pre> 658Bundle appData = getIntent().getBundleExtra(SearchManager.APP_DATA); 659if (appData != null) { 660 boolean jargon = appData.getBoolean(SearchableActivity.JARGON); 661} 662</pre> 663 664<p class="caution"><strong>Caution:</strong> Never call the {@link 665android.app.Activity#startSearch(String,boolean,Bundle,boolean) startSearch()} method from outside 666the {@link android.app.Activity#onSearchRequested()} callback method. To activate the search dialog 667in your activity, always call {@link android.app.Activity#onSearchRequested()}. Otherwise, {@link 668android.app.Activity#onSearchRequested()} is not called and customizations (such as the addition of 669{@code appData} in the above example) are missed.</p> 670 671 672 673<h2 id="UsingSearchWidget">Using the Search Widget</h2> 674 675<div class="figure" style="width:429px;margin:0"> 676 <img src="{@docRoot}images/ui/actionbar-actionview.png" alt="" /> 677 <p class="img-caption"><strong>Figure 2.</strong> The {@link 678android.widget.SearchView} widget as an "action view" in the Action Bar.</p> 679</div> 680 681<p>The {@link android.widget.SearchView} widget is available in Android 3.0 and higher. If 682you're developing your application for Android 3.0 and have decided to use the search widget, we 683recommend that you insert the search widget as an <a 684href="{@docRoot}guide/topics/ui/actionbar.html#ActionView">action view in the Action Bar</a>, 685instead of using the search dialog (and instead of placing the search widget in your activity 686layout). For example, figure 2 shows the search widget in the Action Bar.</p> 687 688<p>The search widget provides the same functionality as the search dialog. It starts the appropriate 689activity when the user executes a search, and it can provide search suggestions and perform voice 690search.</p> 691 692<p class="note"><strong>Note:</strong> When you use the search widget as an action view, you 693still might need to support using the search dialog, for cases in which the search widget does 694not fit in the Action Bar. See the following section about <a href="#UsingBoth">Using both 695the widget and the dialog</a>.</p> 696 697 698<h3 id="ConfiguringWidget">Configuring the search widget</h3> 699 700<p>After you've created a <a href="#SearchableConfiguration">searchable configuration</a> and a <a 701href="#SearchableActivity">searchable activity</a>, as discussed above, you need to enable assisted 702search for each {@link android.widget.SearchView}. You can do so by calling {@link 703android.widget.SearchView#setSearchableInfo setSearchableInfo()} and passing it the {@link 704android.app.SearchableInfo} object that represents your searchable configuration.</p> 705 706<p>You can get a reference to the {@link android.app.SearchableInfo} by calling {@link 707android.app.SearchManager#getSearchableInfo getSearchableInfo()} on {@link 708android.app.SearchManager}.</p> 709 710<p>For example, if you're using a {@link android.widget.SearchView} as an action view in the <a 711href="{@docRoot}guide/topics/ui/actionbar.html">Action Bar</a>, you should enable the widget 712during the {@link android.app.Activity#onCreateOptionsMenu onCreateOptionsMenu()} callback:</p> 713 714<pre> 715@Override 716public boolean onCreateOptionsMenu(Menu menu) { 717 // Inflate the options menu from XML 718 MenuInflater inflater = getMenuInflater(); 719 inflater.inflate(R.menu.options_menu, menu); 720 721 // Get the SearchView and set the searchable configuration 722 SearchManager searchManager = (SearchManager) {@link android.app.Activity#getSystemService getSystemService}(Context.SEARCH_SERVICE); 723 SearchView searchView = (SearchView) menu.findItem(R.id.menu_search).getActionView(); 724 // Assumes current activity is the searchable activity 725 searchView.setSearchableInfo(searchManager.getSearchableInfo({@link android.app.Activity#getComponentName()})); 726 searchView.setIconifiedByDefault(false); // Do not iconify the widget; expand it by default 727 728 return true; 729} 730</pre> 731 732<p>That's all you need. The search widget is now configured and the system will deliver search 733queries to your searchable activity. You can also enable <a href="#SearchSuggestions">search 734suggestions</a> for the search widget.</p> 735 736<p class="note"><strong>Note:</strong> If you want to handle all user input yourself, you can do so 737with some callback methods and event listeners. For more information, see the reference 738documentation for {@link android.widget.SearchView} and its nested interfaces for the 739appropriate event listeners.</p> 740 741<p>For more information about action views in the Action Bar, read the <a 742href="{@docRoot}guide/topics/ui/actionbar.html#ActionView">Action Bar</a> developer guide (which 743includes sample code for adding a search widget as an action view).</p> 744 745 746<h3 id="WidgetFeatures">Other search widget features</h3> 747 748<p>The {@link android.widget.SearchView} widget allows for a few additional features you might 749want:</p> 750 751<dl> 752 <dt>A submit button</dt> 753 <dd>By default, there's no button to submit a search query, so the user must press the 754"Return" key on the keyboard to initiate a search. You can add a "submit" button by calling 755{@link android.widget.SearchView#setSubmitButtonEnabled setSubmitButtonEnabled(true)}.</dd> 756 <dt>Query refinement for search suggestions</dt> 757 <dd>When you've enabled search suggestions, you usually expect users to simply select a 758suggestion, but they might also want to refine the suggested search query. You can add a button 759alongside each suggestion that inserts the suggestion in the search box for refinement by the 760user, by calling {@link android.widget.SearchView#setQueryRefinementEnabled 761setQueryRefinementEnabled(true)}.</dd> 762 <dt>The ability to toggle the search box visibility</dt> 763 <dd>By default, the search widget is "iconified," meaning that it is represented only by a 764search icon (a magnifying glass), and expands to show the search box when the user touches it. 765As shown above, you can show the search box by default, by calling {@link 766android.widget.SearchView#setIconifiedByDefault setIconifiedByDefault(false)}. You can also 767toggle the search widget appearance by calling {@link android.widget.SearchView#setIconified 768setIconified()}.</dd> 769</dl> 770 771<p>There are several other APIs in the {@link android.widget.SearchView} class that allow you to 772customize the search widget. However, most of them are used only when you handle all 773user input yourself, instead of using the Android system to deliver search queries and display 774search suggestions.</p> 775 776 777<h3 id="UsingBoth">Using both the widget and the dialog</h3> 778 779<p>If you insert the search widget in the Action Bar as an <a 780href="{@docRoot}guide/topics/ui/actionbar.html#ActionView">action view</a>, and you enable it to 781appear in the Action Bar "if there is room" (by setting {@code 782android:showAsAction="ifRoom"}), then there is a chance that the search widget will not appear 783as an action view, but the menu item will appear in the overflow menu. For example, when your 784application runs on a smaller screen, there might not be enough room in the Action Bar to display 785the search widget along with other action items or navigation elements, so the menu item will 786instead appear in the overflow menu. When placed in the overflow menu, the item works like an 787ordinary menu item and does not display the action view (the search widget).</p> 788 789<p>To handle this situation, the menu item to which you've attached the search widget should 790activate the search dialog when the user selects it from the overflow menu. In order for it to do 791so, you must implement {@link android.app.Activity#onOptionsItemSelected onOptionsItemSelected()} to 792handle the "Search" menu item and open the search dialog by calling {@link 793android.app.Activity#onSearchRequested onSearchRequested()}.</p> 794 795<p>For more information about how items in the Action Bar work and how to handle this situation, see 796the <a href="{@docRoot}guide/topics/ui/actionbar.html">Action 797Bar</a> developer guide.</p> 798 799<p>Also see the <a 800href="{@docRoot}resources/samples/SearchableDictionary/src/com/example/android/searchabledict/SearchableDictionary.html" 801>Searchable Dictionary</a> for an example implementation using 802both the dialog and the widget.</p> 803 804 805 806<h2 id="VoiceSearch">Adding Voice Search</h2> 807 808<p>You can add voice search functionality to your search dialog or widget by adding the {@code 809android:voiceSearchMode} attribute to your searchable configuration. This adds a voice search 810button that launches a voice prompt. When the user 811has finished speaking, the transcribed search query is sent to your searchable 812activity.</p> 813 814<p>For example:</p> 815 816<pre> 817<?xml version="1.0" encoding="utf-8"?> 818<searchable xmlns:android="http://schemas.android.com/apk/res/android" 819 android:label="@string/search_label" 820 android:hint="@string/search_hint" 821 <b>android:voiceSearchMode="showVoiceSearchButton|launchRecognizer"</b> > 822</searchable> 823</pre> 824 825<p>The value {@code showVoiceSearchButton} is required to enable voice 826search, while the second value, {@code launchRecognizer}, specifies that the voice search button 827should launch a recognizer that returns the transcribed text to the searchable activity.</p> 828 829<p>You can provide additional attributes to specify the voice search behavior, such 830as the language to be expected and the maximum number of results to return. See the <a 831href="searchable-config.html">Searchable Configuration</a> reference for more information about the 832available attributes.</p> 833 834<p class="note"><strong>Note:</strong> Carefully consider whether voice search is appropriate for 835your application. All searches performed with the voice search button are immediately sent to 836your searchable activity without a chance for the user to review the transcribed query. Sufficiently 837test the voice recognition and ensure that it understands the types of queries that 838the user might submit inside your application.</p> 839 840 841 842<h2 id="SearchSuggestions">Adding Search Suggestions</h2> 843 844<div class="figure" style="width:250px;margin:0"> 845<img src="{@docRoot}images/search/search-suggest-custom.png" alt="" height="417" /> 846<p class="img-caption"><strong>Figure 3.</strong> Screenshot of a search dialog with custom 847search suggestions.</p> 848</div> 849 850<p>Both the search dialog and the search widget can provide search suggestions as the user 851types, with assistance from the Android system. The system manages the list of suggestions and 852handles the event when the user selects a suggestion.</p> 853 854<p>You can provide two kinds of search suggestions:</p> 855 856<dl> 857 <dt>Recent query search suggestions</dt> 858 <dd>These suggestions are simply words that the user previously used as search queries in 859your application. 860 <p>See <a href="adding-recent-query-suggestions.html">Adding Recent Query 861Suggestions</a>.</p></dd> 862 <dt>Custom search suggestions</dt> 863 <dd>These are search suggestions that you provide from your own data source, to help users 864immediately select the correct spelling or item they are searching for. Figure 3 shows an 865example of custom suggestions for a dictionary application—the user can select a suggestion 866to instantly go to the definition. 867 <p>See <a href="adding-custom-suggestions.html">Adding Custom 868Suggestions</a></p></dd> 869</dl> 870 871