page.title=Creating a Search Interface page.tags=searchview @jd:body <div id="qv-wrapper"> <div id="qv"> <h2>In this document</h2> <ol> <li><a href="#TheBasics">The Basics</a></li> <li><a href="#SearchableConfiguration">Creating a Searchable Configuration</a></li> <li><a href="#SearchableActivity">Creating a Searchable Activity</a> <ol> <li><a href="#DeclaringSearchableActivity">Declaring a searchable activity</a></li> <li><a href="#PerformingSearch">Performing a search</a></li> </ol> </li> <li><a href="#SearchDialog">Using the Search Dialog</a> <ol> <li><a href="#InvokingTheSearchDialog">Invoking the search dialog</a></li> <li><a href="#LifeCycle">The impact of the search dialog on your activity lifecycle</a></li> <li><a href="#SearchContextData">Passing search context data</a></li> </ol> </li> <li><a href="#UsingSearchWidget">Using the Search Widget</a> <ol> <li><a href="#ConfiguringWidget">Configuring the search widget</a></li> <li><a href="#WidgetFeatures">Other search widget features</a></li> <li><a href="#UsingBoth">Using both the widget and the dialog</a></li> </ol> </li> <li><a href="#VoiceSearch">Adding Voice Search</a></li> <li><a href="#SearchSuggestions">Adding Search Suggestions</a></li> </ol> <h2>Key classes</h2> <ol> <li>{@link android.app.SearchManager}</li> <li>{@link android.widget.SearchView}</li> </ol> <h2>Related samples</h2> <ol> <li><a href="{@docRoot}resources/samples/SearchableDictionary/index.html">Searchable Dictionary</a></li> <li><a href="{@docRoot}resources/samples/ApiDemos/src/com/example/android/apis/view/SearchViewActionBar.html">SearchView in the Action Bar</a></li> <li><a href="{@docRoot}resources/samples/ApiDemos/src/com/example/android/apis/view/SearchViewFilterMode.html">SearchView filter mode</a></li> </ol> <h2>Downloads</h2> <ol> <li><a href="{@docRoot}design/downloads/index.html#action-bar-icon-pack">Action Bar Icon Pack</a></li> </ol> </div> </div> <p>When you're ready to add search functionality to your application, Android helps you implement the user interface with either a search dialog that appears at the top of the activity window or a search widget that you can insert in your layout. Both the search dialog and the widget can deliver the user's search query to a specific activity in your application. This way, the user can initiate a search from any activity where the search dialog or widget is available, and the system starts the appropriate activity to perform the search and present results.</p> <p>Other features available for the search dialog and widget include:</p> <ul> <li>Voice search</li> <li>Search suggestions based on recent queries</li> <li>Search suggestions that match actual results in your application data</li> </ul> <p>This guide shows you how to set up your application to provide a search interface that's assisted by the Android system to deliver search queries, using either the search dialog or the search widget.</p> <h2 id="TheBasics">The Basics</h2> <div class="figure" style="width:250px"> <img src="{@docRoot}images/search/search-ui.png" alt="" height="417" /> <p class="img-caption"><strong>Figure 1.</strong> Screenshot of an application's search dialog.</p> </div> <p>Before you begin, you should decide whether you'll implement your search interface using the search dialog or the search widget. Both provide the same search features, but in slightly different ways:</p> <ul> <li>The <strong>search dialog</strong> is a UI component that's controlled by the Android system. When activated by the user, the search dialog appears at the top of the activity, as shown in figure 1. <p>The Android system controls all events in the search dialog. When the user submits a query, the system delivers the query to the activity that you specify to handle searches. The dialog can also provide search suggestions while the user types.</p></li> <li>The <strong>search widget</strong> is an instance of {@link android.widget.SearchView} that you can place anywhere in your layout. By default, the search widget behaves like a standard {@link android.widget.EditText} widget and doesn't do anything, but you can configure it so that the Android system handles all input events, delivers queries to the appropriate activity, and provides search suggestions (just like the search dialog). <p class="note"><strong>Note:</strong> If you want, you can handle all user input into the search widget yourself, using various callback methods and listeners. This document, however, focuses on how to integrate the search widget with the system for an assisted search implementation. If you want to handle all user input yourself, read the reference documentation for {@link android.widget.SearchView} and its nested interfaces. </p></li> </ul> <p>When the user executes a search from the search dialog or a search widget, the system creates an {@link android.content.Intent} and stores the user query in it. The system then starts the activity that you've declared to handle searches (the "searchable activity") and delivers it the intent. To set up your application for this kind of assisted search, you need the following:</p> <ul> <li>A searchable configuration <p>An XML file that configures some settings for the search dialog or widget. It includes settings for features such as voice search, search suggestion, and hint text for the search box.</p></li> <li>A searchable activity <p>The {@link android.app.Activity} that receives the search query, searches your data, and displays the search results.</p></li> <li>A search interface, provided by either: <ul> <li>The search dialog <p>By default, the search dialog is hidden, but appears at the top of the screen when you call {@link android.app.Activity#onSearchRequested()} (when the user presses your Search button).</p> </li> <li>Or, a {@link android.widget.SearchView} widget <p>Using the search widget allows you to put the search box anywhere in your activity. Instead of putting it in your activity layout, you should usually use {@link android.widget.SearchView} as an action view in the app bar.</p> </li> </ul> </li> </ul> <p>The rest of this document shows you how to create the searchable configuration, searchable activity, and implement a search interface with either the search dialog or search widget.</p> <h2 id="SearchableConfiguration">Creating a Searchable Configuration</h2> <p>The first thing you need is an XML file called the searchable configuration. It configures certain UI aspects of the search dialog or widget and defines how features such as suggestions and voice search behave. This file is traditionally named {@code searchable.xml} and must be saved in the {@code res/xml/} project directory.</p> <p class="note"><strong>Note:</strong> The system uses this file to instantiate a {@link android.app.SearchableInfo} object, but you cannot create this object yourself at runtime—you must declare the searchable configuration in XML.</p> <p>The searchable configuration file must include the <a href="{@docRoot}guide/topics/search/searchable-config.html#searchable-element">{@code <searchable>}</a> element as the root node and specify one or more attributes. For example:</p> <pre> <?xml version="1.0" encoding="utf-8"?> <searchable xmlns:android="http://schemas.android.com/apk/res/android" android:label="@string/app_label" android:hint="@string/search_hint" > </searchable> </pre> <p>The {@code android:label} attribute is the only required attribute. It points to a string resource, which should be the application name. This label isn't actually visible to the user until you enable search suggestions for Quick Search Box. At that point, this label is visible in the list of Searchable items in the system Settings.</p> <p>Though it's not required, we recommend that you always include the {@code android:hint} attribute, which provides a hint string in the search box before users enters a query. The hint is important because it provides important clues to users about what they can search.</p> <p class="note"><strong>Tip:</strong> For consistency among other Android applications, you should format the string for {@code android:hint} as "Search <content-or-product>". For example, "Search songs and artists" or "Search YouTube".</p> <p>The <a href="{@docRoot}guide/topics/search/searchable-config.html#searchable-element">{@code <searchable>}</a> element accepts several other attributes. However, you don't need most attributes until you add features such as <a href="#SearchSuggestions">search suggestions</a> and <a href="#VoiceSearch">voice search</a>. For detailed information about the searchable configuration file, see the <a href="{@docRoot}guide/topics/search/searchable-config.html">Searchable Configuration</a> reference document.</p> <h2 id="SearchableActivity">Creating a Searchable Activity</h2> <p>A searchable activity is the {@link android.app.Activity} in your application that performs searches based on a query string and presents the search results.</p> <p>When the user executes a search in the search dialog or widget, the system starts your searchable activity and delivers it the search query in an {@link android.content.Intent} with the {@link android.content.Intent#ACTION_SEARCH} action. Your searchable activity retrieves the query from the intent's {@link android.app.SearchManager#QUERY QUERY} extra, then searches your data and presents the results.</p> <p>Because you may include the search dialog or widget in any other activity in your application, the system must know which activity is your searchable activity, so it can properly deliver the search query. So, you must first declare your searchable activity in the Android manifest file.</p> <h3 id="DeclaringSearchableActivity">Declaring a searchable activity</h3> <p>If you don't have one already, create an {@link android.app.Activity} that will perform searches and present results. You don't need to implement the search functionality yet—just create an activity that you can declare in the manifest. Inside the manifest's <a href="{@docRoot}guide/topics/manifest/activity-element.html">{@code <activity>}</a> element:</p> <ol> <li>Declare the activity to accept the {@link android.content.Intent#ACTION_SEARCH} intent, in an <a href="{@docRoot}guide/topics/manifest/intent-filter-element.html">{@code <intent-filter>}</a> element.</li> <li>Specify the searchable configuration to use, in a <a href="{@docRoot}guide/topics/manifest/meta-data-element.html">{@code <meta-data>}</a> element.</li> </ol> <p>For example:</p> <pre> <application ... > <activity android:name=".SearchableActivity" > <intent-filter> <action android:name="android.intent.action.SEARCH" /> </intent-filter> <meta-data android:name="android.app.searchable" android:resource="@xml/searchable"/> </activity> ... </application> </pre> <p>The {@code <meta-data>} element must include the {@code android:name} attribute with a value of {@code "android.app.searchable"} and the {@code android:resource} attribute with a reference to the searchable configuration file (in this example, it refers to the {@code res/xml/searchable.xml} file).</p> <p class="note"><strong>Note:</strong> The <a href="{@docRoot}guide/topics/manifest/intent-filter-element.html">{@code <intent-filter>}</a> does not need a <a href="{@docRoot}guide/topics/manifest/category-element.html">{@code <category>}</a> with the {@code DEFAULT} value (which you usually see in <a href="{@docRoot}guide/topics/manifest/activity-element.html">{@code <activity>}</a> elements), because the system delivers the {@link android.content.Intent#ACTION_SEARCH} intent explicitly to your searchable activity, using its component name.</p> <h3 id="PerformingSearch">Performing a search</h3> <p>Once you have declared your searchable activity in the manifest, performing a search in your searchable activity involves three steps:</p> <ol> <li><a href="#ReceivingTheQuery">Receiving the query</a></li> <li><a href="#SearchingYourData">Searching your data</a></li> <li><a href="#PresentingTheResults">Presenting the results</a></li> </ol> <p>Traditionally, your search results should be presented in a {@link android.widget.ListView}, so you might want your searchable activity to extend {@link android.app.ListActivity}. It includes a default layout with a single {@link android.widget.ListView} and provides several convenience methods for working with the {@link android.widget.ListView}.</p> <h4 id="ReceivingTheQuery">Receiving the query</h4> <p>When a user executes a search from the search dialog or widget, the system starts your searchable activity and sends it a {@link android.content.Intent#ACTION_SEARCH} intent. This intent carries the search query in the {@link android.app.SearchManager#QUERY QUERY} string extra. You must check for this intent when the activity starts and extract the string. For example, here's how you can get the search query when your searchable activity starts:</p> <pre> @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.search); // Get the intent, verify the action and get the query Intent intent = getIntent(); if (Intent.ACTION_SEARCH.equals(intent.getAction())) { String query = intent.getStringExtra(SearchManager.QUERY); doMySearch(query); } } </pre> <p>The {@link android.app.SearchManager#QUERY QUERY} string is always included with the {@link android.content.Intent#ACTION_SEARCH} intent. In this example, the query is retrieved and passed to a local {@code doMySearch()} method where the actual search operation is done.</p> <h4 id="SearchingYourData">Searching your data</h4> <p>The process of storing and searching your data is unique to your application. You can store and search your data in many ways, but this guide does not show you how to store your data and search it. Storing and searching your data is something you should carefully consider in terms of your needs and your data format. However, here are some tips you might be able to apply:</p> <ul> <li>If your data is stored in a SQLite database on the device, performing a full-text search (using FTS3, rather than a {@code LIKE} query) can provide a more robust search across text data and can produce results significantly faster. See <a href="http://sqlite.org/fts3.html">sqlite.org</a> for information about FTS3 and the {@link android.database.sqlite.SQLiteDatabase} class for information about SQLite on Android. Also look at the <a href="{@docRoot}resources/samples/SearchableDictionary/index.html">Searchable Dictionary</a> sample application to see a complete SQLite implementation that performs searches with FTS3.</li> <li>If your data is stored online, then the perceived search performance might be inhibited by the user's data connection. You might want to display a spinning progress wheel until your search returns. See {@link android.net} for a reference of network APIs and <a href="{@docRoot}guide/topics/ui/dialogs.html#ProgressDialog">Creating a Progress Dialog</a> for information about how to display a progress wheel.</li> </ul> <div class="sidebox-wrapper"> <div class="sidebox"> <h2>About Adapters</h2> <p>An {@link android.widget.Adapter} binds each item from a set of data into a {@link android.view.View} object. When the {@link android.widget.Adapter} is applied to a {@link android.widget.ListView}, each piece of data is inserted as an individual view into the list. {@link android.widget.Adapter} is just an interface, so implementations such as {@link android.widget.CursorAdapter} (for binding data from a {@link android.database.Cursor}) are needed. If none of the existing implementations work for your data, then you can implement your own from {@link android.widget.BaseAdapter}. Install the SDK Samples package for API Level 4 to see the original version of the Searchable Dictionary, which creates a custom adapter to read data from a file.</p> </div> </div> <p>Regardless of where your data lives and how you search it, we recommend that you return search results to your searchable activity with an {@link android.widget.Adapter}. This way, you can easily present all the search results in a {@link android.widget.ListView}. If your data comes from a SQLite database query, you can apply your results to a {@link android.widget.ListView} using a {@link android.widget.CursorAdapter}. If your data comes in some other type of format, then you can create an extension of {@link android.widget.BaseAdapter}.</p> <h4 id="PresentingTheResults">Presenting the results</h4> <p>As discussed above, the recommended UI for your search results is a {@link android.widget.ListView}, so you might want your searchable activity to extend {@link android.app.ListActivity}. You can then call {@link android.app.ListActivity#setListAdapter(ListAdapter) setListAdapter()}, passing it an {@link android.widget.Adapter} that is bound to your data. This injects all the search results into the activity {@link android.widget.ListView}.</p> <p>For more help presenting your results in a list, see the {@link android.app.ListActivity} documentation.</p> <p>Also see the <a href="{@docRoot}resources/samples/SearchableDictionary/index.html">Searchable Dictionary</a> sample for an a complete demonstration of how to search an SQLite database and use an {@link android.widget.Adapter} to provide results in a {@link android.widget.ListView}.</p> <h2 id="SearchDialog">Using the Search Dialog</h2> <p>The search dialog provides a floating search box at the top of the screen, with the application icon on the left. The search dialog can provide search suggestions as the user types and, when the user executes a search, the system sends the search query to a searchable activity that performs the search. However, if you are developing your application for devices running Android 3.0, you should consider using the search widget instead (see <a href="#UsingSearchWidget">Using the Search Widget</a> section).</p> <p>The search dialog is always hidden by default, until the user activates it. Your application can activate the search dialog by calling {@link android.app.Activity#onSearchRequested onSearchRequested()}. However, this method doesn't work until you enable the search dialog for the activity.</p> <p>To enable the search dialog, you must indicate to the system which searchable activity should receive search queries from the search dialog, in order to perform searches. For example, in the previous section about <a href="#SearchableActivity">Creating a Searchable Activity</a>, a searchable activity named {@code SearchableActivity} was created. If you want a separate activity, named {@code OtherActivity}, to show the search dialog and deliver searches to {@code SearchableActivity}, you must declare in the manifest that {@code SearchableActivity} is the searchable activity to use for the search dialog in {@code OtherActivity}.</p> <p>To declare the searchable activity for an activity's search dialog, add a <a href="{@docRoot}guide/topics/manifest/meta-data-element.html">{@code <meta-data>}</a> element inside the respective activity's <a href="{@docRoot}guide/topics/manifest/activity-element.html">{@code <activity>}</a> element. The <a href="{@docRoot}guide/topics/manifest/meta-data-element.html">{@code <meta-data>}</a> element must include the {@code android:value} attribute that specifies the searchable activity's class name and the {@code android:name} attribute with a value of {@code "android.app.default_searchable"}.</p> <p>For example, here is the declaration for both a searchable activity, {@code SearchableActivity}, and another activity, {@code OtherActivity}, which uses {@code SearchableActivity} to perform searches executed from its search dialog:</p> <pre> <application ... > <!-- this is the searchable activity; it performs searches --> <activity android:name=".SearchableActivity" > <intent-filter> <action android:name="android.intent.action.SEARCH" /> </intent-filter> <meta-data android:name="android.app.searchable" android:resource="@xml/searchable"/> </activity> <!-- this activity enables the search dialog to initiate searches in the SearchableActivity --> <activity android:name=".OtherActivity" ... > <!-- enable the search dialog to send searches to SearchableActivity --> <b><meta-data android:name="android.app.default_searchable" android:value=".SearchableActivity" /></b> </activity> ... </application> </pre> <p>Because the {@code OtherActivity} now includes a <a href="{@docRoot}guide/topics/manifest/meta-data-element.html">{@code <meta-data>}</a> element to declare which searchable activity to use for searches, the activity has enabled the search dialog. While the user is in this activity, the {@link android.app.Activity#onSearchRequested onSearchRequested()} method activates the search dialog. When the user executes the search, the system starts {@code SearchableActivity} and delivers it the {@link android.content.Intent#ACTION_SEARCH} intent.</p> <p class="note"><strong>Note:</strong> The searchable activity itself provides the search dialog by default, so you don't need to add this declaration to {@code SearchableActivity}.</p> <p>If you want every activity in your application to provide the search dialog, insert the above <a href="{@docRoot}guide/topics/manifest/meta-data-element.html">{@code <meta-data>}</a> element as a child of the <a href="{@docRoot}guide/topics/manifest/application-element.html">{@code <application>}</a> element, instead of each <a href="{@docRoot}guide/topics/manifest/activity-element.html">{@code <activity>}</a>. This way, every activity inherits the value, provides the search dialog, and delivers searches to the same searchable activity. (If you have multiple searchable activities, you can override the default searchable activity by placing a different <a href="{@docRoot}guide/topics/manifest/meta-data-element.html">{@code <meta-data>}</a> declaration inside individual activities.)</p> <p>With the search dialog now enabled for your activities, your application is ready to perform searches.</p> <h3 id="InvokingTheSearchDialog">Invoking the search dialog</h3> <p>Although some devices provide a dedicated Search button, the behavior of the button may vary between devices and many devices do not provide a Search button at all. So when using the search dialog, you <strong>must provide a search button in your UI</strong> that activates the search dialog by calling {@link android.app.Activity#onSearchRequested()}.</p> <p>For instance, you should add a Search button in your <a href="{@docRoot}guide/topics/ui/menus.html#options-menu">Options Menu</a> or UI layout that calls {@link android.app.Activity#onSearchRequested()}. For consistency with the Android system and other apps, you should label your button with the Android Search icon that's available from the <a href="{@docRoot}design/downloads/index.html#action-bar-icon-pack">Action Bar Icon Pack</a>.</p> <p class="note"><strong>Note:</strong> If your app uses an <a href="{@docRoot}training/appbar/index.html">app bar</a>, then you should not use the search dialog for your search interface. Instead, use the <a href="#UsingSearchWidget">search widget</a> as a collapsible view in the app bar.</p> <p>You can also enable "type-to-search" functionality, which activates the search dialog when the user starts typing on the keyboard—the keystrokes are inserted into the search dialog. You can enable type-to-search in your activity by calling {@link android.app.Activity#setDefaultKeyMode(int) setDefaultKeyMode}({@link android.app.Activity#DEFAULT_KEYS_SEARCH_LOCAL}) during your activity's {@link android.app.Activity#onCreate(Bundle) onCreate()} method.</p> <h3 id="LifeCycle">The impact of the search dialog on your activity lifecycle</h3> <p>The search dialog is a {@link android.app.Dialog} that floats at the top of the screen. It does not cause any change in the activity stack, so when the search dialog appears, no lifecycle methods (such as {@link android.app.Activity#onPause()}) are called. Your activity just loses input focus, as input focus is given to the search dialog. </p> <p>If you want to be notified when the search dialog is activated, override the {@link android.app.Activity#onSearchRequested()} method. When the system calls this method, it is an indication that your activity has lost input focus to the search dialog, so you can do any work appropriate for the event (such as pause a game). Unless you are <a href="#SearchContextData">passing search context data</a> (discussed below), you should end the method by calling the super class implementation. For example:</p> <pre> @Override public boolean onSearchRequested() { pauseSomeStuff(); return super.onSearchRequested(); } </pre> <p>If the user cancels search by pressing the <em>Back</em> button, the search dialog closes and the activity regains input focus. You can register to be notified when the search dialog is closed with {@link android.app.SearchManager#setOnDismissListener(SearchManager.OnDismissListener) setOnDismissListener()} and/or {@link android.app.SearchManager#setOnCancelListener(SearchManager.OnCancelListener) setOnCancelListener()}. You should need to register only the {@link android.app.SearchManager.OnDismissListener OnDismissListener}, because it is called every time the search dialog closes. The {@link android.app.SearchManager.OnCancelListener OnCancelListener} only pertains to events in which the user explicitly exited the search dialog, so it is not called when a search is executed (in which case, the search dialog naturally disappears).</p> <p>If the current activity is not the searchable activity, then the normal activity lifecycle events are triggered once the user executes a search (the current activity receives {@link android.app.Activity#onPause()} and so forth, as described in the <a href="{@docRoot}guide/components/activities.html#Lifecycle">Activities</a> document). If, however, the current activity is the searchable activity, then one of two things happens:</p> <ol type="a"> <li>By default, the searchable activity receives the {@link android.content.Intent#ACTION_SEARCH} intent with a call to {@link android.app.Activity#onCreate(Bundle) onCreate()} and a new instance of the activity is brought to the top of the activity stack. There are now two instances of your searchable activity in the activity stack (so pressing the <em>Back</em> button goes back to the previous instance of the searchable activity, rather than exiting the searchable activity).</li> <li>If you set {@code android:launchMode} to <code>"singleTop"</code>, then the searchable activity receives the {@link android.content.Intent#ACTION_SEARCH} intent with a call to {@link android.app.Activity#onNewIntent(Intent)}, passing the new {@link android.content.Intent#ACTION_SEARCH} intent here. For example, here's how you might handle this case, in which the searchable activity's launch mode is <code>"singleTop"</code>: <pre> @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.search); handleIntent(getIntent()); } @Override protected void onNewIntent(Intent intent) { setIntent(intent); handleIntent(intent); } private void handleIntent(Intent intent) { if (Intent.ACTION_SEARCH.equals(intent.getAction())) { String query = intent.getStringExtra(SearchManager.QUERY); doMySearch(query); } } </pre> <p>Compared to the example code in the section about <a href="#PerformingSearch">Performing a Search</a>, all the code to handle the search intent is now in the {@code handleIntent()} method, so that both {@link android.app.Activity#onCreate(Bundle) onCreate()} and {@link android.app.Activity#onNewIntent(Intent) onNewIntent()} can execute it.</p> <p>When the system calls {@link android.app.Activity#onNewIntent(Intent)}, the activity has not been restarted, so the {@link android.app.Activity#getIntent()} method returns the same intent that was received with {@link android.app.Activity#onCreate(Bundle) onCreate()}. This is why you should call {@link android.app.Activity#setIntent(Intent)} inside {@link android.app.Activity#onNewIntent(Intent)} (so that the intent saved by the activity is updated in case you call {@link android.app.Activity#getIntent()} in the future).</p> </li> </ol> <p>The second scenario using <code>"singleTop"</code> launch mode is usually ideal, because chances are good that once a search is done, the user will perform additional searches and it's a bad experience if your application creates multiple instances of the searchable activity. So, we recommend that you set your searchable activity to <code>"singleTop"</code> launch mode in the application manifest. For example:</p> <pre> <activity android:name=".SearchableActivity" <b>android:launchMode="singleTop"</b> > <intent-filter> <action android:name="android.intent.action.SEARCH" /> </intent-filter> <meta-data android:name="android.app.searchable" android:resource="@xml/searchable"/> </activity> </pre> <h3 id="SearchContextData">Passing search context data</h3> <p>In some cases, you can make necessary refinements to the search query inside the searchable activity, for every search made. However, if you want to refine your search criteria based on the activity from which the user is performing a search, you can provide additional data in the intent that the system sends to your searchable activity. You can pass the additional data in the {@link android.app.SearchManager#APP_DATA} {@link android.os.Bundle}, which is included in the {@link android.content.Intent#ACTION_SEARCH} intent.</p> <p>To pass this kind of data to your searchable activity, override the {@link android.app.Activity#onSearchRequested()} method for the activity from which the user can perform a search, create a {@link android.os.Bundle} with the additional data, and call {@link android.app.Activity#startSearch startSearch()} to activate the search dialog. For example:</p> <pre> @Override public boolean onSearchRequested() { Bundle appData = new Bundle(); appData.putBoolean(SearchableActivity.JARGON, true); startSearch(null, false, appData, false); return true; } </pre> <p>Returning "true" indicates that you have successfully handled this callback event and called {@link android.app.Activity#startSearch startSearch()} to activate the search dialog. Once the user submits a query, it's delivered to your searchable activity along with the data you've added. You can extract the extra data from the {@link android.app.SearchManager#APP_DATA} {@link android.os.Bundle} to refine the search. For example:</p> <pre> Bundle appData = getIntent().getBundleExtra(SearchManager.APP_DATA); if (appData != null) { boolean jargon = appData.getBoolean(SearchableActivity.JARGON); } </pre> <p class="caution"><strong>Caution:</strong> Never call the {@link android.app.Activity#startSearch(String,boolean,Bundle,boolean) startSearch()} method from outside the {@link android.app.Activity#onSearchRequested()} callback method. To activate the search dialog in your activity, always call {@link android.app.Activity#onSearchRequested()}. Otherwise, {@link android.app.Activity#onSearchRequested()} is not called and customizations (such as the addition of {@code appData} in the above example) are missed.</p> <h2 id="UsingSearchWidget">Using the Search Widget</h2> <div class="figure" style="width:429px;margin:0"> <img src="{@docRoot}images/ui/actionbar-actionview.png" alt="" /> <p class="img-caption"><strong>Figure 2.</strong> The {@link android.widget.SearchView} widget as an "action view" in the Action Bar.</p> </div> <p>The {@link android.widget.SearchView} widget is available in Android 3.0 and higher. If you're developing your application for Android 3.0 and have decided to use the search widget, we recommend that you insert the search widget as an action view in the app bar, instead of using the search dialog (and instead of placing the search widget in your activity layout). For example, figure 2 shows the search widget in the app bar.</p> <p>The search widget provides the same functionality as the search dialog. It starts the appropriate activity when the user executes a search, and it can provide search suggestions and perform voice search. If it's not an option for you to put the search widget in the Action Bar, you can instead put the search widget somewhere in your activity layout.</p> <p class="note"><strong>Note:</strong> When you use the search widget as an action view, you still might need to support using the search dialog, for cases in which the search widget does not fit in the Action Bar. See the following section about <a href="#UsingBoth">Using both the widget and the dialog</a>.</p> <h3 id="ConfiguringWidget">Configuring the search widget</h3> <p>After you've created a <a href="#SearchableConfiguration">searchable configuration</a> and a <a href="#SearchableActivity">searchable activity</a>, as discussed above, you need to enable assisted search for each {@link android.widget.SearchView}. You can do so by calling {@link android.widget.SearchView#setSearchableInfo setSearchableInfo()} and passing it the {@link android.app.SearchableInfo} object that represents your searchable configuration.</p> <p>You can get a reference to the {@link android.app.SearchableInfo} by calling {@link android.app.SearchManager#getSearchableInfo getSearchableInfo()} on {@link android.app.SearchManager}.</p> <p>For example, if you're using a {@link android.widget.SearchView} as an action view in the <a href="{@docRoot}training/appbar/index.html">app bar</a>, you should enable the widget during the {@link android.app.Activity#onCreateOptionsMenu onCreateOptionsMenu()} callback:</p> <pre> @Override public boolean onCreateOptionsMenu(Menu menu) { // Inflate the options menu from XML MenuInflater inflater = getMenuInflater(); inflater.inflate(R.menu.options_menu, menu); // Get the SearchView and set the searchable configuration SearchManager searchManager = (SearchManager) {@link android.app.Activity#getSystemService getSystemService}(Context.SEARCH_SERVICE); SearchView searchView = (SearchView) menu.findItem(R.id.menu_search).getActionView(); // Assumes current activity is the searchable activity searchView.setSearchableInfo(searchManager.getSearchableInfo({@link android.app.Activity#getComponentName()})); searchView.setIconifiedByDefault(false); // Do not iconify the widget; expand it by default return true; } </pre> <p>That's all you need. The search widget is now configured and the system will deliver search queries to your searchable activity. You can also enable <a href="#SearchSuggestions">search suggestions</a> for the search widget.</p> <p class="note"><strong>Note:</strong> If you want to handle all user input yourself, you can do so with some callback methods and event listeners. For more information, see the reference documentation for {@link android.widget.SearchView} and its nested interfaces for the appropriate event listeners.</p> <p>For more information about action views in the Action Bar, see <a href="{@docRoot}training/appbar/action-views.html">Action Views and Action Providers</a>.</p> <h3 id="WidgetFeatures">Other search widget features</h3> <p>The {@link android.widget.SearchView} widget allows for a few additional features you might want:</p> <dl> <dt>A submit button</dt> <dd>By default, there's no button to submit a search query, so the user must press the "Return" key on the keyboard to initiate a search. You can add a "submit" button by calling {@link android.widget.SearchView#setSubmitButtonEnabled setSubmitButtonEnabled(true)}.</dd> <dt>Query refinement for search suggestions</dt> <dd>When you've enabled search suggestions, you usually expect users to simply select a suggestion, but they might also want to refine the suggested search query. You can add a button alongside each suggestion that inserts the suggestion in the search box for refinement by the user, by calling {@link android.widget.SearchView#setQueryRefinementEnabled setQueryRefinementEnabled(true)}.</dd> <dt>The ability to toggle the search box visibility</dt> <dd>By default, the search widget is "iconified," meaning that it is represented only by a search icon (a magnifying glass), and expands to show the search box when the user touches it. As shown above, you can show the search box by default, by calling {@link android.widget.SearchView#setIconifiedByDefault setIconifiedByDefault(false)}. You can also toggle the search widget appearance by calling {@link android.widget.SearchView#setIconified setIconified()}.</dd> </dl> <p>There are several other APIs in the {@link android.widget.SearchView} class that allow you to customize the search widget. However, most of them are used only when you handle all user input yourself, instead of using the Android system to deliver search queries and display search suggestions.</p> <h3 id="UsingBoth">Using both the widget and the dialog</h3> <p>If you insert the search widget in the Action Bar as an <a href="{@docRoot}guide/topics/ui/actionbar.html#ActionView">action view</a>, and you enable it to appear in the Action Bar "if there is room" (by setting {@code android:showAsAction="ifRoom"}), then there is a chance that the search widget will not appear as an action view, but the menu item will appear in the overflow menu. For example, when your application runs on a smaller screen, there might not be enough room in the Action Bar to display the search widget along with other action items or navigation elements, so the menu item will instead appear in the overflow menu. When placed in the overflow menu, the item works like an ordinary menu item and does not display the action view (the search widget).</p> <p>To handle this situation, the menu item to which you've attached the search widget should activate the search dialog when the user selects it from the overflow menu. In order for it to do so, you must implement {@link android.app.Activity#onOptionsItemSelected onOptionsItemSelected()} to handle the "Search" menu item and open the search dialog by calling {@link android.app.Activity#onSearchRequested onSearchRequested()}.</p> <p>For more information about how items in the Action Bar work and how to handle this situation, see the <a href="{@docRoot}guide/topics/ui/actionbar.html">Action Bar</a> developer guide.</p> <p>Also see the <a href="{@docRoot}resources/samples/SearchableDictionary/src/com/example/android/searchabledict/SearchableDictionary.html" >Searchable Dictionary</a> for an example implementation using both the dialog and the widget.</p> <h2 id="VoiceSearch">Adding Voice Search</h2> <p>You can add voice search functionality to your search dialog or widget by adding the {@code android:voiceSearchMode} attribute to your searchable configuration. This adds a voice search button that launches a voice prompt. When the user has finished speaking, the transcribed search query is sent to your searchable activity.</p> <p>For example:</p> <pre> <?xml version="1.0" encoding="utf-8"?> <searchable xmlns:android="http://schemas.android.com/apk/res/android" android:label="@string/search_label" android:hint="@string/search_hint" <b>android:voiceSearchMode="showVoiceSearchButton|launchRecognizer"</b> > </searchable> </pre> <p>The value {@code showVoiceSearchButton} is required to enable voice search, while the second value, {@code launchRecognizer}, specifies that the voice search button should launch a recognizer that returns the transcribed text to the searchable activity.</p> <p>You can provide additional attributes to specify the voice search behavior, such as the language to be expected and the maximum number of results to return. See the <a href="searchable-config.html">Searchable Configuration</a> reference for more information about the available attributes.</p> <p class="note"><strong>Note:</strong> Carefully consider whether voice search is appropriate for your application. All searches performed with the voice search button are immediately sent to your searchable activity without a chance for the user to review the transcribed query. Sufficiently test the voice recognition and ensure that it understands the types of queries that the user might submit inside your application.</p> <h2 id="SearchSuggestions">Adding Search Suggestions</h2> <div class="figure" style="width:250px;margin:0"> <img src="{@docRoot}images/search/search-suggest-custom.png" alt="" height="417" /> <p class="img-caption"><strong>Figure 3.</strong> Screenshot of a search dialog with custom search suggestions.</p> </div> <p>Both the search dialog and the search widget can provide search suggestions as the user types, with assistance from the Android system. The system manages the list of suggestions and handles the event when the user selects a suggestion.</p> <p>You can provide two kinds of search suggestions:</p> <dl> <dt>Recent query search suggestions</dt> <dd>These suggestions are simply words that the user previously used as search queries in your application. <p>See <a href="adding-recent-query-suggestions.html">Adding Recent Query Suggestions</a>.</p></dd> <dt>Custom search suggestions</dt> <dd>These are search suggestions that you provide from your own data source, to help users immediately select the correct spelling or item they are searching for. Figure 3 shows an example of custom suggestions for a dictionary application—the user can select a suggestion to instantly go to the definition. <p>See <a href="adding-custom-suggestions.html">Adding Custom Suggestions</a></p></dd> </dl>