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