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