search-dialog.jd revision 911711fd31c29fa3a0fad27d98071f7295fc5c00
1page.title=Creating a Search Interface
2parent.title=Search
3parent.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
47Dictionary</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
57Icon 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
64the user interface with either a search dialog that appears at the top of the activity window or a
65search widget that you can insert in your layout. Both the search dialog and the widget can deliver
66the user's search query to a specific activity in your application. This way, the user can initiate
67a search from any activity where the search dialog or widget is available, and the system starts the
68appropriate 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
79that's assisted by the Android system to deliver search queries, using either the
80search 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
91search dialog or the search widget. Both provide the same search features, but in slightly different
92ways:</p>
93
94<ul>
95  <li>The <strong>search dialog</strong> is a UI component that's controlled by the Android system.
96When activated by the user, the search dialog appears at the top of the activity, as shown in figure
971.
98    <p>The Android system controls all events in the search dialog. When the user
99submits a query, the system delivers the query to the activity that you specify to
100handle 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
103you can place anywhere in your layout. By default, the search widget behaves like a standard {@link
104android.widget.EditText} widget and doesn't do anything, but you can configure it so that the
105Android system handles all input events, delivers queries to the appropriate activity, and provides
106search suggestions (just like the search dialog). However, the search widget is available only in
107Android 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
110search widget yourself, using various callback methods and listeners. This document, however,
111focuses on how to integrate the search widget with the system for an assisted search
112implementation. 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
118that you've declared to handle searches (the "searchable activity") and delivers it the intent. To
119set 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
124for 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
127data, 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.
137Instead 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
146activity, 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
152certain UI aspects of the search dialog or widget and defines how features such as suggestions and
153voice search behave. This file is traditionally named {@code searchable.xml} and must be saved in
154the {@code res/xml/} project directory.</p>
155
156<p class="note"><strong>Note:</strong> The system uses this file to instantiate a {@link
157android.app.SearchableInfo} object, but you cannot create this object yourself at
158runtime&mdash;you must declare the searchable configuration in XML.</p>
159
160<p>The searchable configuration file must include the <a
161href="{@docRoot}guide/topics/search/searchable-config.html#searchable-element">{@code
162&lt;searchable&gt;}</a> element as the root node and specify one
163or more attributes. For example:</p>
164
165<pre>
166&lt;?xml version="1.0" encoding="utf-8"?>
167&lt;searchable xmlns:android="http://schemas.android.com/apk/res/android"
168    android:label="@string/app_label"
169    android:hint="@string/search_hint" >
170&lt;/searchable>
171</pre>
172
173<p>The {@code android:label} attribute is the only required attribute. It points to a string
174resource, which should be the application name. This label isn't actually visible to the
175user until you enable search suggestions for Quick Search Box. At that point, this label is visible
176in 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}
179attribute, which provides a hint string in the search box before users
180enters a query. The hint is important because it provides important clues to users about what
181they can search.</p>
182
183<p class="note"><strong>Tip:</strong> For consistency among other
184Android applications, you should format the string for {@code android:hint} as "Search
185&lt;content-or-product&gt;". For example, "Search songs and artists" or "Search
186YouTube".</p>
187
188<p>The <a
189href="{@docRoot}guide/topics/search/searchable-config.html#searchable-element">{@code
190&lt;searchable&gt;}</a> element accepts several other attributes. However, you don't need
191most attributes until you add features such as <a href="#SearchSuggestions">search suggestions</a>
192and <a href="#VoiceSearch">voice search</a>. For detailed information about the searchable
193configuration file, see the <a
194href="{@docRoot}guide/topics/search/searchable-config.html">Searchable Configuration</a> reference
195document.</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
202searches 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
205searchable activity and delivers it the search query in an {@link
206android.content.Intent} with the  {@link android.content.Intent#ACTION_SEARCH} action. Your
207searchable activity retrieves the query from the intent's {@link android.app.SearchManager#QUERY
208QUERY} 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,
211the system must know which activity is your searchable activity, so it can properly deliver the
212search 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
218searches and present results. You don't need to implement the search functionality yet&mdash;just
219create an activity that you can declare in the manifest. Inside the manifest's <a
220href="{@docRoot}guide/topics/manifest/activity-element.html">{@code &lt;activity&gt;}</a>
221element:</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&lt;intent-filter&gt;}</a>
226element.</li>
227  <li>Specify the searchable configuration to use, in a <a
228href="{@docRoot}guide/topics/manifest/meta-data-element.html">{@code &lt;meta-data&gt;}</a>
229element.</li>
230</ol>
231
232<p>For example:</p>
233
234<pre>
235&lt;application ... >
236    &lt;activity android:name=".SearchableActivity" >
237        &lt;intent-filter>
238            &lt;action android:name="android.intent.action.SEARCH" />
239        &lt;/intent-filter>
240        &lt;meta-data android:name="android.app.searchable"
241                   android:resource="@xml/searchable"/>
242    &lt;/activity>
243    ...
244&lt;/application>
245</pre>
246
247<p>The {@code &lt;meta-data&gt;} element must include the {@code android:name} attribute with a
248value of {@code "android.app.searchable"} and the {@code android:resource} attribute with a
249reference to the searchable configuration file (in this example, it
250refers to the {@code res/xml/searchable.xml} file).</p>
251
252<p class="note"><strong>Note:</strong> The <a
253href="{@docRoot}guide/topics/manifest/intent-filter-element.html">{@code
254&lt;intent-filter&gt;}</a> does not need a <a
255href="{@docRoot}guide/topics/manifest/category-element.html">{@code &lt;category&gt;}</a> with the
256{@code DEFAULT} value (which you usually see in <a
257href="{@docRoot}guide/topics/manifest/activity-element.html">{@code &lt;activity&gt;}</a> elements),
258because the system delivers the {@link android.content.Intent#ACTION_SEARCH} intent explicitly to
259your 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
266searchable 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
275you might want your searchable activity to extend {@link android.app.ListActivity}. It includes
276a default layout with a single {@link android.widget.ListView} and provides several
277convenience 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
283searchable activity and sends it a {@link android.content.Intent#ACTION_SEARCH} intent. This intent
284carries the search query in the
285{@link android.app.SearchManager#QUERY QUERY} string extra. You must check for
286this intent when the activity starts and extract the string. For example, here's how you can get the
287search query when your searchable activity starts:</p>
288
289<pre>
290&#64;Override
291public 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
305the {@link android.content.Intent#ACTION_SEARCH} intent. In this example, the query is
306retrieved and passed to a local {@code doMySearch()} method where the actual search operation
307is 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.
313You can store and search your data in many ways, but this guide does not show you how to store your
314data and search it. Storing and searching your data is something you should carefully consider in
315terms of your needs and your data format. However, here are some tips you might be able to
316apply:</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
321can produce results significantly faster. See <a href="http://sqlite.org/fts3.html">sqlite.org</a>
322for information about FTS3 and the {@link android.database.sqlite.SQLiteDatabase} class for
323information about SQLite on Android. Also look at the <a
324href="{@docRoot}resources/samples/SearchableDictionary/index.html">Searchable Dictionary</a> sample
325application 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
327inhibited by the user's data connection. You might want to display a spinning progress wheel until
328your search returns. See {@link android.net} for a reference of network APIs and <a
329href="{@docRoot}guide/topics/ui/dialogs.html#ProgressDialog">Creating a Progress Dialog</a>
330for 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}
339is applied to a {@link android.widget.ListView}, each piece of data is inserted as an individual
340view into the list. {@link
341android.widget.Adapter} is just an interface, so implementations such as {@link
342android.widget.CursorAdapter} (for binding data from a {@link android.database.Cursor}) are needed.
343If 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
345original version of the Searchable Dictionary, which creates a custom adapter to read data from
346a 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
351results to your searchable activity with an {@link android.widget.Adapter}. This way, you can easily
352present all the search results in a {@link android.widget.ListView}. If your data comes from a
353SQLite database query, you can apply your results to a {@link android.widget.ListView}
354using a {@link android.widget.CursorAdapter}. If your data comes in some other type of format, then
355you 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
361android.widget.ListView}, so you might want your searchable activity to extend {@link
362android.app.ListActivity}. You can then call {@link
363android.app.ListActivity#setListAdapter(ListAdapter) setListAdapter()}, passing it an {@link
364android.widget.Adapter} that is bound to your data. This injects all the
365search 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}
368documentation.</p>
369
370<p>Also see the <a
371href="{@docRoot}resources/samples/SearchableDictionary/index.html">Searchable Dictionary</a> sample
372for 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
385higher), because the {@link android.widget.SearchView} widget was introduced in Android 3.0. So,
386if you are developing your application for a version of Android lower than 3.0, the search widget is
387not 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
389your needs. In most cases, we recommend that you use the search widget as an "action view" in the
390Action Bar. However, it might not be an option for you to put the search
391widget in the Action Bar for some reason (perhaps there's not enough space or you don't use the
392Action Bar). So, you might instead want to put the search widget somewhere in your activity layout.
393And if all else fails, you can still use the search dialog if you prefer to keep the search box
394hidden. In fact, you might want to offer both the dialog and the widget in some cases. For more
395information 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
400icon on the left. The search dialog can provide search suggestions as the user types and, when
401the user executes a search, the system sends the search query to a
402searchable activity that performs the search. However, if you are developing
403your application for devices running Android 3.0, you should consider using the search widget
404instead (see the side box).</p>
405
406<p>The search dialog is always hidden by default, until the user activates it. Your application
407can activate the search dialog by calling {@link
408android.app.Activity#onSearchRequested onSearchRequested()}. However, this method doesn't work
409until 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
412receive search queries from the search dialog, in order to perform searches. For example, in the
413previous section about <a href="#SearchableActivity">Creating a Searchable Activity</a>, a
414searchable activity named {@code SearchableActivity} was created. If you want a separate activity,
415named {@code OtherActivity}, to show the search dialog and deliver searches to {@code
416SearchableActivity}, you must declare in the manifest that {@code SearchableActivity} is the
417searchable 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,
420add a <a href="{@docRoot}guide/topics/manifest/meta-data-element.html">{@code &lt;meta-data&gt;}</a>
421element inside the respective activity's <a
422href="{@docRoot}guide/topics/manifest/activity-element.html">{@code &lt;activity&gt;}</a> element.
423The <a href="{@docRoot}guide/topics/manifest/meta-data-element.html">{@code &lt;meta-data&gt;}</a>
424element must include the {@code android:value} attribute that specifies the searchable activity's
425class 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
429both a searchable activity, {@code SearchableActivity}, and another activity, {@code
430OtherActivity}, which uses {@code SearchableActivity} to perform searches executed from its
431search dialog:</p>
432
433<pre>
434&lt;application ... >
435    &lt;!-- this is the searchable activity; it performs searches --&gt;
436    &lt;activity android:name=".SearchableActivity" >
437        &lt;intent-filter>
438            &lt;action android:name="android.intent.action.SEARCH" />
439        &lt;/intent-filter>
440        &lt;meta-data android:name="android.app.searchable"
441                   android:resource="@xml/searchable"/>
442    &lt;/activity>
443
444    &lt;!-- this activity enables the search dialog to initiate searches
445         in the SearchableActivity --&gt;
446    &lt;activity android:name=".OtherActivity" ... >
447        &lt;!-- enable the search dialog to send searches to SearchableActivity -->
448        <b>&lt;meta-data android:name="android.app.default_searchable"
449                   android:value=".SearchableActivity" /&gt;</b>
450    &lt;/activity>
451    ...
452&lt;/application>
453</pre>
454
455<p>Because the {@code OtherActivity} now includes a <a
456href="{@docRoot}guide/topics/manifest/meta-data-element.html">{@code &lt;meta-data&gt;}</a>
457element to declare which searchable activity to use for searches, the activity has enabled the
458search dialog.
459While the user is in this activity, the {@link
460android.app.Activity#onSearchRequested onSearchRequested()} method activates the search dialog.
461When the user executes the search, the system starts {@code SearchableActivity} and delivers it
462the {@link android.content.Intent#ACTION_SEARCH} intent.</p>
463
464<p class="note"><strong>Note:</strong> The searchable activity itself provides the search dialog
465by 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
468href="{@docRoot}guide/topics/manifest/meta-data-element.html">{@code &lt;meta-data&gt;}</a>
469element as a child of the <a
470href="{@docRoot}guide/topics/manifest/application-element.html">{@code &lt;application&gt;}</a>
471element, instead of each <a
472href="{@docRoot}guide/topics/manifest/activity-element.html">{@code &lt;activity&gt;}</a>. This
473way, every activity inherits the value, provides the search dialog, and delivers searches to
474the same searchable activity. (If you have multiple searchable activities, you can override the
475default searchable activity by placing a different <a
476href="{@docRoot}guide/topics/manifest/meta-data-element.html">{@code &lt;meta-data&gt;}</a>
477declaration inside individual activities.)</p>
478
479<p>With the search dialog now enabled for your activities, your application is ready to perform
480searches.</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
486between devices and many devices do not provide a Search button at all. So when using the search
487dialog, you <strong>must provide a search button in your UI</strong> that activates the search
488dialog by calling {@link android.app.Activity#onSearchRequested()}.</p>
489
490<p>For instance, you should add a Search button in your <a
491href="{@docRoot}guide/topics/ui/menus.html#options-menu">Options Menu</a> or UI
492layout that calls {@link android.app.Activity#onSearchRequested()}. For consistency with
493the Android system and other apps, you should label your button with the Android Search icon that's
494available from the <a href="{@docRoot}design/downloads/index.html#action-bar-icon-pack">Action Bar
495Icon Pack</a>.</p>
496
497<p class="note"><strong>Note:</strong> If your app uses the <a
498href="{@docRoot}guide/topics/ui/actionbar.html">action bar</a>, then you should not use
499the search dialog for your search interface. Instead, use the <a href="#UsingSearchWidget">search
500widget</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
503user starts typing on the keyboard&mdash;the keystrokes are inserted into the search dialog. You can
504enable type-to-search in your activity by calling
505{@link android.app.Activity#setDefaultKeyMode(int) setDefaultKeyMode}({@link
506android.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
513screen. It does not cause any change in the activity stack, so when the search dialog appears, no
514lifecycle methods (such as {@link android.app.Activity#onPause()}) are called. Your activity just
515loses 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
519android.app.Activity#onSearchRequested()} method. When the system calls this method, it is an
520indication that your activity has lost input focus to the search dialog, so you can do any
521work appropriate for the event (such as pause
522a game). Unless you are <a
523href="#SearchContextData">passing search context data</a>
524(discussed below), you should end the method by calling the super class implementation. For
525example:</p>
526
527<pre>
528&#64;Override
529public 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
536activity
537regains input focus. You can register to be notified when the search dialog is
538closed with {@link android.app.SearchManager#setOnDismissListener(SearchManager.OnDismissListener)
539setOnDismissListener()}
540and/or {@link android.app.SearchManager#setOnCancelListener(SearchManager.OnCancelListener)
541setOnCancelListener()}. You
542should need to register only the {@link android.app.SearchManager.OnDismissListener
543OnDismissListener}, because it is called every time the search dialog closes. The {@link
544android.app.SearchManager.OnCancelListener OnCancelListener} only pertains to events in which the
545user explicitly exited the search dialog, so it is not called when a search is executed (in which
546case, the search dialog naturally disappears).</p>
547
548<p>If the current activity is not the searchable activity, then the normal activity lifecycle
549events are triggered once the user executes a search (the current activity receives {@link
550android.app.Activity#onPause()} and so forth, as
551described in the <a
552href="{@docRoot}guide/components/activities.html#Lifecycle">Activities</a>
553document). If, however, the current activity is the searchable activity, then one of two
554things happens:</p>
555
556<ol type="a">
557  <li>By default, the searchable activity receives the {@link
558android.content.Intent#ACTION_SEARCH} intent with a call to {@link
559android.app.Activity#onCreate(Bundle) onCreate()} and a new instance of the
560activity is brought to the top of the activity stack. There are now two instances of your
561searchable activity in the activity stack (so pressing the <em>Back</em> button goes back to the
562previous
563instance 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
565searchable activity receives the {@link android.content.Intent#ACTION_SEARCH} intent with a call
566to {@link android.app.Activity#onNewIntent(Intent)}, passing the new {@link
567android.content.Intent#ACTION_SEARCH} intent here. For example, here's how you might handle
568this case, in which the searchable activity's launch mode is <code>"singleTop"</code>:
569<pre>
570&#64;Override
571public void onCreate(Bundle savedInstanceState) {
572    super.onCreate(savedInstanceState);
573    setContentView(R.layout.search);
574    handleIntent(getIntent());
575}
576
577&#64;Override
578protected void onNewIntent(Intent intent) {
579    setIntent(intent);
580    handleIntent(intent);
581}
582
583private 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
592Search</a>, all the code to handle the
593search intent is now in the {@code handleIntent()} method, so that both {@link
594android.app.Activity#onCreate(Bundle)
595onCreate()} 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
598not been restarted, so the {@link android.app.Activity#getIntent()} method
599returns the same intent that was received with {@link
600android.app.Activity#onCreate(Bundle) onCreate()}. This is why you should call {@link
601android.app.Activity#setIntent(Intent)} inside {@link
602android.app.Activity#onNewIntent(Intent)} (so that the intent saved by the activity is updated in
603case 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
609are good that once a search is done, the user will perform additional searches and it's a bad
610experience if your application creates multiple instances of the searchable activity. So, we
611recommend that you set your searchable activity to <code>"singleTop"</code> launch mode in the
612application manifest. For example:</p>
613
614<pre>
615&lt;activity android:name=".SearchableActivity"
616          <b>android:launchMode="singleTop"</b> >
617    &lt;intent-filter>
618        &lt;action android:name="android.intent.action.SEARCH" />
619    &lt;/intent-filter>
620    &lt;meta-data android:name="android.app.searchable"
621                      android:resource="@xml/searchable"/>
622  &lt;/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
630activity, for every search made. However, if you want to refine your search criteria based on the
631activity from which the user is performing a search, you can provide additional data in the intent
632that the system sends to your searchable activity. You can pass the additional data in the {@link
633android.app.SearchManager#APP_DATA} {@link android.os.Bundle}, which is included in the {@link
634android.content.Intent#ACTION_SEARCH} intent.</p>
635
636<p>To pass this kind of data to your searchable activity, override the {@link
637android.app.Activity#onSearchRequested()} method for the activity from which the user can perform a
638search, create a {@link android.os.Bundle} with the additional data, and call {@link
639android.app.Activity#startSearch startSearch()} to activate the search dialog.
640For example:</p>
641
642<pre>
643&#64;Override
644public 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
653called {@link android.app.Activity#startSearch startSearch()} to activate
654the search dialog. Once the user submits a query, it's delivered to your
655searchable activity along with the data you've added. You can extract the extra data from the {@link
656android.app.SearchManager#APP_DATA} {@link android.os.Bundle} to refine the search. For example:</p>
657
658<pre>
659Bundle appData = getIntent().getBundleExtra(SearchManager.APP_DATA);
660if (appData != null) {
661    boolean jargon = appData.getBoolean(SearchableActivity.JARGON);
662}
663</pre>
664
665<p class="caution"><strong>Caution:</strong> Never call the {@link
666android.app.Activity#startSearch(String,boolean,Bundle,boolean) startSearch()} method from outside
667the {@link android.app.Activity#onSearchRequested()} callback method. To activate the search dialog
668in your activity, always call {@link android.app.Activity#onSearchRequested()}. Otherwise, {@link
669android.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
679android.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
683you're developing your application for Android 3.0 and have decided to use the search widget, we
684recommend that you insert the search widget as an <a
685href="{@docRoot}guide/topics/ui/actionbar.html#ActionView">action view in the Action Bar</a>,
686instead of using the search dialog (and instead of placing the search widget in your activity
687layout). 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
690activity when the user executes a search, and it can provide search suggestions and perform voice
691search.</p>
692
693<p class="note"><strong>Note:</strong> When you use the search widget as an action view, you
694still might need to support using the search dialog, for cases in which the search widget does
695not fit in the Action Bar. See the following section about <a href="#UsingBoth">Using both
696the 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
702href="#SearchableActivity">searchable activity</a>, as discussed above, you need to enable assisted
703search for each {@link android.widget.SearchView}. You can do so by calling {@link
704android.widget.SearchView#setSearchableInfo setSearchableInfo()} and passing it the {@link
705android.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
708android.app.SearchManager#getSearchableInfo getSearchableInfo()} on {@link
709android.app.SearchManager}.</p>
710
711<p>For example, if you're using a {@link android.widget.SearchView} as an action view in the <a
712href="{@docRoot}guide/topics/ui/actionbar.html">Action Bar</a>, you should enable the widget
713during the {@link android.app.Activity#onCreateOptionsMenu onCreateOptionsMenu()} callback:</p>
714
715<pre>
716&#64;Override
717public 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
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&lt;?xml version="1.0" encoding="utf-8"?>
818&lt;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&lt;/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&mdash;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