diff options
author | Scott Main <smain@google.com> | 2010-07-16 14:52:03 -0700 |
---|---|---|
committer | Android (Google) Code Review <android-gerrit@google.com> | 2010-07-16 14:52:03 -0700 |
commit | 2a8dd4e46f43c2bc5b3c1cfd2f350a83ea2b18b1 (patch) | |
tree | 23f702d742667901566c6dad3128aacf315ecaa8 /docs/html/guide | |
parent | d59f1dea1746b316e556df5b4d2080f110aabd1c (diff) | |
parent | 5e892d8183d4ffb1b61b41248763636b9221958b (diff) | |
download | frameworks_base-2a8dd4e46f43c2bc5b3c1cfd2f350a83ea2b18b1.zip frameworks_base-2a8dd4e46f43c2bc5b3c1cfd2f350a83ea2b18b1.tar.gz frameworks_base-2a8dd4e46f43c2bc5b3c1cfd2f350a83ea2b18b1.tar.bz2 |
Merge "docs: editorial revisions to Search guide" into froyo
Diffstat (limited to 'docs/html/guide')
-rw-r--r-- | docs/html/guide/topics/search/adding-custom-suggestions.jd | 589 | ||||
-rw-r--r-- | docs/html/guide/topics/search/adding-recent-query-suggestions.jd | 214 | ||||
-rw-r--r-- | docs/html/guide/topics/search/index.jd | 106 | ||||
-rw-r--r-- | docs/html/guide/topics/search/search-dialog.jd | 460 | ||||
-rw-r--r-- | docs/html/guide/topics/search/searchable-config.jd | 268 |
5 files changed, 874 insertions, 763 deletions
diff --git a/docs/html/guide/topics/search/adding-custom-suggestions.jd b/docs/html/guide/topics/search/adding-custom-suggestions.jd index 9ea4c8b..ce0c619 100644 --- a/docs/html/guide/topics/search/adding-custom-suggestions.jd +++ b/docs/html/guide/topics/search/adding-custom-suggestions.jd @@ -5,74 +5,88 @@ parent.link=index.html <div id="qv-wrapper"> <div id="qv"> -<h2>Key classes</h2> -<ol> -<li>{@link android.app.SearchManager}</li> -<li>{@link android.content.SearchRecentSuggestionsProvider}</li> -<li>{@link android.content.ContentProvider}</li> -</ol> <h2>In this document</h2> <ol> <li><a href="#TheBasics">The Basics</a></li> -<li><a href="#CustomSearchableConfiguration">Modifying the searchable configuration</a></li> +<li><a href="#CustomSearchableConfiguration">Modifying the Searchable Configuration</a></li> <li><a href="#CustomContentProvider">Creating a Content Provider</a> <ol> <li><a href="#HandlingSuggestionQuery">Handling a suggestion query</a></li> <li><a href="#SuggestionTable">Building a suggestion table</a></li> </ol> </li> -<li><a href="#IntentForSuggestions">Declaring an Intent for suggestions</a> +<li><a href="#IntentForSuggestions">Declaring an Intent for Suggestions</a> <ol> <li><a href="#IntentAction">Declaring the Intent action</a></li> <li><a href="#IntentData">Declaring the Intent data</a></li> </ol> </li> <li><a href="#HandlingIntent">Handling the Intent</a></li> -<li><a href="#RewritingQueryText">Rewriting the query text</a></li> -<li><a href="#QSB">Exposing search suggestions to Quick Search Box</a></li> +<li><a href="#RewritingQueryText">Rewriting the Query Text</a></li> +<li><a href="#QSB">Exposing Search Suggestions to Quick Search Box</a></li> +</ol> + +<h2>Key classes</h2> +<ol> +<li>{@link android.app.SearchManager}</li> +<li>{@link android.content.SearchRecentSuggestionsProvider}</li> +<li>{@link android.content.ContentProvider}</li> +</ol> + +<h2>Related Samples</h2> +<ol> +<li><a href="{@docRoot}resources/samples/SearchableDictionary/index.html">Searchable +Dictionary</a></li> </ol> + <h2>See also</h2> <ol> <li><a href="searchable-config.html">Searchable Configuration</a></li> <li><a href="{@docRoot}guide/topics/providers/content-providers.html">Content Providers</a></li> -<li><a href="{@docRoot}resources/samples/SearchableDictionary/index.html">Searchable -Dictionary sample app</a></li> </ol> </div> </div> -<p>The Android search framework provides the ability for your application to -provide suggestions while the user types into the Android search dialog. In this guide, you'll learn -how to create custom suggestions. These are suggestions based on custom data provided by your -application. For example, if your application is a word dictionary, you can suggest words from the -dictionary that match the text entered so far. These are the most valuable suggestions because you -can effectively predict what the user wants and provide instant access to it. Once you provide -custom suggestions, you then make them available to the system-wide Quick Search Box, providing -access to your content from outside your application.</p> - -<p>Before you begin, you need to have implemented the Android search dialog for searches in your -application. If you haven't done this, see <a href="search-dialog.html">Using the Android Search +<p>When using the Android search dialog, you can provide custom search suggestions that are +created from data in your application. For example, if your application is a word +dictionary, you can suggest words from the +dictionary that match the text entered so far. These are the most valuable suggestions, because you +can effectively predict what the user wants and provide instant access to it. Figure 1 shows +an example of a search dialog with custom suggestions.</p> + +<p>Once you provide custom suggestions, you can also make them available to the system-wide Quick +Search Box, providing access to your content from outside your application.</p> + +<p>Before you begin with this guide to add custom suggestions, you need to have implemented the +Android search dialog for searches in your +application. If you haven't, see <a href="search-dialog.html">Using the Android Search Dialog</a>.</p> <h2 id="TheBasics">The Basics</h2> -<img src="{@docRoot}images/search/search-suggest-custom.png" alt="" height="417" -style="float:right;clear:right;" /> +<div class="figure" style="width:250px"> +<img src="{@docRoot}images/search/search-suggest-custom.png" alt="" height="417" /> +<p class="img-caption"><strong>Figure 1.</strong> Screenshot of a search dialog with custom +search suggestions.</p> +</div> -<p>When the user selects a custom suggestions, the Search Manager will send a customized Intent to -your searchable Activity. Whereas a normal search query will send an Intent with the {@link +<p>When the user selects a custom suggestion, the Search Manager sends an {@link +android.content.Intent} to +your searchable Activity. Whereas a normal search query sends an Intent with the {@link android.content.Intent#ACTION_SEARCH} action, you can instead define your custom suggestions to use -{@link android.content.Intent#ACTION_VIEW} (or any other action), and also include additional data +{@link android.content.Intent#ACTION_VIEW} (or any other Intent action), and also include data that's relevant to the selected suggestion. Continuing the dictionary example, when the user selects a suggestion, your application can immediately open the definition for that word, instead of searching the dictionary for matches.</p> -<p>To provide custom suggestions, you need to do the following:</p> +<p>To provide custom suggestions, do the following:</p> <ul> <li>Implement a basic searchable Activity, as described in <a href="search-dialog.html">Using the Android Search Dialog</a>.</li> + <li>Modify the searchable configuration with information about the content provider that +provides custom suggestions.</li> <li>Build a table (such as in an {@link android.database.sqlite.SQLiteDatabase}) for your suggestions and format the table with required columns.</li> <li>Create a <a href="{@docRoot}guide/topics/providers/content-providers.html">Content @@ -80,36 +94,32 @@ Provider</a> that has access to your suggestions table and declare the provider in your manifest.</li> <li>Declare the type of {@link android.content.Intent} to be sent when the user selects a suggestion (including a custom action and custom data). </li> - <li>Modify the searchable configuration with information about the content provider.</li> </ul> -<p>Just like the Search Manager handles the rendering of the search dialog, it will also do the work -to display all search suggestions below the search dialog. All you need to do is provide a source -from which the suggestions can be retrieved.</p> - -<p class="note"><strong>Note:</strong> If you're not familiar with creating Content -Providers, please read the <a href="{@docRoot}guide/topics/providers/content-providers.html">Content +<p>Just like the Search Manager displays the search dialog, it also displays your search +suggestions. All you need is a content provider from which the Search Manager can retrieve your +suggestions. If you're not familiar with creating content +providers, read the <a href="{@docRoot}guide/topics/providers/content-providers.html">Content Providers</a> developer guide before you continue.</p> -<p>When the Search Manager identifies that your Activity is searchable and also provides search -suggestions, the following procedure will take place as soon as the user types into the Android -search box:</p> +<p>When the Search Manager identifies that your Activity is searchable and provides search +suggestions, the following procedure takes place as soon as the user enters text into the +search dialog:</p> -<ul> - <li>The Search Manager takes the search query text (whatever has been typed so far) and performs a -query to the content provider that manages your suggestions.</li> - <li>Your content provider then returns a {@link android.database.Cursor} that points to all +<ol> + <li>Search Manager takes the search query text (whatever has been typed so far) and performs a +query to your content provider that manages your suggestions.</li> + <li>Your content provider returns a {@link android.database.Cursor} that points to all suggestions that are relevant to the search query text.</li> - <li>The Search Manager then displays the list of suggestions provided by the Cursor (as -demonstrated in the screenshot to the right).</li> -</ul> + <li>Search Manager displays the list of suggestions provided by the Cursor.</li> +</ol> -<p>At this point, the following may happen:</p> +<p>Once the custom suggestions are displayed, the following might happen:</p> <ul> <li>If the user types another key, or changes the query in any way, the above steps are repeated and the suggestion list is updated as appropriate. </li> - <li>If the user executes the search, the suggestions are ignored and the search is delivered + <li>If the user executes the search, the suggestions are ignored and the search is delivered to your searchable Activity using the normal {@link android.content.Intent#ACTION_SEARCH} Intent.</li> <li>If the user selects a suggestion, an Intent is sent to your searchable Activity, carrying a @@ -124,56 +134,64 @@ custom action and custom data so that your application can open the suggested co to the {@code <searchable>} element in your searchable configuration file. For example:</p> <pre> -<?xml version="1.0" encoding="utf-8"?> +<?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" - android:searchSuggestAuthority="my.package.MyCustomSuggestionProvider" > -</searchable> + <b>android:searchSuggestAuthority="com.example.MyCustomSuggestionProvider"</b>> +</searchable> </pre> -<p>You may require some additional attributes, depending on the type of Intent you attach +<p>You might need some additional attributes, depending on the type of Intent you attach to each suggestion and how you want to format queries to your content provider. The other optional -attributes are discussed in the relevant sections below.</p> +attributes are discussed in the following sections.</p> + <h2 id="CustomContentProvider">Creating a Content Provider</h2> -<p>Creating a content provider for custom suggestions requires previous knowledge about Content -Providers that's covered in the <a +<p>Creating a content provider for custom suggestions requires previous knowledge about content +providers that's covered in the <a href="{@docRoot}guide/topics/providers/content-providers.html">Content Provider</a> developer guide. For the most part, a content provider for custom suggestions is the same as any other content provider. However, for each suggestion you provide, the respective row in the {@link android.database.Cursor} must include specific columns that the Search Manager -understands.</p> +understands and uses to format the suggestions.</p> -<p>When the user starts typing into the search dialog, the Search Manager will query your Content -Provider for suggestions by calling {@link +<p>When the user starts typing into the search dialog, the Search Manager queries your content +provider for suggestions by calling {@link android.content.ContentProvider#query(Uri,String[],String,String[],String) query()} each time a letter is typed. In your implementation of {@link android.content.ContentProvider#query(Uri,String[],String,String[],String) query()}, your content provider must search your suggestion data and return a {@link -android.database.Cursor} that points to the rows you determine to be good suggestions.</p> +android.database.Cursor} that points to the rows you have determined to be good suggestions.</p> -<p>The following two sections describe how the Search Manager will send requests to your Content -Provider and how you can handle them, and define the columns that the Search Manager understands and -expects to be provided in the {@link android.database.Cursor} returned with each query.</p> +<p>Details about creating a content provider for custom suggestions are discussed in the following +two sections:</p> +<dl> + <dt><a href="#HandlingSuggestionQuery">Handling the suggestion query</a></dt> + <dd>How the Search Manager sends requests to your content provider and how to handle them</dd> + <dt><a href="#SuggestionTable">Building a suggestion table</a></dt> + <dd>How to define the columns that the Search Manager expects in the {@link +android.database.Cursor} returned with each query</dd> +</dl> <h3 id="HandlingSuggestionQuery">Handling the suggestion query</h3> -<p>When the Search Manager makes a request for suggestions from your content provider, it will call -{@link android.content.ContentProvider#query(Uri,String[],String,String[],String)}. You must -implement this method in your content provider so that it will search your suggestions and return a -Cursor that contains the suggestions you deem relevant.</p> +<p>When the Search Manager requests suggestions from your content provider, it calls your content +provider's {@link android.content.ContentProvider#query(Uri,String[],String,String[],String) +query()} method. You must +implement this method to search your suggestion data and return a +{@link android.database.Cursor} pointing to the suggestions you deem relevant.</p> -<p>Here's a summary of the parameters that the Search Manager will pass to your {@link +<p>Here's a summary of the parameters that the Search Manager passes to your {@link android.content.ContentProvider#query(Uri,String[],String,String[],String) query()} method (listed in order):</p> <dl> <dt><code>uri</code></dt> - <dd>This will always be a content {@link android.net.Uri}, formatted as: + <dd>Always a content {@link android.net.Uri}, formatted as: <pre class="no-pretty-print"> content://<em>your.authority</em>/<em>optional.suggest.path</em>/<em>{@link android.app.SearchManager#SUGGEST_URI_PATH_QUERY}</em> @@ -184,46 +202,48 @@ For example:</p> content://<em>your.authority</em>/<em>optional.suggest.path</em>/<em>{@link android.app.SearchManager#SUGGEST_URI_PATH_QUERY}</em>/puppies </pre> -<p>The query text on the end will be encoded using URI encoding rules, so you may need to decode -it.</p> +<p>The query text on the end is encoded using URI encoding rules, so you might need to decode +it before performing a search.</p> <p>The <em>{@code optional.suggest.path}</em> portion is only included in the URI if you have set such a path in your searchable configuration file with the {@code android:searchSuggestPath} attribute. This is only needed if you use the same content provider for multiple searchable -activities, in which case you need to disambiguate the source of the suggestion query.</p> -<p>Note that {@link android.app.SearchManager#SUGGEST_URI_PATH_QUERY} is not the literal +activities, in which case, you need to disambiguate the source of the suggestion query.</p> +<p class="note"><strong>Note:</strong> {@link +android.app.SearchManager#SUGGEST_URI_PATH_QUERY} is not the literal string provided in the URI, but a constant that you should use if you need to refer to this path.</p> </dd> <dt><code>projection</code></dt> - <dd>This is always null</dd> + <dd>Always null</dd> <dt><code>selection</code></dt> - <dd>This is the value provided in the {@code android:searchSuggestSelection} attribute of + <dd>The value provided in the {@code android:searchSuggestSelection} attribute of your searchable configuration file, or null if you have not declared the {@code -android:searchSuggestSelection} attribute. More about this below.</dd> +android:searchSuggestSelection} attribute. More about using this to <a href="#GetTheQuery">get the +query</a> below.</dd> <dt><code>selectionArgs</code></dt> - <dd>This contains the search query as the first (and only) element of the array if you have + <dd>Contains the search query as the first (and only) element of the array if you have declared the {@code android:searchSuggestSelection} attribute in your searchable configuration. If you have not declared {@code android:searchSuggestSelection}, then this parameter is null. More -about this below.</dd> +about using this to <a href="#GetTheQuery">get the query</a> below.</dd> <dt><code>sortOrder</code></dt> - <dd>This is always null</dd> + <dd>Always null</dd> </dl> -<p>As you may have realized, there are two ways by which the Search Manager can send you the search -query text. The default manner is for the query text to be included as the last path of the content -URI that is passed in the {@code uri} parameter. However, if you include a selection value in your +<p>The Search Manager can send you the search query text in two ways. The +default manner is for the query text to be included as the last path of the content +URI passed in the {@code uri} parameter. However, if you include a selection value in your searchable configuration's {@code -android:searchSuggestSelection} attribute, then the query text will instead be passed as the first -element of the {@code selectionArgs} string array. Both options are summarized below.</p> +android:searchSuggestSelection} attribute, then the query text is instead passed as the first +element of the {@code selectionArgs} string array. Both options are summarized next.</p> -<h4>Get the query in the Uri</h4> +<h4 id="GetTheQueryUri">Get the query in the Uri</h4> -<p>By default, the query will be appended as the last segment of the {@code uri} +<p>By default, the query is appended as the last segment of the {@code uri} parameter (a {@link android.net.Uri} object). To retrieve the query text in this case, simply use {@link android.net.Uri#getLastPathSegment()}. For example:</p> @@ -231,52 +251,59 @@ parameter (a {@link android.net.Uri} object). To retrieve the query text in this String query = uri.getLastPathSegment().toLowerCase(); </pre> -<p>This will return the last segment of the Uri, which is the query text entered in the search -dialog.</p> +<p>This returns the last segment of the {@link android.net.Uri}, which is the query text entered in +the search dialog.</p> -<h4>Get the query in the selection arguments</h4> +<h4 id="GetTheQuery">Get the query in the selection arguments</h4> -<p>Instead of using the URI, you may decide it makes more sense for your {@link +<p>Instead of using the URI, you might decide it makes more sense for your {@link android.content.ContentProvider#query(Uri,String[],String,String[],String) query()} method to receive everything it needs to perform the look-up and you want the -{@code selection} and {@code selectionArgs} parameters to carry values. In this case, you can -add the {@code android:searchSuggestSelection} attribute to your searchable configuration with your -SQLite selection string. In this selection string, you can include a question mark ("?") as -a placeholder for the actual search query. This selection string will be delivered as the -{@code selection} string parameter, and the query entered into the search dialog will be delivered -as the first element in the {@code selectionArgs} string array parameter.</p> +{@code selection} and {@code selectionArgs} parameters to carry the appropriate values. In such a +case, add the {@code android:searchSuggestSelection} attribute to your searchable configuration with +your SQLite selection string. In the selection string, include a question mark ("?") as +a placeholder for the actual search query. The Search Manager calls {@link +android.content.ContentProvider#query(Uri,String[],String,String[],String) query()} with the +selection string as the {@code selection} parameter and the search query as the first +element in the {@code selectionArgs} array.</p> <p>For example, here's how you might form the {@code android:searchSuggestSelection} attribute to create a full-text search statement:</p> <pre> -<?xml version="1.0" encoding="utf-8"?> +<?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" - android:searchSuggestAuthority="my.package.MyCustomSuggestionProvider" + android:searchSuggestAuthority="com.example.MyCustomSuggestionProvider" android:searchSuggestIntentAction="android.Intent.action.VIEW" - android:searchSuggestSelection="word MATCH ?"> -</searchable> + <b>android:searchSuggestSelection="word MATCH ?"</b>> +</searchable> </pre> -<p>When you then receive the {@code selection} and {@code selectionArgs} parameters in your {@link -android.content.ContentProvider#query(Uri,String[],String,String[],String) ContentProvider.query()} -method, they will carry the selection ("word MATCH ?") and the query text, respectively. When -these are passed to an SQLite {@link -android.database.sqlite.SQLiteDatabase#query(String,String[],String,String[],String,String, -String) query} method, they will be synthesized together (replacing the question mark with the query -text, wrapped in single-quotes). Note that if you chose this method and need to add any wildcards to -your query text, you must do so by appending (and/or prefixing) them to the {@code selectionArgs} -parameter, because this is the value that will be wrapped in quotes and inserted in place of the +<p>With this configuration, your {@link +android.content.ContentProvider#query(Uri,String[],String,String[],String) query()} method +delivers the {@code selection} parameter as "word MATCH ?" and the {@code selectionArgs} +parameter as whatever the user entered in the search dialog. When you pass these to an SQLite +{@link android.database.sqlite.SQLiteDatabase#query(String,String[],String,String[],String,String, +String) query()} method, as their respective arguments, they are synthesized together (the +question mark is replaced with the query +text). If you chose to receive suggestion queries this way and need to add wildcards to +the query text, append (and/or prefix) them to the {@code selectionArgs} +parameter, because this value is wrapped in quotes and inserted in place of the question mark.</p> +<p>Another new attribute in the example above is {@code android:searchSuggestIntentAction}, which +defines the Intent action sent with each Intent when the user selects a suggestion. It is +discussed further in the section about <a href="#IntentForSuggestions">Declaring an Intent for +suggestions</a>.</p> + <p class="note"><strong>Tip:</strong> If you don't want to define a selection clause in the {@code android:searchSuggestSelection} attribute, but would still like to receive the query text in the {@code selectionArgs} parameter, simply provide a non-null value for the {@code -android:searchSuggestSelection} attribute. This will trigger the query to be passed in {@code +android:searchSuggestSelection} attribute. This triggers the query to be passed in {@code selectionArgs} and you can ignore the {@code selection} parameter. In this way, you can instead define the actual selection clause at a lower level so that your content provider doesn't have to handle it.</p> @@ -287,11 +314,12 @@ handle it.</p> <div class="sidebox-wrapper"> <div class="sidebox"> -<h2>Creating a Cursor on the fly</h2> -<p>If your search suggestions are not stored in a table format using the columns required by the +<h2>Creating a Cursor without a table</h2> +<p>If your search suggestions are not stored in a table format (such as an SQLite table) using the +columns required by the Search Manager, then you can search your suggestion data for matches and then format them -into the necessary table on the fly. To do so, create a {@link android.database.MatrixCursor} using -the required column names and then add a row for each suggestion using {@link +into the necessary table on each request. To do so, create a {@link android.database.MatrixCursor} +using the required column names and then add a row for each suggestion using {@link android.database.MatrixCursor#addRow(Object[])}. Return the final product from your Content Provider's {@link android.content.ContentProvider#query(Uri,String[],String,String[],String) query()} method.</p> @@ -299,97 +327,94 @@ android.content.ContentProvider#query(Uri,String[],String,String[],String) query </div> <p>When you return suggestions to the Search Manager with a {@link android.database.Cursor}, the -Search Manager expects there to be specific columns in each row. So, regardless of whether you +Search Manager expects specific columns in each row. So, regardless of whether you decide to store your suggestion data in an SQLite database on the device, a database on a web server, or another format on the device or web, you must format the suggestions as rows in a table and -present them with a {@link android.database.Cursor}. There are several columns that the Search -Manager will understand, but only two are required:</p> +present them with a {@link android.database.Cursor}. The Search +Manager understands several columns, but only two are required:</p> <dl> <dt>{@link android.provider.BaseColumns#_ID}</dt> - <dd>This is the unique row ID for each suggestion. The search dialog requires this in order -to present the suggestions in a ListView.</dd> + <dd>A unique integer row ID for each suggestion. The search dialog requires this in order +to present suggestions in a ListView.</dd> <dt>{@link android.app.SearchManager#SUGGEST_COLUMN_TEXT_1}</dt> - <dd>This is the line of text that will be presented to the user as a suggestion.</dd> + <dd>The string that is presented as a suggestion.</dd> </dl> -<p>The following columns are all optional (and most will be discussed further in the following -sections, so you may want to skip this list for now):</p> +<p>The following columns are all optional (and most are discussed further in the following +sections):</p> <dl> <dt>{@link android.app.SearchManager#SUGGEST_COLUMN_TEXT_2}</dt> - <dd>If your Cursor includes this column, then all suggestions will be provided in a two-line -format. The data in this column will be displayed as a second, smaller line of text below the + <dd>A string. If your Cursor includes this column, then all suggestions are provided in a +two-line format. The string in this column is displayed as a second, smaller line of text below the primary suggestion text. It can be null or empty to indicate no secondary text.</dd> <dt>{@link android.app.SearchManager#SUGGEST_COLUMN_ICON_1}</dt> - <dd>If your Cursor includes this column, then all suggestions will be provided in an -icon-plus-text format with the icon on the left side. This value should be a reference to the -icon. It can be null or zero to indicate no icon in this row.</dd> + <dd>A drawable resource, content, or file URI string. If your Cursor includes this column, then +all suggestions are provided in an icon-plus-text format with the drawable icon on the left side. +This can be null or zero to indicate no icon in this row.</dd> <dt>{@link android.app.SearchManager#SUGGEST_COLUMN_ICON_2}</dt> - <dd>If your Cursor includes this column, then all suggestions will be provided in an -icon-plus-text format with the icon on the right side. This value should be a reference to the -icon. It can be null or zero to indicate no icon in this row.</dd> + <dd>A drawable resource, content, or file URI string. If your Cursor includes this column, then +all suggestions are provided in an icon-plus-text format with the icon on the right side. This can +be null or zero to indicate no icon in this row.</dd> <dt>{@link android.app.SearchManager#SUGGEST_COLUMN_INTENT_ACTION}</dt> - <dd>If this column exists and this element exists at the given row, this is the action that will -be used when forming the suggestion's Intent . If the element is not provided, the action will be -taken from the {@code android:searchSuggestIntentAction} field in your searchable configuration. At -least one of these -must be present for the suggestion to generate an Intent. Note: If your action is the same for all + <dd>An Intent action string. If this column exists and contains a value at the given row, the +action defined here is used when forming the suggestion's Intent. If the element is not +provided, the action is taken from the {@code android:searchSuggestIntentAction} field in your +searchable configuration. If your action is the same for all suggestions, it is more efficient to specify the action using {@code -android:searchSuggestIntentAction} and omit this column from the Cursor .</dd> +android:searchSuggestIntentAction} and omit this column.</dd> <dt>{@link android.app.SearchManager#SUGGEST_COLUMN_INTENT_DATA}</dt> - <dd>If this column exists and this element exists at the given row, this is the data that will be -used when forming the suggestion's Intent. If the element is not provided, the data will be taken -from the {@code android:searchSuggestIntentData} field in your searchable configuration. If neither -source is provided, -the Intent's data field will be null. Note: If your data is the same for all suggestions, or can be + <dd>A data URI string. If this column exists and contains a value at the given row, this is the +data that is used when forming the suggestion's Intent. If the element is not provided, the data is +taken from the {@code android:searchSuggestIntentData} field in your searchable configuration. If +neither source is provided, +the Intent's data field is null. If your data is the same for all suggestions, or can be described using a constant part and a specific ID, it is more efficient to specify it using {@code -android:searchSuggestIntentData} and omit this column from the Cursor . +android:searchSuggestIntentData} and omit this column. </dd> <dt>{@link android.app.SearchManager#SUGGEST_COLUMN_INTENT_DATA_ID}</dt> - <dd>If this column exists and this element exists at the given row, then "/" and this value will -be appended to the data field in the Intent. This should only be used if the data field specified + <dd>A URI path string. If this column exists and contains a value at the given row, then "/" and +this value is appended to the data field in the Intent. This should only be used if the data field +specified by the {@code android:searchSuggestIntentData} attribute in the searchable configuration has already been set to an appropriate base string.</dd> <dt>{@link android.app.SearchManager#SUGGEST_COLUMN_INTENT_EXTRA_DATA}</dt> - <dd>If this column exists and this element exists at a given row, this is the <em>extra</em> data -that will be used when forming the suggestion's Intent. If not provided, the Intent's extra data -field will be -null. This column allows suggestions to provide additional arbitrary data which will be + <dd>Arbitrary data. If this column exists and contains a value at a given row, this is the +<em>extra</em> data used when forming the suggestion's Intent. If not provided, the +Intent's extra data field is null. This column allows suggestions to provide additional data that is included as an extra in the Intent's {@link android.app.SearchManager#EXTRA_DATA_KEY} key.</dd> <dt>{@link android.app.SearchManager#SUGGEST_COLUMN_QUERY}</dt> - <dd>If this column exists and this element exists at the given row, this is the data that will be + <dd>If this column exists and this element exists at the given row, this is the data that is used when forming the suggestion's query, included as an extra in the Intent's {@link android.app.SearchManager#QUERY} key. Required if suggestion's action is {@link android.content.Intent#ACTION_SEARCH}, optional otherwise.</dd> <dt>{@link android.app.SearchManager#SUGGEST_COLUMN_SHORTCUT_ID}</dt> - <dd>Only used when providing suggestions for Quick Search Box. This column is used to indicate + <dd>Only used when providing suggestions for Quick Search Box. This column indicates whether a search suggestion should be stored as a -shortcut, and whether it should be validated. Shortcuts are usually formed when the user clicks a -suggestion from Quick Search Box. If missing, the result will be stored as a shortcut and never -refreshed. If set to {@link android.app.SearchManager#SUGGEST_NEVER_MAKE_SHORTCUT}, the result will -not be stored as a shortcut. -Otherwise, the shortcut id will be used to check back for for an up to date suggestion using +shortcut and whether it should be validated. Shortcuts are usually formed when the user clicks a +suggestion from Quick Search Box. If missing, the result is stored as a shortcut and never +refreshed. If set to {@link android.app.SearchManager#SUGGEST_NEVER_MAKE_SHORTCUT}, the result is +not stored as a shortcut. +Otherwise, the shortcut ID is used to check back for an up to date suggestion using {@link android.app.SearchManager#SUGGEST_URI_PATH_SHORTCUT}.</dd> <dt>{@link android.app.SearchManager#SUGGEST_COLUMN_SPINNER_WHILE_REFRESHING}</dt> - <dd>Only used when providing suggestions for Quick Search Box. This column is used to specify that + <dd>Only used when providing suggestions for Quick Search Box. This column specifies that a spinner should be shown instead of an icon from {@link android.app.SearchManager#SUGGEST_COLUMN_ICON_2} while the shortcut of this suggestion is being refreshed in Quick Search Box.</dd> </dl> -<p>Again, most of these columns will be discussed in the relevant sections below, so don't worry if -they don't make sense to you now.</p> +<p>Some of these columns are discussed more in the following sections.</p> <h2 id="IntentForSuggestions">Declaring an Intent for suggestions</h2> -<p>When the user selects a suggestion from the list that appears below the search -dialog (instead of performing a search), the Search Manager will send -a custom {@link android.content.Intent} to your searchable Activity. You must define both the -<em>action</em> and <em>data</em> for the Intent.</p> +<p>When the user selects a suggestion from the list that appears below the search dialog, the Search +Manager sends a custom {@link android.content.Intent} to your searchable Activity. You must define +the action and data for the Intent.</p> <h3 id="IntentAction">Declaring the Intent action</h3> @@ -397,34 +422,42 @@ a custom {@link android.content.Intent} to your searchable Activity. You must de <p>The most common Intent action for a custom suggestion is {@link android.content.Intent#ACTION_VIEW}, which is appropriate when you want to open something, like the definition for a word, a person's contact information, or a web -page. However, the Intent action can be whatever you want and can even be different for each +page. However, the Intent action can be any other action and can even be different for each suggestion.</p> -<p>To declare an Intent action that will be the same for all suggestions, define the action in -the {@code android:searchSuggestIntentAction} attribute of your searchable configuration file. For -example:</p> +<p>Depending on whether you want all suggestions to use the same Intent action, you +can define the action in two ways:</p> + +<ol type="a"> + <li>Use the {@code android:searchSuggestIntentAction} attribute of your searchable configuration +file to define the action for all suggestions. <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/app_label" android:hint="@string/search_hint" - android:searchSuggestAuthority="my.package.MySuggestionProvider" - android:searchSuggestIntentAction="android.Intent.action.VIEW" > + android:searchSuggestAuthority="com.example.MyCustomSuggestionProvider" + <b>android:searchSuggestIntentAction="android.Intent.action.VIEW"</b> > </searchable> </pre> -<p>If you want to declare an Intent action that's unique for each suggestion, add the {@link -android.app.SearchManager#SUGGEST_COLUMN_INTENT_ACTION} column to + </li> + <li>Use the {@link android.app.SearchManager#SUGGEST_COLUMN_INTENT_ACTION} column to define the +action for individual suggestions. + <p>Add the {@link android.app.SearchManager#SUGGEST_COLUMN_INTENT_ACTION} column to your suggestions table and, for each suggestion, place in it the action to use (such as -{@code "android.Intent.action.VIEW"}). </p> +{@code "android.Intent.action.VIEW"}).</p> + + </li> +</ol> <p>You can also combine these two techniques. For instance, you can include the {@code android:searchSuggestIntentAction} attribute with an action to be used with all suggestions by default, then override this action for some suggestions by declaring a different action in the {@link android.app.SearchManager#SUGGEST_COLUMN_INTENT_ACTION} column. If you do not include a value in the {@link android.app.SearchManager#SUGGEST_COLUMN_INTENT_ACTION} column, then the -Intent provided in the {@code android:searchSuggestIntentAction} attribute will be used.</p> +Intent provided in the {@code android:searchSuggestIntentAction} attribute is used.</p> <p class="note"><strong>Note</strong>: If you do not include the {@code android:searchSuggestIntentAction} attribute in your searchable configuration, then you @@ -432,45 +465,45 @@ Intent provided in the {@code android:searchSuggestIntentAction} attribute will column for every suggestion, or the Intent will fail.</p> + <h3 id="IntentData">Declaring Intent data</h3> -<p>When the user selects a suggestion, your searchable Activity will receive the Intent with the +<p>When the user selects a suggestion, your searchable Activity receives the Intent with the action you've defined (as discussed in the previous section), but the Intent must also carry -data in order for your Activity to identify which suggestions was selected. Specifically, +data in order for your Activity to identify which suggestion was selected. Specifically, the data should be something unique for each suggestion, such as the row ID for the suggestion in -your suggestions table. When the Intent is received, +your SQLite table. When the Intent is received, you can retrieve the attached data with {@link android.content.Intent#getData()} or {@link android.content.Intent#getDataString()}.</p> -<p>There are two ways to define the data that is included with the Intent:</p> +<p>You can define the data included with the Intent in two ways:</p> <ol type="a"> <li>Define the data for each suggestion inside the {@link -android.app.SearchManager#SUGGEST_COLUMN_INTENT_DATA} column of your suggestions table.</li> - <li>Fragment a data URI into two pieces: the portion common to all suggestions and the portion -unique to each suggestion. Place these parts into the {@code android:searchSuggestIntentData} -attribute of the searchable configuration and the {@link -android.app.SearchManager#SUGGEST_COLUMN_INTENT_DATA_ID} column of your -suggestions table, respectively.</li> -</ol> +android.app.SearchManager#SUGGEST_COLUMN_INTENT_DATA} column of your suggestions table. -<p>The first option is straight-forward. Simply provide all necessary data information for each -Intent in the suggestions table by including the {@link -android.app.SearchManager#SUGGEST_COLUMN_INTENT_DATA} column and then populating it with unique -data for each row. The data from this column will be attached to the Intent exactly as it -is found in this column. You can then retrieve it with with {@link android.content.Intent#getData()} -or {@link android.content.Intent#getDataString()}.</p> +<p>Provide all necessary data information for each Intent in the suggestions table by including the +{@link android.app.SearchManager#SUGGEST_COLUMN_INTENT_DATA} column and then populating it with +unique data for each row. The data from this column is attached to the Intent exactly as you +define it in this column. You can then retrieve it with with {@link +android.content.Intent#getData()} or {@link android.content.Intent#getDataString()}.</p> <p class="note"><strong>Tip</strong>: It's usually easiest to use the table's row ID as the -Intent data because it's always unique. And the easiest way to do that is by using the +Intent data, because it's always unique. And the easiest way to do that is by using the {@link android.app.SearchManager#SUGGEST_COLUMN_INTENT_DATA} column name as an alias for the row ID column. See the <a href="{@docRoot}resources/samples/SearchableDictionary/index.html">Searchable Dictionary sample -app</a> for an example in which {@link android.database.sqlite.SQLiteQueryBuilder} is used to -create a projection map of column names to aliases.</p> +app</a> for an example in which {@link android.database.sqlite.SQLiteQueryBuilder} creates a +projection map of column names to aliases.</p> + </li> + + <li>Fragment a data URI into two pieces: the portion common to all suggestions and the portion +unique to each suggestion. Place these parts into the {@code android:searchSuggestIntentData} +attribute of the searchable configuration and the {@link +android.app.SearchManager#SUGGEST_COLUMN_INTENT_DATA_ID} column of your +suggestions table, respectively. -<p>The second option is to fragment your data URI into the common piece and the unique piece. -Declare the piece of the URI that is common to all suggestions in the {@code +<p>Declare the piece of the URI that is common to all suggestions in the {@code android:searchSuggestIntentData} attribute of your searchable configuration. For example:</p> <pre> @@ -478,35 +511,40 @@ android:searchSuggestIntentData} attribute of your searchable configuration. For <searchable xmlns:android="http://schemas.android.com/apk/res/android" android:label="@string/app_label" android:hint="@string/search_hint" - android:searchSuggestAuthority="my.package.MySuggestionProvider" + android:searchSuggestAuthority="com.example.MyCustomSuggestionProvider" android:searchSuggestIntentAction="android.Intent.action.VIEW" - android:searchSuggestIntentData="content://my.package/datatable" > + <b>android:searchSuggestIntentData="content://com.example/datatable"</b> > </searchable> </pre> -<p>Now include the final path for each suggestion (the unique part) in the {@link +<p>Then include the final path for each suggestion (the unique part) in the {@link android.app.SearchManager#SUGGEST_COLUMN_INTENT_DATA_ID} -column of your suggestions table. When the user selects a suggestion, the Search Manager will take -the string from {@code android:searchSuggestIntentData}, append a slash ("/") and then add the +column of your suggestions table. When the user selects a suggestion, the Search Manager takes +the string from {@code android:searchSuggestIntentData}, appends a slash ("/") and then adds the respective value from the {@link android.app.SearchManager#SUGGEST_COLUMN_INTENT_DATA_ID} column to form a complete content URI. You can then retrieve the {@link android.net.Uri} with with {@link android.content.Intent#getData()}.</p> + </li> +</ol> + <h4>Add more data</h4> <p>If you need to express even more information with your Intent, you can add another table column, {@link android.app.SearchManager#SUGGEST_COLUMN_INTENT_EXTRA_DATA}, which can store additional -information about the suggestion. The data saved in this column will be placed in {@link +information about the suggestion. The data saved in this column is placed in {@link android.app.SearchManager#EXTRA_DATA_KEY} of the Intent's extra Bundle.</p> + <h2 id="HandlingIntent">Handling the Intent</h2> -<p>Now that your search dialog provides custom search suggestions with custom formatted Intents, you -need your searchable Activity to handle these Intents as they are delivered once the user selects a -suggestion. (This is, of course, in addition to handling the {@link -android.content.Intent#ACTION_SEARCH} Intent, which your searchable Activity already does.) -Accepting the new Intent is rather self-explanatory, so we'll skip straight to an example:</p> +<p>Now that your search dialog provides custom search suggestions with custom Intents, you +need your searchable Activity to handle these Intents when the user selects a +suggestion. This is in addition to handling the {@link +android.content.Intent#ACTION_SEARCH} Intent, which your searchable Activity already does. +Here's an example of how you can handle the Intents during your Activity {@link +android.app.Activity#onCreate(Bundle) onCreate()} callback:</p> <pre> Intent intent = getIntent(); @@ -515,26 +553,32 @@ if (Intent.ACTION_SEARCH.equals(intent.getAction())) { String query = intent.getStringExtra(SearchManager.QUERY); doSearch(query); } else if (Intent.ACTION_VIEW.equals(intent.getAction())) { - // Handle a suggestions click (because my suggestions all use ACTION_VIEW) - Uri data = intent.getData()); - showResult(rowId); + // Handle a suggestions click (because the suggestions all use ACTION_VIEW) + Uri data = intent.getData(); + showResult(data); } </pre> <p>In this example, the Intent action is {@link android.content.Intent#ACTION_VIEW} and the data carries a complete URI pointing to the suggested item, as synthesized by the {@code android:searchSuggestIntentData} string and {@link -android.app.SearchManager#SUGGEST_COLUMN_INTENT_DATA_ID} column. The URI is then passed to a local -method that will query the content provider for the item specified by the URI and show it.</p> +android.app.SearchManager#SUGGEST_COLUMN_INTENT_DATA_ID} column. The URI is then passed to the local +{@code showResult()} method that queries the content provider for the item specified by the URI.</p> +<p class="note"><strong>Note:</strong> You do <em>not</em> need to add an Intent filter to your +Android manifest file for the Intent action you defined with the {@code +android:searchSuggestIntentAction} attribute or {@link +android.app.SearchManager#SUGGEST_COLUMN_INTENT_ACTION} column. The Search Manager opens your +searchable Activity by name to deliver the suggestion's Intent, so the Activity does not need to +declare the accepted action.</p> <h2 id="RewritingQueryText">Rewriting the query text</h2> -<p>If the user navigates through the suggestions list using the device directional controls, the -text in the search dialog won't change, by default. However, you can temporarily rewrite the -user's query text as it appears in the text box with -a query that matches the currently selected suggestion. This enables the user to see what query is +<p>If the user navigates through the suggestions list using the directional controls (trackball or +d-pad), the text in the search dialog won't change, by default. However, you can temporarily rewrite +the user's query text as it appears in the text box with +a query that matches the suggestion currently in focus. This enables the user to see what query is being suggested (if appropriate) and then select the search box and edit the query before dispatching it as a search.</p> @@ -544,39 +588,40 @@ dispatching it as a search.</p> <li>Add the {@code android:searchMode} attribute to your searchable configuration with the "queryRewriteFromText" value. In this case, the content from the suggestion's {@link android.app.SearchManager#SUGGEST_COLUMN_TEXT_1} -column will be used to rewrite the query text.</li> +column is used to rewrite the query text.</li> <li>Add the {@code android:searchMode} attribute to your searchable configuration with the "queryRewriteFromData" value. In this case, the content from the suggestion's -{@link android.app.SearchManager#SUGGEST_COLUMN_INTENT_DATA} column will be used to rewrite the -query text. Note that this should only -be used with Uri's or other data formats that are intended to be user-visible, such as HTTP URLs. -Internal Uri schemes should not be used to rewrite the query in this way.</li> +{@link android.app.SearchManager#SUGGEST_COLUMN_INTENT_DATA} column is used to rewrite the +query text. This should only +be used with URI's or other data formats that are intended to be user-visible, such as HTTP URLs. +Internal URI schemes should not be used to rewrite the query in this way.</li> <li>Provide a unique query text string in the {@link android.app.SearchManager#SUGGEST_COLUMN_QUERY} column of your suggestions table. If this column is -present and contains a value for the current suggestion, it will be used to rewrite the query text +present and contains a value for the current suggestion, it is used to rewrite the query text (and override either of the previous implementations).</li> </ol> + <h2 id="QSB">Exposing search suggestions to Quick Search Box</h2> -<p>Once your application is configured to provide custom search suggestions, making them available -to the globally-accessible Quick Search Box is as easy as modifying your searchable configuration to +<p>Once you configure your application to provide custom search suggestions, making them available +to the globally accessible Quick Search Box is as easy as modifying your searchable configuration to include {@code android:includeInGlobalSearch} as "true".</p> -<p>The only scenario in which additional work will be required is if your content provider for -custom suggestions requires a permission for read access. In which case, you need to add a special -{@code <path-permission>} element for the provider to grant Quick Search Box read access to your -content provider. For example:</p> +<p>The only scenario in which additional work is necessary is when your content provider demands a +read permission. In which case, you need to add a special +{@code <path-permission>} element for the provider to grant Quick Search Box read access to +your content provider. For example:</p> <pre> <provider android:name="MySuggestionProvider" - android:authorities="my.package.authority" + android:authorities="com.example.MyCustomSuggestionProvider" android:readPermission="com.example.provider.READ_MY_DATA" - android:writePermission="com.example.provider.WRITE_MY_DATA"> + android:writePermission="com.example.provider.WRITE_MY_DATA"> <path-permission android:pathPrefix="/search_suggest_query" - android:readPermission="android.permission.GLOBAL_SEARCH" /> -</provider> + android:readPermission="android.permission.GLOBAL_SEARCH" /> +</provider> </pre> <p>In this example, the provider restricts read and write access to the content. The @@ -585,8 +630,8 @@ inside the {@code "/search_suggest_query"} path prefix when the {@code "android.permission.GLOBAL_SEARCH"} permission exists. This grants access to Quick Search Box so that it may query your content provider for suggestions.</p> -<p>Content providers that enforce no permissions are already available to the search -infrastructure.</p> +<p>If your content provider does not enforce read permissions, then Quick Search Box can read +it by default.</p> <h3 id="EnablingSuggestions">Enabling suggestions on a device</h3> @@ -608,89 +653,93 @@ android:searchSettingsDescription} attribute to your searchable configuration. F <searchable xmlns:android="http://schemas.android.com/apk/res/android" android:label="@string/app_label" android:hint="@string/search_hint" - android:searchSuggestAuthority="my.package.MySuggestionProvider" + android:searchSuggestAuthority="com.example.MyCustomSuggestionProvider" android:searchSuggestIntentAction="android.Intent.action.VIEW" android:includeInGlobalSearch="true" - android:searchSettingsDescription="@string/search_description" > + <b>android:searchSettingsDescription="@string/search_description"</b> > </searchable> </pre> <p>The string for {@code android:searchSettingsDescription} should be as concise as possible and state the content that is searchable. For example, "Artists, albums, and tracks" for a music application, or "Saved notes" for a notepad application. Providing this description is important so -the user knows what kind of suggestions will be provided. This attribute should always be included +the user knows what kind of suggestions are provided. You should always include this attribute when {@code android:includeInGlobalSearch} is "true".</p> -<p>Remember that the user must visit this settings menu to enable search suggestions for your -application before your search suggestions will appear in Quick Search Box. As such, if search is an -important aspect of your application, then you may want to consider a way to message this to your -users — perhaps with a note the first time they launch the app about how to enable search -suggestions for Quick Search Box.</p> +<p>Remember that the user must visit the settings menu to enable search suggestions for your +application before your search suggestions appear in Quick Search Box. As such, if search is an +important aspect of your application, then you might want to consider a way to convey that to +your users — you might provide a note the first time they launch the app that instructs +them how to enable search suggestions for Quick Search Box.</p> <h3 id="ManagingShortcuts">Managing Quick Search Box suggestion shortcuts</h3> -<p>Suggestions that the user selects from Quick Search Box may be automatically made into shortcuts. +<p>Suggestions that the user selects from Quick Search Box can be automatically made into shortcuts. These are suggestions that the Search Manager has copied from your content provider so it can quickly access the suggestion without the need to re-query your content provider. </p> <p>By default, this is enabled for all suggestions retrieved by Quick Search Box, but if your -suggestion data may change over time, then you can request that the shortcuts be refreshed. For +suggestion data changes over time, then you can request that the shortcuts be refreshed. For instance, if your suggestions refer to dynamic data, such as a contact's presence status, then you should request that the suggestion shortcuts be refreshed when shown to the user. To do so, include the {@link android.app.SearchManager#SUGGEST_COLUMN_SHORTCUT_ID} in your suggestions table. Using this column, you can -configure the shortcut behavior for each suggestion in the following ways:</p> +configure the shortcut behavior for each suggestion in one of the following ways:</p> <ol type="a"> - <li>Have Quick Search Box re-query your content provider for a fresh version of the shortcutted -suggestion. + <li>Have Quick Search Box re-query your content provider for a fresh version of the suggestion +shortcut. <p>Provide a value in the {@link android.app.SearchManager#SUGGEST_COLUMN_SHORTCUT_ID} column -and the suggestion will be -re-queried for a fresh version of the suggestion each time the shortcut is displayed. The shortcut -will be quickly displayed with whatever data was most recently available until the refresh query -returns, after which the suggestion will be dynamically refreshed with the new information. The -refresh query will be sent to your content provider with a URI path of {@link +and the suggestion is +re-queried for a fresh version each time the shortcut is displayed. The shortcut +is quickly displayed with whatever data was most recently available until the refresh query +returns, at which point the suggestion is refreshed with the new information. The +refresh query is sent to your content provider with a URI path of {@link android.app.SearchManager#SUGGEST_URI_PATH_SHORTCUT} -(instead of {@link android.app.SearchManager#SUGGEST_URI_PATH_QUERY}). The Cursor you return should -contain one suggestion using the +(instead of {@link android.app.SearchManager#SUGGEST_URI_PATH_QUERY}).</p> + <p>The {@link android.database.Cursor} you return should contain one suggestion using the same columns as the original suggestion, or be empty, indicating that the shortcut is no -longer valid (in which case, the suggestion will disappear and the shortcut will be removed).</p> - <p>If a suggestion refers to data that could take longer to refresh, such as a network based -refresh, you may also add the {@link +longer valid (in which case, the suggestion disappears and the shortcut is removed).</p> + <p>If a suggestion refers to data that could take longer to refresh, such as a network-based +refresh, you can also add the {@link android.app.SearchManager#SUGGEST_COLUMN_SPINNER_WHILE_REFRESHING} column to your suggestions table with a value of "true" in order to show a progress spinner for the right hand icon until the refresh is complete. -(Any value other than "true" will not show the progress spinner.)</p></li> +Any value other than "true" does not show the progress spinner.</p> + </li> + <li>Prevent the suggestion from being copied into a shortcut at all. <p>Provide a value of {@link android.app.SearchManager#SUGGEST_NEVER_MAKE_SHORTCUT} in the {@link android.app.SearchManager#SUGGEST_COLUMN_SHORTCUT_ID} column. In -this case, the suggestion will never be copied into a shortcut. This should only be necessary if you -absolutely do not want the previously copied suggestion to appear at all. (Recall that if you -provide a normal value for the column then the suggestion shortcut will appear only until the +this case, the suggestion is never copied into a shortcut. This should only be necessary if you +absolutely do not want the previously copied suggestion to appear. (Recall that if you +provide a normal value for the column, then the suggestion shortcut appears only until the refresh query returns.)</p></li> <li>Allow the default shortcut behavior to apply. - <p>Simply leave the {@link android.app.SearchManager#SUGGEST_COLUMN_SHORTCUT_ID} empty for each + <p>Leave the {@link android.app.SearchManager#SUGGEST_COLUMN_SHORTCUT_ID} empty for each suggestion that will not change and can be saved as a shortcut.</p></li> </ol> -<p>Of course, if none of your suggestions will ever change, then you do not need the +<p>If none of your suggestions ever change, then you do not need the {@link android.app.SearchManager#SUGGEST_COLUMN_SHORTCUT_ID} column at all.</p> -<p class="note"><strong>Note</strong>: Quick Search Box will ultimately decide whether to shortcut -your app's suggestions, considering these values as a strong request from your application.</p> +<p class="note"><strong>Note</strong>: Quick Search Box ultimately decides whether or not to create +a shortcut for a suggestion, considering these values as a strong request from your +application—there is no guarantee that the behavior you have requested for your suggestion +shortcuts will be honored.</p> <h3 id="AboutRanking">About Quick Search Box suggestion ranking</h3> -<p>Once your application's search results are made available to Quick Search Box, how they surface -to the user for a particular query will be determined as appropriate by Quick Search Box ranking. -This may depend on how many other apps have results for that query, and how often the user has -selected on your results compared to those of the other apps. There is no guarantee about how -ranking will occur, or whether your app's suggestions will show at all for a given query. In -general, you can expect that providing quality results will increase the likelihood that your app's -suggestions are provided in a prominent position, and apps that provide lower quality suggestions -will be more likely to be ranked lower and/or not displayed.</p> +<p>Once you make your application's search suggestions available to Quick Search Box, the Quick +Search Box ranking determines how the suggestions are surfaced to the user for a particular query. +This might depend on how many other apps have results for that query, and how often the user has +selected your results compared to those from other apps. There is no guarantee about how your +suggestions are ranked, or whether your app's suggestions show at all for a given query. In +general, you can expect that providing quality results increases the likelihood that your app's +suggestions are provided in a prominent position and apps that provide low quality suggestions +are more likely to be ranked lower or not displayed.</p> <div class="special"> <p>See the <a href="{@docRoot}resources/samples/SearchableDictionary/index.html">Searchable diff --git a/docs/html/guide/topics/search/adding-recent-query-suggestions.jd b/docs/html/guide/topics/search/adding-recent-query-suggestions.jd index 37e0e82..cb063a1 100644 --- a/docs/html/guide/topics/search/adding-recent-query-suggestions.jd +++ b/docs/html/guide/topics/search/adding-recent-query-suggestions.jd @@ -5,20 +5,22 @@ parent.link=index.html <div id="qv-wrapper"> <div id="qv"> -<h2>Key classes</h2> -<ol> -<li>{@link android.provider.SearchRecentSuggestions}</li> -<li>{@link android.content.SearchRecentSuggestionsProvider}</li> -</ol> <h2>In this document</h2> <ol> <li><a href="#TheBasics">The Basics</a></li> -<li><a href="#RecentQuerySearchableConfiguration">Modifying the searchable -configuration</a></li> <li><a href="#RecentQueryContentProvider">Creating a Content Provider</a></li> -<li><a href="#SavingQueries">Saving queries</a></li> -<li><a href="#ClearingSuggestionData">Clearing the suggestion data</a></li> +<li><a href="#RecentQuerySearchableConfiguration">Modifying the Searchable +Configuration</a></li> +<li><a href="#SavingQueries">Saving Queries</a></li> +<li><a href="#ClearingSuggestionData">Clearing the Suggestion Data</a></li> </ol> + +<h2>Key classes</h2> +<ol> +<li>{@link android.provider.SearchRecentSuggestions}</li> +<li>{@link android.content.SearchRecentSuggestionsProvider}</li> +</ol> + <h2>See also</h2> <ol> <li><a href="searchable-config.html">Searchable Configuration</a></li> @@ -26,99 +28,76 @@ configuration</a></li> </div> </div> -<p>The Android search framework provides the ability for your application to -provide suggestions while the user types into the Android search dialog. In this guide, you'll learn -how to create recent query suggestions. These are suggestions based -on queries previously entered by the user. So, if the user previously searched for "puppies" then it -will appear as a suggestion as they begin typing the same string of text. The screenshot below -shows an example of recent query suggestions.</p> +<p>When using the Android search dialog, you can provide search suggestions based on recent search +queries. For example, if a user previously searched for "puppies," then that query appears as a +suggestion once he or she begins typing the same query. Figure 1 shows an example of a search dialog +with recent query suggestions.</p> + +<p>Before you begin, you need to implement the search dialog for basic searches in your application. +If you haven't, see <a href="search-dialog.html">Using the Android Search Dialog</a>.</p> -<p>Before you begin, you need to have implemented the Android search dialog for searches in your -application. If you haven't done this, see <a href="search-dialog.html">Using the Android Search -Dialog</a>.</p> <h2 id="TheBasics">The Basics</h2> -<img src="{@docRoot}images/search/search-suggest-recent-queries.png" alt="" height="417" -style="float:right;clear:right;" /> +<div class="figure" style="width:250px"> +<img src="{@docRoot}images/search/search-suggest-recent-queries.png" alt="" height="417" /> +<p class="img-caption"><strong>Figure 1.</strong> Screenshot of a search dialog with recent query +suggestions.</p> +</div> <p>Recent query suggestions are simply saved searches. When the user selects one of -the suggestions, your searchable Activity will receive a normal {@link +the suggestions, your searchable Activity receives a {@link android.content.Intent#ACTION_SEARCH} Intent with the suggestion as the search query, which your -searchable Activity will already handle.</p> +searchable Activity already handles (as described in <a href="search-dialog.html">Using the Android +Search Dialog</a>).</p> <p>To provide recent queries suggestions, you need to:</p> <ul> - <li>Implement a basic searchable Activity, as documented in <a -href="{@docRoot}guide/topics/search/search-dialog.html">Using the Android Search Dialog</a>.</li> + <li>Implement a searchable Activity, <a +href="{@docRoot}guide/topics/search/search-dialog.html">using the Android Search Dialog</a>.</li> <li>Create a content provider that extends {@link android.content.SearchRecentSuggestionsProvider} and declare it in your application manifest.</li> - <li>Modify the searchable configuration with information about the content provider.</li> - <li>Save queries to your content provider each time a search is made.</li> + <li>Modify the searchable configuration with information about the content provider that +provides search suggestions.</li> + <li>Save queries to your content provider each time a search is executed.</li> </ul> -<p>Just like the Search Manager handles the rendering of the search dialog, it will also do the work -to display all search suggestions below the search dialog. All you need to do is provide a source -from which the suggestions can be retrieved.</p> +<p>Just as the Search Manager displays the search dialog, it also displays the +search suggestions. All you need to do is provide a source from which the suggestions can be +retrieved.</p> -<p>When the Search Manager identifies that your Activity is searchable and also provides search -suggestions, the following procedure will take place as soon as the user types into the Android -search box:</p> +<p>When the Search Manager identifies that your Activity is searchable and provides search +suggestions, the following procedure takes place as soon as the user types into the search +dialog:</p> -<ul> - <li>The Search Manager takes the search query text (whatever has been typed so far) and performs a -query to the content provider that manages your suggestions.</li> - <li>Your content provider then returns a {@link android.database.Cursor} that points to all -suggestions that are relevant to the search query text.</li> - <li>The Search Manager then displays the list of suggestions provided by the Cursor (as -demonstrated in the screenshot to the right).</li> -</ul> +<ol> + <li>Search Manager takes the search query text (whatever has been typed so far) and performs a +query to the content provider that contains your suggestions.</li> + <li>Your content provider returns a {@link android.database.Cursor} that points to all +suggestions that match the search query text.</li> + <li>Search Manager displays the list of suggestions provided by the Cursor.</li> +</ol> -<p>At this point, the following may happen:</p> +<p>Once the recent query suggestions are displayed, the following might happen:</p> <ul> - <li>If the user types another key, or changes the query in any way, the above steps are repeated -and the suggestion list is updated as appropriate.</li> + <li>If the user types another key, or changes the query in any way, the aforementioned steps are +repeated and the suggestion list is updated.</li> <li>If the user executes the search, the suggestions are ignored and the search is delivered to your searchable Activity using the normal {@link android.content.Intent#ACTION_SEARCH} Intent.</li> - <li>If the user selects a suggestion, a normal -{@link android.content.Intent#ACTION_SEARCH} Intent is triggered, using the suggested text as the -query.</li> + <li>If the user selects a suggestion, an +{@link android.content.Intent#ACTION_SEARCH} Intent is delivered to your searchable Activity using +the suggested text as the query.</li> </ul> -<p>As you'll soon discover, the {@link android.content.SearchRecentSuggestionsProvider} class that -you'll extend for your content provider will automatically do the work described above, so there's +<p>The {@link android.content.SearchRecentSuggestionsProvider} class that +you extend for your content provider automatically does the work described above, so there's actually very little code to write.</p> -<h2 id="RecentQuerySearchableConfiguration">Modifying the searchable configuration</h2> - -<p>First, you need to add the {@code android:searchSuggestAuthority} and -{@code android:searchSuggestSelection} attributes to the {@code <searchable>} element in your -searchable configuration file. 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" - android:searchSuggestAuthority="my.package.MySuggestionProvider" - android:searchSuggestSelection=" ?" > -</searchable> -</pre> - -<p>The value for {@code android:searchSuggestAuthority} should be a fully-qualified name for -your content provider: your application package name followed by the name of your content provider. -This string must match the authority used in the content provider (discussed in the next section). -</p> - -<p>The value for {@code android:searchSuggestSelection} must be a single question-mark, preceded by -a space (" ?"), which is simply a placeholder for the SQLite selection argument (which will be -automatically replaced by the query text entered by the user).</p> - <h2 id="RecentQueryContentProvider">Creating a Content Provider</h2> @@ -131,7 +110,7 @@ suggestions:</p> <pre> public class MySuggestionProvider extends SearchRecentSuggestionsProvider { - public final static String AUTHORITY = "my.package.MySuggestionProvider"; + public final static String AUTHORITY = "com.example.MySuggestionProvider"; public final static int MODE = DATABASE_MODE_QUERIES; public MySuggestionProvider() { @@ -140,41 +119,72 @@ public class MySuggestionProvider extends SearchRecentSuggestionsProvider { } </pre> -<p>The call to {@link android.content.SearchRecentSuggestionsProvider#setupSuggestions(String,int)} -passes the name of the search authority (matching the one in the searchable configuration) and a -database mode. The database mode must include {@link +<p>The call to {@link android.content.SearchRecentSuggestionsProvider#setupSuggestions(String,int) +setupSuggestions()} passes the name of the search authority and a +database mode. The search authority can be any unique string, but the best practice is to use a +fully qualified name for your content provider +(package name followed by the provider's class name; for example, +"com.example.MySuggestionProvider"). The database mode must include {@link android.content.SearchRecentSuggestionsProvider#DATABASE_MODE_QUERIES} and can optionally include {@link -android.content.SearchRecentSuggestionsProvider#DATABASE_MODE_2LINES}, which will add another column +android.content.SearchRecentSuggestionsProvider#DATABASE_MODE_2LINES}, which adds another column to the suggestions table that allows you to provide a second line of text with each suggestion. For -example:</p> +example, if you want to provide two lines in each suggestion:</p> + <pre> public final static int MODE = DATABASE_MODE_QUERIES | DATABASE_MODE_2LINES; </pre> -<p>In the following section, you'll see how to save both lines of text.</p> - -<p>Now simply declare the content provider in your application manifest with the same authority -string used in the class (and in the searchable configuration). For example:</p> +<p>Now declare the content provider in your application manifest with the same authority +string used in your {@link android.content.SearchRecentSuggestionsProvider} class (and in the +searchable configuration). For example:</p> <pre> <application> <provider android:name=".MySuggestionProvider" - android:authorities="my.package.authority" /> + android:authorities="com.example.MySuggestionProvider" /> ... </application> </pre> -<h2 id="SavingQueries">Saving queries</h2> -<p>In order to populate your collection of recent queries, you need to add each query -received by your searchable Activity to the content provider you've just built. To do this, create -an instance of {@link +<h2 id="RecentQuerySearchableConfiguration">Modifying the Searchable Configuration</h2> + +<p>To configure your search dialog to use your suggestions provider, you need to add +the {@code android:searchSuggestAuthority} and {@code android:searchSuggestSelection} attributes to +the {@code <searchable>} element in your searchable configuration file. 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" + <b>android:searchSuggestAuthority="com.example.MySuggestionProvider" + android:searchSuggestSelection=" ?"</b> > +</searchable> +</pre> + +<p>The value for {@code android:searchSuggestAuthority} should be a fully qualified name for +your content provider that exactly matches the authority used in the content provider (the {@code +AUTHORITY} string in the above example). +</p> + +<p>The value for {@code android:searchSuggestSelection} must be a single question mark, preceded by +a space ({@code " ?"}), which is simply a placeholder for the SQLite selection argument (which is +automatically replaced by the query text entered by the user).</p> + + + +<h2 id="SavingQueries">Saving Queries</h2> + +<p>To populate your collection of recent queries, add each query +received by your searchable Activity to your {@link +android.content.SearchRecentSuggestionsProvider}. To do this, create an instance of {@link android.provider.SearchRecentSuggestions} and call {@link -android.provider.SearchRecentSuggestions#saveRecentQuery(String,String)} each time your searchable -Activity receives a query. For example, here's how you can save the query during your -Activity's {@link android.app.Activity#onCreate(Bundle) onCreate()} method:</p> +android.provider.SearchRecentSuggestions#saveRecentQuery(String,String) saveRecentQuery()} each time +your searchable Activity receives a query. For example, here's how you can save the query during +your Activity's {@link android.app.Activity#onCreate(Bundle) onCreate()} method:</p> <pre> @Override @@ -193,24 +203,24 @@ public void onCreate(Bundle savedInstanceState) { } </pre> -<p>Notice that the {@link android.content.SearchRecentSuggestionsProvider} constructor requires the +<p>The {@link android.content.SearchRecentSuggestionsProvider} constructor requires the same authority and database mode declared by your content provider.</p> -<p>The {@link android.provider.SearchRecentSuggestions#saveRecentQuery(String,String)} method takes +<p>The {@link android.provider.SearchRecentSuggestions#saveRecentQuery(String,String) +saveRecentQuery()} method takes the search query string as the first parameter and, optionally, a second string to include as the -second line of the suggestion. The second parameter is only used if you've enabled two-line mode -for the search suggestions with {@link +second line of the suggestion (or null). The second parameter is only used if you've enabled +two-line mode for the search suggestions with {@link android.content.SearchRecentSuggestionsProvider#DATABASE_MODE_2LINES}. If you have enabled -two-line mode, then the query text will be matched against this second line as well.</p> +two-line mode, then the query text is also matched against this second line when the Search Manager +looks for matching suggestions.</p> -<p>That's all that's needed to build a recent queries suggestion provider. However, there's one -other important thing to do: provide the ability for the user to clear this search history.</p> -<h2 id="ClearingSuggestionData">Clearing the suggestion data</h2> +<h2 id="ClearingSuggestionData">Clearing the Suggestion Data</h2> <p>To protect the user's privacy, you should always provide a way for the user to clear the recent -query suggestions. To clear the recent queries, simply call {@link +query suggestions. To clear the query history, call {@link android.provider.SearchRecentSuggestions#clearHistory()}. For example:</p> <pre> @@ -219,7 +229,7 @@ SearchRecentSuggestions suggestions = new SearchRecentSuggestions(this, suggestions.clearHistory(); </pre> -<p>Simply execute this from your choice of a "Clear Search History" menu item, -preference item, or button. You should also provide a confirmation dialog when this is pressed, to +<p>Execute this from your choice of a "Clear Search History" menu item, +preference item, or button. You should also provide a confirmation dialog to verify that the user wants to delete their search history.</p> diff --git a/docs/html/guide/topics/search/index.jd b/docs/html/guide/topics/search/index.jd index b2252bb..78e0be2 100644 --- a/docs/html/guide/topics/search/index.jd +++ b/docs/html/guide/topics/search/index.jd @@ -13,98 +13,96 @@ page.title=Search <ol> <li><a href="searchable-config.html">Searchable Configuration</a></li> </ol> -<h2>See also</h2> +<h2>Related Samples</h2> <ol> <li><a href="{@docRoot}resources/samples/SearchableDictionary/index.html">Searchable -Dictionary sample app</a></li> +Dictionary</a></li> </ol> </div> </div> -<p>The ability to search is considered to be a core user feature on Android. The user should be able -to search any data that is available to them, whether the content is located on the device or the -Internet. This experience should be seamless and consistent across the entire -system, which is why Android provides a simple search framework to help you provide users with +<p>Search is a core user feature on Android. Users should be able +to search any data that is available to them, whether the content is located on the device or +the Internet. The search experience should be seamless and consistent across the entire +system, which is why Android provides a search framework to help you provide users with a familiar search dialog and a great search experience.</p> -<img src="{@docRoot}images/search/search-suggest-custom.png" alt="" height="417" -style="float:right;clear:right;" /> +<div class="figure" style="width:250px"> +<img src="{@docRoot}images/search/search-suggest-custom.png" alt="" height="417" /> +<p class="img-caption"><strong>Figure 1.</strong> Screenshot of a search dialog with custom +search suggestions.</p> +</div> + +<p>Android's search framework provides a user interface in which users can perform a search and +an interaction layer that communicates with your application, so you don't have to build +your own search Activity. Instead, a search dialog appears at the top of the screen at the user's +command without interrupting the current Activity.</p> -<p>Android's search framework provides a user interface in which the user can perform a search and -an interaction layer that communicates with your application. This way, you don't have to build -a search box that the user must find in order to begin a search. Instead, -a custom search dialog will appear at the top of the screen at the user's command. -The search framework will manage the search dialog and when the user executes their search, the -search framework will pass the query text to your application so that your application can begin a -search. The screenshot to the right shows an example of the search dialog (using -search suggestions).</p> +<p>The search framework manages the life of the search dialog. When users execute a search, the +search framework passes the query text to your application so your application can perform a +search. Figure 1 shows an example of the search dialog with optional search suggestions.</p> <p>Once your application is set up to use the search dialog, you can:</p> <ul> -<li>Customize some of the search dialog characteristics</li> <li>Enable voice search</li> <li>Provide search suggestions based on recent user queries</li> -<li>Provide search suggestions that match actual results in your application data</li> +<li>Provide custom search suggestions that match actual results in your application data</li> <li>Offer your application's search suggestions in the system-wide Quick Search Box</li> </ul> -<p>The following documents will teach you how to use the search dialog in -your application:</p> +<p class="note"><strong>Note</strong>: The search framework does <em>not</em> provide APIs to +search your data. To perform a search, you need to use APIs appropriate for your data. For example, +if your data is stored in an SQLite database, you should use the {@link android.database.sqlite} +APIs to perform searches.</p> + +<p>The following documents show you how to use the search dialog in your application:</p> <dl> <dt><strong><a href="search-dialog.html">Using the Android Search Dialog</a></strong></dt> - <dd>How to set up your application to use the search dialog for searches. </dd> + <dd>How to set up your application to use the search dialog. </dd> <dt><strong><a href="adding-recent-query-suggestions.html">Adding Recent Query Suggestions</a></strong></dt> <dd>How to show suggestions based on queries previously used in the search dialog.</dd> <dt><strong><a href="adding-custom-suggestions.html">Adding Custom Suggestions</a></strong></dt> <dd>How to show suggestions based on custom data from your application and offer your suggestions in the system-wide Quick Search Box.</dd> + <dt><strong><a href="searchable-config.html">Searchable Configuration</a></strong></dt> + <dd>A reference for the searchable configuration file (though the other +documents also discuss the configuration file in terms of specific behaviors).</dd> </dl> -<p>Also, the <strong><a href="searchable-config.html">Searchable Configuration</a></strong> document -provides a reference for the searchable configuration file (though the above -documents also discuss the configuration file in terms of specific behaviors).</p> - -<p class="note"><strong>Note</strong>: The search framework does <em>not</em> provide APIs to -perform searches on your data. Performing actual searches is a task that you must accomplish -using APIs appropriate for your data, such as those in {@link android.database.sqlite} -if your data is in an SQLite database.</p> - <h2>Protecting User Privacy</h2> -<p>When you implement search in your application, you should take steps to protect the user's -privacy whenever possible. Many users consider their activities on the phone, including searches, to -be private information. To protect the user's privacy, you should abide by the following +<p>When you implement search in your application, take steps to protect the user's +privacy. Many users consider their activities on the phone—including searches—to +be private information. To protect each user's privacy, you should abide by the following principles:</p> <ul> -<li><strong>Don't send personal information to servers, and if you do, don't log it.</strong> -<p>"Personal information" is information that can personally identify your users, such as their -name, email address, billing information, or other data which can be reasonably linked to such -information. If -your application implements search with the assistance of a server, try to avoid sending personal -information along with the search queries. For example, if you are searching for businesses near a -zip code, -you don't need to send the user ID as well — send only the zip code to the server. If you must -send the personal information, you should take steps to avoid logging it. If you must log it, you -should protect that data very carefully and erase it as soon as possible.</p> +<li><strong>Don't send personal information to servers, but if you must, do not log it.</strong> +<p>Personal information is any information that can personally identify your users, such as their +names, email addresses, billing information, or other data that can be reasonably linked to such +information. If your application implements search with the assistance of a server, avoid sending +personal information along with the search queries. For example, if you are searching for businesses +near a zip code, +you don't need to send the user ID as well; send only the zip code to the server. If you must +send the personal information, you should not log it. If you must log it, protect that data +very carefully and erase it as soon as possible.</p> </li> <li><strong>Provide the user with a way to clear their search history.</strong> -<p>The search framework helps your application provide context-specific suggestions while they type. -Sometimes these -suggestions are based on previous searches, or other actions taken by the user in an earlier -session. A user may not wish for previous searches to be revealed to other users, for instance if -they share their phone with a friend. If your application provides suggestions that can reveal -previous activities, you should implement a "Clear History" menu item, preference, or button. If you -are -using {@link android.provider.SearchRecentSuggestions}, you can simply call its {@link -android.provider.SearchRecentSuggestions#clearHistory()} method. If you are implementing custom -suggestions, you'll need to provide a -similar "clear history" method in your provider that can be invoked by the user.</p> +<p>The search framework helps your application provide context-specific suggestions while the user +types. Sometimes these +suggestions are based on previous searches or other actions taken by the user in an earlier +session. A user might not wish for previous searches to be revealed to other device users, for +instance, if they share their phone with a friend. If your application provides suggestions that can +reveal previous activities, you should implement the ability for the user to clear the search +history. If you are using {@link android.provider.SearchRecentSuggestions}, you can simply call the +{@link android.provider.SearchRecentSuggestions#clearHistory()} method. If you are implementing +custom suggestions, you'll need to provide a similar "clear history" method in your provider that +the user can execute.</p> </li> </ul> diff --git a/docs/html/guide/topics/search/search-dialog.jd b/docs/html/guide/topics/search/search-dialog.jd index a5f99c7..49c6627 100644 --- a/docs/html/guide/topics/search/search-dialog.jd +++ b/docs/html/guide/topics/search/search-dialog.jd @@ -5,10 +5,6 @@ parent.link=index.html <div id="qv-wrapper"> <div id="qv"> -<h2>Key classes</h2> -<ol> -<li>{@link android.app.SearchManager}</li> -</ol> <h2>In this document</h2> <ol> <li><a href="#TheBasics">The Basics</a></li> @@ -27,64 +23,81 @@ parent.link=index.html <li><a href="#SearchContextData">Passing Search Context Data</a></li> <li><a href="#VoiceSearch">Adding Voice Search</a></li> </ol> + +<h2>Key classes</h2> +<ol> +<li>{@link android.app.SearchManager}</li> +</ol> + +<h2>Related Samples</h2> +<ol> +<li><a href="{@docRoot}resources/samples/SearchableDictionary/index.html">Searchable +Dictionary</a></li> +</ol> + +<h2>Downloads</h2> +<ol> +<li><a href="{@docRoot}shareables/search_icons.zip">search_icons.zip</a></li> +</ol> + <h2>See also</h2> <ol> <li><a href="adding-recent-query-suggestions.html">Adding Recent Query Suggestions</a></li> <li><a href="adding-custom-suggestions.html">Adding Custom Suggestions</a></li> <li><a href="searchable-config.html">Searchable Configuration</a></li> -<li><a href="{@docRoot}resources/samples/SearchableDictionary/index.html">Searchable -Dictionary App</a></li> </ol> + </div> </div> -<p>When you want to provide search in your application, the last thing you should have to worry -about is where to put your search box. By using the Android search framework, your application will -reveal a custom search dialog whenever the user requests it. At the -press of a dedicated search key or an API call from your application, the search dialog will -appear at the top of the screen and will automatically show your application icon. An example is -shown in the screenshot below.</p> +<p>When you want to implement search in your application, the last thing you should have to worry +about is where to put the search box. When you implement search with the Android search framework, +you don't have to. When the user invokes search, a search dialog appears at the top of the screen +with your application icon to the left of the search box. When the user executes the search, your +application receives the query so it can search your application's data. An example of the search +dialog is shown in figure 1.</p> -<p>This guide will teach you how to set up your application to provide search in a custom search -dialog. In doing so, you will provide a standardized search experience and be able to add -features like voice search and search suggestions.</p> +<p>This guide shows you how to set up your application to provide search in the search +dialog. When you use the search dialog, you provide a standardized search +experience and can add features such as voice search and search suggestions.</p> <h2 id="TheBasics">The Basics</h2> -<img src="{@docRoot}images/search/search-ui.png" alt="" height="417" -style="float:right;clear:right;" /> +<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>The Android search framework will manage the search dialog on your behalf; you never need -to draw it or worry about where it is, and your current Activity will not be -interrupted. The {@link android.app.SearchManager} is the component that does this work for -you (hereafter, referred to as "the Search Manager"). It manages the life of the Android search -dialog and will send your application the search query when executed by the user.</p> +<p>The Android search framework manages the search dialog for your application. You never need +to draw it or worry about where it is, and your Activity is not interrupted when the search dialog +appears. The Search Manager ({@link android.app.SearchManager}) is the component that does this work +for you. It manages the life of the search dialog and sends your application the user's search +query.</p> -<p>When the user executes a search, the Search Manager will use a specially-formed Intent to pass -the search query to the Activity that you've declared to handle searches. Essentially, all you -need is an Activity that receives this Intent, performs the search, and presents the results. -Specifically, what you need is the following:</p> +<p>When the user executes a search, the Search Manager creates an {@link android.content.Intent} to +pass the search query to the Activity that you've declared to handle searches. Basically, all you +need is an Activity that receives the search Intent, performs the search, and presents the results. +Specifically, you need the following:</p> <dl> <dt>A searchable configuration</dt> - <dd>This is an XML file that configures the search dialog and includes settings for -features such as the hint text shown in text box and settings voice search and search -suggestion.</dd> + <dd>An XML file that configures the search dialog and includes settings for features such as voice +search, search suggestion, and the hint text.</dd> <dt>A searchable Activity</dt> - <dd>This is the {@link android.app.Activity} that receives the search query then -searches your data and displays the search results.</dd> + <dd>The {@link android.app.Activity} that receives the search query, then searches your data and +displays the search results.</dd> <dt>A mechanism by which the user can invoke search</dt> - <dd>By default, the device search key (if available) will invoke the search dialog once -you've configured a searchable Activity. However, you should always provide another means by -which the user can invoke a search, such as with a search button in the Options Menu or elsewhere in -the Activity UI, because not all devices provide a dedicated search key.</dd> + <dd>The device search key invokes the search dialog, by default. However, a dedicated search key +is not guaranteed on all devices, so provide another means by which the user can invoke a search, +such as a search button in the Options Menu or elsewhere in the Activity UI.</dd> </dl> + <h2 id="SearchableConfiguration">Creating a Searchable Configuration</h2> -<p>The searchable configuration is an XML file that defines several settings for the Android search +<p>The searchable configuration is an XML file that defines several settings for the search dialog in your application. This file is traditionally named {@code searchable.xml} and must be saved in the {@code res/xml/} project directory.</p> @@ -94,45 +107,61 @@ or more attributes that configure your search dialog. 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:label="@string/app_label" + android:hint="@string/search_hint" > </searchable> </pre> -<p>This is the minimum configuration required in order to provide the search dialog. The {@code -android:label} attribute is the only required attribute and points to a string resource, which -should normally be the same as the application. (Although it's required, this -label isn't actually shown to the user until you enable suggestions for Quick Search Box.)</p> +<p>The {@code android:label} attribute is the only required attribute and points to a string +resource, which should be the same as the application name. This label isn't actually visible to the +user until you enable suggestions for Quick Search Box, at which point, this label is visible in the +list of Searchable items in the system Settings.</p> -<p>There are several other attributes accepted by the {@code <searchable>} element. Most of -which apply only when configuring features such as search suggestions and voice -search. However, we recommend that you always include the {@code android:hint} attribute, which -specifies a string resource for the text to display in the search dialog's text box before the user -enters their query—it provides important clues to the user about what they can search. </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 dialog's text box before the user +enters their 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 <em><content-or-product></em>". For example, "Search songs and artists" or "Search YouTube".</p> -<p>Next, you'll hook this configuration into your application.</p> +<p>The {@code <searchable>} element accepts several other attributes. Most attributes apply +only when configuring features such as search suggestions and voice search.</p> + +<p>For more details about the searchable configuration file, see the <a +href="{@docRoot}guide/topics/search/searchable-config.html">Searchable Configuration</a> +reference.</p> + <h2 id="SearchableActivity">Creating a Searchable Activity</h2> -<p>When the user executes a search from the search dialog, the Search Manager will send -your searchable {@link android.app.Activity} the search query with the {@link -android.content.Intent#ACTION_SEARCH} {@link android.content.Intent}. Your searchable Activity will -then search your data and present the results.</p> +<p>When the user executes a search from the search dialog, the Search Manager takes the query +and sends it to your searchable {@link android.app.Activity} in the {@link +android.content.Intent#ACTION_SEARCH} {@link android.content.Intent}. Your searchable Activity +then searches your data using the query and presents the results to the user.</p> + +<p>In order for the Search Manager to know where to deliver the search query, you must 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 be used to -perform searches, then declare it to -accept the {@link android.content.Intent#ACTION_SEARCH} {@link android.content.Intent} and apply the -searchable configuration. To do so, you need to add an {@code -<intent-filter>} element and a {@code <meta-data>} element to the -appropriate {@code <activity>} element in your manifest file. For example:</p> +<p>If you don't have one already, create an {@link android.app.Activity} that performs +searches and present search results. To set up this Activity as your searchable Activity:</p> +<ol> + <li>Declare the Activity to accept the {@link android.content.Intent#ACTION_SEARCH} {@link +android.content.Intent}, in an <a +href="{@docRoot}guide/topics/manifest/intent-filter-element.html">{@code <intent-filter>}</a> +element.</li> + <li>Apply the searchable configuration, 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 ... > @@ -147,29 +176,27 @@ appropriate {@code <activity>} element in your manifest file. For example: </application> </pre> -<p>The {@code android:name} attribute in the {@code <meta-data>} element must be defined with -{@code "android.app.searchable"} and the {@code android:resource} attribute value must be a -reference to the searchable configuration file saved in {@code res/xml} (in this example, it +<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">If you're wondering why the {@code -<intent-filter>} does not include a {@code <category>} with the {@code DEFAULT} -value, it's because the Intent that is delivered to this Activity when a search is executed will -explicitly define this Activity as the component for the Intent (which the Search Manager knows -from the searcahble meta-data declared for the Activity).</p> +<p class="note"><strong>Note:</strong> The {@code <intent-filter>} does not need a <a +href="{@docRoot}guide/topics/manifest/category-element.html">{@code <category>}</a> with the +{@code DEFAULT} value, because the Search Manager delivers the {@link +android.content.Intent#ACTION_SEARCH} Intent explicitly to your searchable Activity by name.</p> -<p>Be aware that the search dialog will not be available from within every -Activity of your application, by default. Rather, the search dialog will be presented to -users only when they +<p>The search dialog is not, by default, available from every Activity of your +application. Rather, the search dialog is presented to users only when they invoke search from a searchable context of your application. A searchable context is any Activity for which you have declared searchable meta-data in the manifest file. For example, the searchable Activity itself (declared in the manifest snippet above) is -a searchable context because it contains searchable meta-data that defines the +a searchable context because it includes meta-data that defines the searchable configuration. Any other Activity in your application is not a searchable context, by -default, and thus, will not reveal the search dialog. You probably do want the -search dialog to be available from every Activity in your application, so this can be easily -fixed.</p> +default, and thus, does not reveal the search dialog. However, you probably do want the search +dialog available from your other activities (and to launch the searchable Activity when the user +executes a search). You can do exactly that.</p> <p>If you want all of your activities to provide the search dialog, add another {@code <meta-data>} element inside the {@code @@ -187,9 +214,9 @@ default searchable Activity. For example:</p> </activity> <activity android:name=".AnotherActivity" ... > </activity> - <!-- this one declares the searchable Activity for the whole app --> - <meta-data android:name="android.app.default_searchable" - android:value=".MySearchableActivity" /> + <!-- declare the default searchable Activity for the whole app --> + <b><meta-data android:name="android.app.default_searchable" + android:value=".MySearchableActivity" /></b> ... </application> </pre> @@ -199,28 +226,34 @@ default searchable Activity. For example:</p> which it is placed (which, in this case, is the entire application). The searchable Activity to use is specified with the {@code android:value} attribute. All other activities in the application, such as {@code AnotherActivity}, are now considered a searchable context and can invoke -the search dialog. When a search is executed, {@code MySearchableActivity} will -be launched to handle the search query.</p> +the search dialog. When a search is executed, {@code MySearchableActivity} is launched to handle +the search query.</p> -<p>Notice that this allows you to control which activities provide search at a more granular level. -To specify only an individual Activity as a searchable context, simply place the {@code +<p>You can also control which activities provide search at a more granular level. +To specify only an individual Activity as a searchable context, place the {@code <meta-data>} with the {@code "android.app.default_searchable"} name inside the respective {@code <activity>} -element (rather than inside the {@code <application>}). And, while it is uncommon, you can -even create more than one searchable Activity and provide each one in different contexts of your +element (rather than inside the {@code <application>} element). While uncommon, you +can also create more than one searchable Activity and provide each one in different contexts of your application, either by declaring a different searchable Activity in each {@code <activity>} -element, or declaring a default searchable Activity for the entire application and then overriding -it with a different {@code <meta-data>} element inside certain activities.</p> +element, or by declaring a default searchable Activity for the entire application and then +overriding it with a {@code <meta-data>} element inside certain activities. (You might do +this if you want to search different sets of data that cannot be handled by the same +searchable Activity, depending on the currently open Activity.)</p> <h3 id="PerformingSearch">Performing a search</h3> -<p>Once your Activity is declared searchable, performing the actual search involves three steps: -receiving the query, searching your data, and presenting the results.</p> +<p>Once you have declared your searchable Activity, performing a search for the user 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} -(assuming that our results are text-based), so -you may want your searchable Activity to extend {@link android.app.ListActivity}, which +<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}, which provides easy access to {@link android.widget.ListView} APIs. (See the <a href="{@docRoot}resources/tutorials/views/hello-listview.html">List View Tutorial</a> for a simple {@link android.app.ListActivity} sample.)</p> @@ -228,12 +261,12 @@ href="{@docRoot}resources/tutorials/views/hello-listview.html">List View Tutoria <h4 id="ReceivingTheQuery">Receiving the query</h4> -<p>When a search is executed from the search dialog, your searchable Activity will be opened -with the {@link android.content.Intent#ACTION_SEARCH} {@link android.content.Intent}, which carries -the search query in the -{@link android.app.SearchManager#QUERY QUERY} extra. All you need to do is check for -this Intent and extract the string. For example, here's how you can get the query when your -Activity launches:</p> +<p>When a user executes a search from the search dialog, the Search Manager sends the {@link +android.content.Intent#ACTION_SEARCH} {@link android.content.Intent} to your searchable Activity. +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 +query when your Activity starts:</p> <pre> @Override @@ -258,22 +291,21 @@ is done.</p> <h4 id="SearchingYourData">Searching your data</h4> -<p>The process of storing and searching your data is a process that's unique to your application. -There are many ways that you might do this and discussing all options is beyond the scope of -this document. This guide will not teach you how to store your data and search it; this -is something you must carefully consider in terms of your needs and your data. However, here are -some tips you may be able to apply:</p> +<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. 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 LIKE query) can provide a more robust search across text data and can -produce results many, many times faster. See <a href="http://sqlite.org/fts3.html">sqlite.org</a> +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 may be -inhibited by the user's data connection. You may want to display a spinning progress wheel until + <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> to see how you can display a progress wheel.</li> @@ -283,32 +315,32 @@ how you can display a progress wheel.</li> <div class="sidebox-wrapper"> <div class="sidebox"> <h2>About Adapters</h2> -<p>An Adapter will bind individual items from a set of data into individual {@link +<p>An Adapter binds individual items from a set of data into individual {@link android.view.View} objects. When the Adapter is applied to a {@link android.widget.ListView}, the Views are injected as individual items of the list. {@link android.widget.Adapter} is simply 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 should implement your own from -{@link android.widget.BaseAdapter}. Install the SDK Samples package for API Level 4 to see a -version of the Searchable Dictionary that creates a custom BaseAdapter.</p> +{@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 BaseAdapter.</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, then you can easily apply your results to a {@link android.widget.ListView} +SQLite database query, then 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 the {@link android.widget.BaseAdapter}.</p> <h4 id="PresentingTheResults">Presenting the results</h4> -<p>Presenting your search results is mostly a UI detail and not something covered by the search -framework APIs. However, a simple solution is to create your searchable Activity to extend {@link -android.app.ListActivity} and then call {@link +<p>Presenting your search results is mostly a UI detail that is not handled by the search APIs. +However, one option is to create your searchable Activity to extend {@link +android.app.ListActivity} and call {@link android.app.ListActivity#setListAdapter(ListAdapter)}, passing it an {@link -android.widget.Adapter} that is bound to your data. This will automatically project all the +android.widget.Adapter} that is bound to your data. This injects all the results into the Activity {@link android.widget.ListView}.</p> <p>For more help presenting your results, see the {@link android.app.ListActivity} @@ -316,29 +348,27 @@ documentation.</p> <p>Also see the <a href="{@docRoot}resources/samples/SearchableDictionary/index.html">Searchable Dictionary</a> sample -application for an a complete demonstration of how to search an SQLite database and use an -{@link android.widget.Adapter} to provide resuls in a {@link android.widget.ListView}.</p> +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="InvokingTheSearchDialog">Invoking the Search Dialog</h2> -<p>Once you have a searchable Activity in place, invoking the search dialog so the user can -submit a -query is easy. Many Android devices provide a dedicated search key and when it is pressed while the -user is within a searchable context of your application, the search dialog will be revealed. -However, -you should never assume that a search key is available on the user's device and should always -provide a search button in your UI that will invoke search.</p> +<p>Once you have a searchable Activity, invoking the search dialog is easy. Many Android +devices provide a dedicated SEARCH key, which reveals the search dialog when the user presses it +from a searchable context of your application. However, you should not assume that a SEARCH +key is available on the user's device and should always provide a search button in your UI that +invokes search.</p> -<p>To invoke search from your Activity, simply call {@link -android.app.Activity#onSearchRequested()}.</p> +<p>To invoke search from your Activity, call {@link android.app.Activity#onSearchRequested()}.</p> -<p>For example, you should provide a menu item in your <a +<p>For instance, you should provide a menu item in your <a href="{@docRoot}guide/topics/ui/menus.html#options-menu">Options Menu</a> or a button in your UI to -invoke search with this method. For your convenience, this <a +invoke search with this method. The <a href="{@docRoot}shareables/search_icons.zip">search_icons.zip</a> file includes icons for -medium and high density screens, which you can use for your menu item or button (low density -screens will automatically scale-down the hdpi image by one half). </p> +medium and high density screens, which you can use for your search menu item or button (low density +screens automatically scale-down the hdpi image by one half). </p> <!-- ... maybe this should go into the Creating Menus document .... <p>If you chose to provide a shortcut key for the menu item, using {@link @@ -346,28 +376,29 @@ android.view.MenuItem#setAlphabeticShortcut(char)}, then SearchManager.MENU_KEY key character, representing the default search key.</p> --> -<p>You can also enable "type-to-search" functionality in your Activity by calling {@link -android.app.Activity#setDefaultKeyMode(int) setDefaultKeyMode}({@link -android.app.Activity#DEFAULT_KEYS_SEARCH_LOCAL}). When this is enabled and the user begins typing on -the keyboard, search will automatically be -invoked and the keystrokes will be inserted in the search dialog. Be sure to enable this mode -during your Activity {@link android.app.Activity#onCreate(Bundle) onCreate()} method.</p> +<p>You can also enable "type-to-search" functionality, which reveals the search dialog when the +user starts typing on the keyboard and 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 life-cycle</h3> +<h3 id="LifeCycle">The impact of the search dialog on your Activity lifecycle</h3> -<p>The search dialog behaves like a {@link android.app.Dialog} that floats at the top of the -screen. It -does not cause any change in the Activity stack, so no life-cycle methods (such as {@link -android.app.Activity#onPause()}) will -be called. All that happens is your Activity loses input focus as it is given to the search dialog. +<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 for the currently open Activity (such as {@link +android.app.Activity#onPause()}) are called. Your Activity just loses input focus as it is given to +the search dialog. </p> -<p>If you want to be notified when search is invoked, simply override the {@link -android.app.Activity#onSearchRequested()} method. When this is called, you can do any work you may -want to do when your Activity looses input focus (such as pause animations). But unless you are -<a href="#SearchContextData">Passing Search Context Data</a> (discussed above), you should always -call the super class implementation. For example:</p> +<p>If you want to be notified when search is invoked, override the {@link +android.app.Activity#onSearchRequested()} method. When the system calls this method, you can do any +work you want to when your Activity looses input focus to the search dialog (such as pause +animations). 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 @@ -377,35 +408,37 @@ public boolean onSearchRequested() { } </pre> -<p>If the user cancels search by pressing the device Back key, the Activity in which search was -invoked will re-gain input focus. You can register to be notified when the search dialog is -closed with {@link android.app.SearchManager#setOnDismissListener(SearchManager.OnDismissListener)} -and/or {@link android.app.SearchManager#setOnCancelListener(SearchManager.OnCancelListener)}. You -should normally only need to register the {@link android.app.SearchManager.OnDismissListener -OnDismissListener}, because this is called every time that the search dialog is closed. The {@link +<p>If the user cancels search by pressing the BACK key, the Activity in which search was +invoked re-gains 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 left the search dialog, so it is not called when a search is executed (in which +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 life-cycle -events will be triggered once the user executes a search (the current Activity will receive {@link +<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 <a href="{@docRoot}guide/topics/fundamentals.html#lcycles">Application Fundamentals</a>). If, however, the current Activity is the searchable Activity, then one of two -things will happen:</p> +things happens:</p> -<ul> - <li>By default, the searchable Activity will receive the {@link +<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 will be brought to the top of the stack. You'll now have two instances of your searchable -Activity in the Activity stack (so pressing the Back key will go back to the previous instance of -the searchable Activity, rather than exiting the searchable Activity).</li> - <li>On the other hand, if the Activity has set {@code android:launchMode} to "singleTop" then the -searchable Activity will receive the {@link android.content.Intent#ACTION_SEARCH} Intent with a call +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 BACK key 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 "singleTop", 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 want to handle -this case: +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 "singleTop": <pre> @Override public void onCreate(Bundle savedInstanceState) { @@ -430,28 +463,30 @@ private void handleIntent(Intent intent) { <p>Compared to the example code in the section about <a href="#PerfomingSearch">Performing a Search</a>, all the code to handle the -search Intent has been moved outside the {@link android.app.Activity#onCreate(Bundle) -onCreate()} method so it can also be executed from {@link android.app.Activity#onNewIntent(Intent) -onNewIntent()}. -It's important to note that when {@link android.app.Activity#onNewIntent(Intent)} is -called, the Activity has not been restarted, so the {@link android.app.Activity#getIntent()} method -will still return the Intent that was first received with {@link -android.app.Activity#onCreate(Bundle) onCreate()}. This is why {@link -android.app.Activity#setIntent(Intent)} is called inside {@link -android.app.Activity#onNewIntent(Intent)} (just in case you call {@link -android.app.Activity#getIntent()} at a later time).</p> +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> -</ul> +</ol> -<p>This second scenario is normally ideal, because the chances are good that once a search is -completed, the user will perform additional searches and it's a bad experience if your application -piles multiple instances of the searchable Activity on the stack. So we recommend that you set your -searchable Activity to "singleTop" launch mode in the application manifest. For example:</p> +<p>The second scenario using "singleTop" 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 "singleTop" launch mode in the application +manifest. For example:</p> <pre> <activity android:name=".MySearchableActivity" - android:launchMode="singleTop" > + <b>android:launchMode="singleTop"</b> > <intent-filter> <action android:name="android.intent.action.SEARCH" /> </intent-filter> @@ -461,19 +496,20 @@ searchable Activity to "singleTop" launch mode in the application manifest. For </pre> + <h2 id="SearchContextData">Passing Search Context Data</h2> -<p>In order to refine your search criteria, you may want to provide some additional -data to your searchable Activity when a search is executed. For instance, when you search your data, -you may want to filter results based on more than just the search query text. In a simple -case, you could just make your refinements inside the searchable Activity, for every search made. -If, however, your -search criteria may vary from one searchable context to another, then you can pass whatever data is -necessary to refine your search in the {@link android.app.SearchManager#APP_DATA} 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, you need to override {@link -android.app.Activity#onSearchRequested()} method for the Activity in which search will be invoked. +<p>To refine your search criteria from the current Activity instead of depending only on the user's +search query, you can provide additional data in the Intent that the Search Manager sends to your +searchable Activity. In a simple case, you can make your refinements inside the searchable +Activity, for every search made, but if your +search criteria varies from one searchable context to another, then you can pass whatever data +is necessary to refine your search 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 {@link +android.app.Activity#onSearchRequested()} method for the Activity in which search can be invoked. For example:</p> <pre> @@ -487,56 +523,54 @@ public boolean onSearchRequested() { </pre> <p>Returning "true" indicates that you have successfully handled this callback event. Then in your -searchable Activity, you can extract this data from the {@link +searchable Activity, you can extract the data placed inside {@code appdata} 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(MySearchableActivity.JARGON); - } +Bundle appData = getIntent().getBundleExtra(SearchManager.APP_DATA); +if (appData != null) { + boolean jargon = appData.getBoolean(MySearchableActivity.JARGON); +} </pre> -<p class="caution"><strong>Note:</strong> You should never call the {@link +<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. When you want to invoke the -search dialog, always call {@link android.app.Activity#onSearchRequested()} so that custom -implementations (such as the addition of {@code appData}, in the above example) can be accounted -for.</p> +the {@link android.app.Activity#onSearchRequested()} callback method. To invoke 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="VoiceSearch">Adding Voice Search</h2> -<p>You can easily add voice search functionality to your search dialog by adding the {@code -android:voiceSearchMode} attribute to your searchable configuration. This will add a voice search -button in the search dialog that, when clicked, will launch a voice prompt. When the user -has finished speaking, the transcribed search query will be sent to your searchable +<p>You can add voice search functionality to your search dialog by adding the {@code +android:voiceSearchMode} attribute to your searchable configuration. This adds a voice search +button in the search dialog that launches a voice prompt. When the user +has finished speaking, the transcribed search query is sent to your searchable Activity.</p> -<p>To enable voice search for your activity, add the {@code android:voiceSearchMode} -attribute to your searchable configuration. For example:</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" - android:voiceSearchMode="showVoiceSearchButton|launchRecognizer" > + <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. This is -how most applications should declare this attribute.</p> +should launch a recognizer that returns the transcribed text to the searchable Activity.</p> -<p>There are some additional attributes you can provide to specify the voice search behavior, such +<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> for more information about the +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 will be immediately sent to -your searchable Activity without a chance for the user to review the transcribed query. Be sure to -sufficiently test the voice recognition and ensure that it understands the types of queries that -the user will submit inside your application.</p> +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> diff --git a/docs/html/guide/topics/search/searchable-config.jd b/docs/html/guide/topics/search/searchable-config.jd index 71566de..2aa2db6 100644 --- a/docs/html/guide/topics/search/searchable-config.jd +++ b/docs/html/guide/topics/search/searchable-config.jd @@ -14,18 +14,18 @@ parent.link=index.html </div> </div> -<p>In order to utilize the Android search framework and provide a custom search dialog, your +<p>To utilize the Android search framework and provide a custom search dialog, your application must provide a search configuration in the form of an XML resource. This document describes the search configuration XML -in terms of its syntax and usage. For a more complete discussion about how to implement search -features for your application, see the companion documents about <a +in terms of its syntax and usage. For more information about how to implement search +features for your application, see the developer guide about <a href="index.html">Search</a>.</p> <dl class="xml"> <dt>file location:</dt> <dd><code>res/xml/<em>filename</em>.xml</code><br/> -The filename will be used as the resource ID.</dd> +Android uses the filename as the resource ID.</dd> <dt>syntax:</dt> <dd> @@ -70,174 +70,187 @@ The filename will be used as the resource ID.</dd> <p class="caps">attributes:</p> <dl class="atn-list"> <dt><code>android:label</code></dt> - <dd><em>String resource</em>. <strong>Required</strong>. This is the name of your application. -It should normally be the same as the name applied to the {@code android:label} attribute of your <a + <dd><em>String resource</em>. (Required.) The name of your application. +It should be the same as the name applied to the {@code android:label} attribute of your <a href="{@docRoot}guide/topics/manifest/activity-element.html#label">{@code <activity>}</a> or <a href="{@docRoot}guide/topics/manifest/application-element.html#label">{@code -<application>}</a> manifest element. This is only visible to the user when you set -<code>android:includeInGlobalSearch</code> "true", in which case, this label is used to identify +<application>}</a> manifest element. This label is only visible to the user when you set +<code>android:includeInGlobalSearch</code> to "true", in which case, this label is used to identify your application as a searchable item in the system's search settings.</dd> + <dt><code>android:hint</code></dt> - <dd><em>String resource</em>. The text to display in the search text field when no text has - been entered. This is recommended in order to provide a hint to the user about what -content is searchable. For consistency among other Android applications, you should format the + <dd><em>String resource</em>. (Recommended.) The text to display in the search text field when +no text has been entered. It provides a hint to the user about what +content is searchable. For consistency with other Android applications, you should format the string for {@code android:hint} as "Search <em><content-or-product></em>". For example, "Search songs and artists" or "Search YouTube".</dd> + <dt><code>android:searchMode</code></dt> - <dd><em>Keyword</em>. Sets additional modes that control the search presentation. -Specifically, the available modes define how the query text in the search dialog's text box -should be rewritten when a suggestion is focused. The following mode values are accepted: + <dd><em>Keyword</em>. Sets additional modes that control the search dialog presentation. +Currently available modes define how the query text that appears in the search dialog +should be rewritten when a custom suggestion receives focus. The following mode values are accepted: <table> <tr><th>Value</th><th>Description</th></tr> <tr> - <td><code>"queryRewriteFromData"</code></td> - <td>If set, this causes the suggestion column - {@link android.app.SearchManager#SUGGEST_COLUMN_INTENT_DATA} to be considered as the -text for suggestion query - rewriting. This should only be used when the values in - {@link android.app.SearchManager#SUGGEST_COLUMN_INTENT_DATA} are suitable for user -inspection and editing - - typically, HTTP/HTTPS Uri's.</td> + <td><code>"queryRewriteFromText"</code></td> + <td>Use the value from the {@link android.app.SearchManager#SUGGEST_COLUMN_TEXT_1} +colum to rewrite the query text in the search dialog.</td> </tr> <tr> - <td><code>"queryRewriteFromText"</code></td> - <td>If set, this causes the suggestion - column {@link android.app.SearchManager#SUGGEST_COLUMN_TEXT_1} to be considered as the -text for suggestion query - rewriting. This should be used for suggestions in which no query - text is provided and the {@link android.app.SearchManager#SUGGEST_COLUMN_INTENT_DATA} -values are not suitable - for user inspection and editing.</td> + <td><code>"queryRewriteFromData"</code></td> + <td>Use the value from the + {@link android.app.SearchManager#SUGGEST_COLUMN_INTENT_DATA} column to rewrite the +query text in the search dialog. This should only be used when the values in + {@link android.app.SearchManager#SUGGEST_COLUMN_INTENT_DATA} are suitable for user +inspection and editing, typically HTTP URI's.</td> </tr> </table> <p>For more information, see the discussion about rewriting the query text in <a href="adding-custom-suggestions.html#RewritingQueryText">Adding Custom Suggestions</a>.</p> </dd> + <dt><code>android:searchButtonText</code></dt> - <dd><em>String resource</em>. The text to display in the button that executes the search. By + <dd><em>String resource</em>. The text to display in the button that executes search. By default, the button shows a search icon (a magnifying glass), which is ideal for -internationalization.</dd> +internationalization, so you should not use this attribute to change the button unless the +behavior is something other than a search (such as a URL request in a web browser).</dd> + <dt><code>android:inputType</code></dt> - <dd><em>Keyword</em>. Defines the type of input method (soft-keyboard) to use with the search -dialog. For most searches, in which free form text is expected, this attribute is not needed and -the default input method should be used. See {@link android.R.attr#inputType} for a list of suitable -values for this attribute.</dd> + <dd><em>Keyword</em>. Defines the type of input method (such as the type of soft keyboard) +to use with the search dialog. For most searches, in which free-form text is expected, you don't +need this attribute. See {@link android.R.attr#inputType} for a list of suitable values for this +attribute.</dd> + <dt><code>android:imeOptions</code></dt> <dd><em>Keyword</em>. Supplies additional options for the input method. - For most searches, in which free form text is expected, this attribute is not needed, - and will default to "actionSearch" (provides the "search" button instead of a carriage -return). See {@link android.R.attr#imeOptions} for a list of suitable values for this attribute. + For most searches, in which free-form text is expected, you don't need this attribute. The +default IME is "actionSearch" (provides the "search" button instead of a carriage +return in the soft keyboard). See {@link android.R.attr#imeOptions} for a list of suitable values +for this attribute. </dd> </dl> + + <h4>Search suggestion attributes</h4> + <p>If you have defined a content provider to generate search suggestions, you need to - define additional attributes in order to configure communications with the Content - Provider. When providing search suggestions, you'll need some of the following + define additional attributes that configure communications with the content + provider. When providing search suggestions, you need some of the following {@code <searchable>} attributes:</p><br/> <dl class="atn-list"> <dt><code>android:searchSuggestAuthority</code></dt> - <dd><em>String</em>. <strong>Required to provide search suggestions</strong>. + <dd><em>String</em>. (Required to provide search suggestions.) This value must match the authority string provided in the {@code android:authorities} -attribute of the {@code <provider>} element.</dd> +attribute of the Android manifest {@code <provider>} element.</dd> + <dt><code>android:searchSuggestPath</code></dt> - <dd><em>String</em>. This path will be used as a portion of the suggestions + <dd><em>String</em>. This path is used as a portion of the suggestions query {@link android.net.Uri}, after the prefix and authority, but before the standard suggestions path. This is only required if you have a single content provider issuing different types - of suggestions (e.g. for different data types) and you need - a way to disambiguate the suggestions queries when they are received.</dd> + of suggestions (such as for different data types) and you need + a way to disambiguate the suggestions queries when you receive them.</dd> + <dt><code>android:searchSuggestSelection</code></dt> - <dd><em>String</em>. This value will be passed into your - query function as the {@code selection} parameter. Typically this will be a WHERE clause -for your database, and should contain a single question mark, which is a place-holder for the -actual query string that has been typed by the user. However, you can also use any non-null -value to simply trigger the delivery of the query text via the {@code + <dd><em>String</em>. This value is passed into your + query function as the {@code selection} parameter. Typically this is a WHERE clause +for your database, and should contain a single question mark, which is a placeholder for the +actual query string that has been typed by the user (for example, {@code "query=?"}). However, you +can also use any non-null value to trigger the delivery of the query text via the {@code selectionArgs} parameter (and then ignore the {@code selection} parameter).</dd> + <dt><code>android:searchSuggestIntentAction</code></dt> <dd><em>String</em>. The default Intent action to be used when a user - clicks on a search suggestion (such as {@code "android.intent.action.VIEW"}). - If not overridden by the selected suggestion (via the {@link -android.app.SearchManager#SUGGEST_COLUMN_INTENT_ACTION} column), this value will - be placed in the action field of the {@link android.content.Intent} when the - user clicks a suggestion.</dd> + clicks on a custom search suggestion (such as {@code "android.intent.action.VIEW"}). + If this is not overridden by the selected suggestion (via the {@link +android.app.SearchManager#SUGGEST_COLUMN_INTENT_ACTION} column), this value is placed in the action +field of the {@link android.content.Intent} when the user clicks a suggestion.</dd> + <dt><code>android:searchSuggestIntentData</code></dt> <dd><em>String</em>. The default Intent data to be used when a user - clicks on a search suggestion. + clicks on a custom search suggestion. If not overridden by the selected suggestion (via the {@link -android.app.SearchManager#SUGGEST_COLUMN_INTENT_DATA} column), this value will be +android.app.SearchManager#SUGGEST_COLUMN_INTENT_DATA} column), this value is placed in the data field of the {@link android.content.Intent} when the user clicks a suggestion.</dd> + <dt><code>android:searchSuggestThreshold</code></dt> <dd><em>Integer</em>. The minimum number of characters needed to - trigger a suggestion look-up. Only guarantees that a source will not be - queried for anything shorter than the threshold. The default value is 0.</dd> + trigger a suggestion look-up. Only guarantees that the Search Manager will not query your + content provider for anything shorter than the threshold. The default value is 0.</dd> </dl> <p>For more information about the above attributes for search suggestions, see the guides for <a href="adding-recent-query-suggestions.html">Adding Recent Query Suggestions</a> and <a href="adding-custom-suggestions.html">Adding Custom Suggestions</a>.</p> - <p>Beyond providing search suggestions while using your application's search dialog, you - can also configure your search suggestions to be made available to Quick Search Box, - which will allow users so receive search suggestions from your application content from outside - your application. When providing search suggestions to Quick Search Box, you'll need some of the + + <h4>Quick Search Box attributes</h4> + + <p>To make your custom search suggestions available to Quick Search Box, you need some of the following {@code <searchable>} attributes:</p><br/> <dl class="atn-list"> <dt><code>android:includeInGlobalSearch</code></dt> - <dd><em>Boolean</em>. <strong>Required to provide search suggestions in - Quick Search Box</strong>. "true" if you want your suggestions to be - included in the globally accessible Quick Search Box. Note that the user must - still enable your application as a searchable item in the system search settings in order - for your suggestions to appear in Quick Search Box.</dd> + <dd><em>Boolean</em>. (Required to provide search suggestions in + Quick Search Box.) Set to "true" if you want your suggestions to be + included in the globally accessible Quick Search Box. The user must + still enable your application as a searchable item in the system search settings before + your suggestions will appear in Quick Search Box.</dd> + <dt><code>android:searchSettingsDescription</code></dt> <dd><em>String</em>. Provides a brief description of the search suggestions that you provide -to Quick Search Box, which will be displayed in the searchable items entry for your application. +to Quick Search Box, which is displayed in the searchable items entry for your application. Your description should concisely describe the content that is searchable. For example, "Artists, albums, and tracks" for a music application, or "Saved notes" for a notepad application.</dd> + <dt><code>android:queryAfterZeroResults</code></dt> - <dd><em>Boolean</em>. "true" if you want your content provider to be invoked for - supersets of queries that have returned zero results for in the past. For example, if a - source returned zero results for "bo", it would be ignored for "bob". If "false", - this source will only be ignored for a single session; the next time the search dialog - is invoked, all sources will be queried. The default value is false.</dd> + <dd><em>Boolean</em>. Set to "true" if you want your content provider to be invoked for + supersets of queries that have returned zero results in the past. For example, if +your content provider returned zero results for "bo", it should be requiried for "bob". If set to +"false", supersets are ignored for a single session ("bob" does not invoke a requery). This lasts +only for the life of the search dialog (when the search dialog is reopened, "bo" queries your +content provider again). The default value is false.</dd> </dl> + + <h4>Voice search attributes</h4> + <p>To enable voice search for your search dialog, you'll need some of the following {@code <searchable>} attributes:</p><br/> <dl class="atn-list"> <dt><code>android:voiceSearchMode</code></dt> - <dd><em>Keyword</em>. <strong>Required to provide voice search capabilities</strong>. + <dd><em>Keyword</em>. (Required to provide voice search capabilities.) Enables voice search for the search dialog, with a specific mode for voice search. - (Voice search may not be provided by the device, in which case these flags will + (Voice search may not be provided by the device, in which case these flags have no effect.) The following mode values are accepted: <table> <tr><th>Value</th><th>Description</th></tr> <tr> <td><code>"showVoiceSearchButton"</code></td> - <td>Display a voice search button. This only - takes effect if voice search is available on the device. If set, then either - {@code "launchWebSearch"} or {@code "launchRecognizer"} must also be set + <td>Display a voice search button, if voice search is available on the device. If set, +then either {@code "launchWebSearch"} or {@code "launchRecognizer"} must also be set (separated by the pipe | character).</td> </tr> <tr> <td><code>"launchWebSearch"</code></td> - <td>The voice search button will take the user directly - to a built-in voice web search activity. Most applications will not use this flag, as - it will take the user away from the Activity in which search was invoked.</td> + <td>The voice search button takes the user directly + to a built-in voice web search activity. Most applications don't need this flag, as + it takes the user away from the Activity in which search was invoked.</td> </tr> <tr> <td><code>"launchRecognizer"</code></td> - <td>The voice search button will take + <td>The voice search button takes the user directly to a built-in voice recording activity. This Activity - will prompt the user to speak, transcribe the spoken text, and forward the resulting - query text to the searchable Activity, just as if the user had typed it into the + prompts the user to speak, transcribes the spoken text, and forwards the resulting + query text to the searchable Activity, just as if the user typed it into the search UI and clicked the search button.</td> </tr> </table> </dd> + <dt><code>android:voiceLanguageModel</code></dt> <dd><em>Keyword</em>. The language model that should be used by the voice recognition system. The following values are accepted: @@ -245,92 +258,99 @@ albums, and tracks" for a music application, or "Saved notes" for a notepad appl <tr><th>Value</th><th>Description</th></tr> <tr> <td><code>"free_form"</code></td> - <td>Use a language model based on free-form speech recognition. This is the -default.</td> + <td>Use free-form speech recognition for dictating queries. This is primarily +optimized for English. This is the default.</td> </tr> <tr> <td><code>"web_search"</code></td> - <td>Use a language model based on web search terms.</td> + <td>Use web-search-term recognition for shorter, search-like phrases. This is +available in more languages than "free_form".</td> </tr> </table> <p>Also see {@link android.speech.RecognizerIntent#EXTRA_LANGUAGE_MODEL} for more information.</p></dd> + <dt><code>android:voicePromptText</code></dt> <dd><em>String</em>. An additional message to display in the voice input dialog.</dd> + <dt><code>android:voiceLanguage</code></dt> <dd><em>String</em>. The spoken language to be expected, expressed as the string value of -a constants in {@link java.util.Locale} (for example, {@code "de"} for German or {@code "fr"} for -French). This is only needed if it is different from the current value of {@link +a constants in {@link java.util.Locale} (such as {@code "de"} for German or {@code "fr"} for +French). This is needed only if it is different from the current value of {@link java.util.Locale#getDefault() Locale.getDefault()}.</dd> + <dt><code>android:voiceMaxResults</code></dt> <dd><em>Integer</em>. Forces the maximum number of results to return, - including the "best" result which will always be provided as the {@link + including the "best" result which is always provided as the {@link android.content.Intent#ACTION_SEARCH} Intent's primary query. Must be 1 or greater. Use {@link android.speech.RecognizerIntent#EXTRA_RESULTS} to get the results from the Intent. - If not provided, the recognizer will choose how many results to return.</dd> + If not provided, the recognizer chooses how many results to return.</dd> </dl> </dd> <!-- end searchable element --> + <dt id="actionkey-element"><code><actionkey></code></dt> - <dd>Defines a shortcut key for a search action, in order to provide special behaviors at the touch -of a button, based on the current query or focused suggestion. For example, the Contacts -application enables the device call key for suggestions. So, when -the user focuses on a search suggestion using the directional controls and then presses the call -key, the application will immediately initiate a phone call to the suggested contact. + <dd>Defines a device key and behavior for a search action. A search action provides a +special behavior at the touch of a button on the device, based on the current query or focused +suggestion. For example, the Contacts application provides a search action to initiate a phone call +to the currenly focused contact suggestion at the press of the CALL button. <p>Not all action keys are available on every device, and not all keys are allowed to be overriden in this way. For example, the "Home" key cannot be used and must always return to the home screen. Also be sure not to define an action key for a key that's needed for typing a search query. This essentially limits the available and reasonable action keys to the call button and menu button. Also note that action keys are not generally discoverable, so you should not provide them as a core user feature.</p> + <p>You must define the <code>android:keycode</code> to define the key and at least one of the +other three attributes in order to define the search action.</p> <p class="caps">attributes:</p> <dl class="atn-list"> <dt><code>android:keycode</code></dt> - <dd><em>String</em>. <strong>Required</strong>. A key code from {@link + <dd><em>String</em>. (Required.) A key code from {@link android.view.KeyEvent} that represents the action key - you wish to respond to (for example {@code "KEYCODE_CALL"}). This will be added to the - {@link android.content.Intent#ACTION_SEARCH ACTION_SEARCH} Intent that is passed to your - searchable Activity. To examine the key code, use - {@link android.content.Intent#getIntExtra getIntExtra(SearchManager.ACTION_KEY)}. - In addition to the key code, you must also provide one or more of - the action specifier attributes below. Not all action keys -are actually supported using this mechanism, as many of them are used for typing, - navigation, or system functions. Note that although each of the action message elements are -optional, at least one must be present for the action key to have any effect.</dd> + you wish to respond to (for example {@code "KEYCODE_CALL"}). This is added to the + {@link android.content.Intent#ACTION_SEARCH ACTION_SEARCH} Intent that is passed to your + searchable Activity. To examine the key code, use + {@link android.content.Intent#getIntExtra getIntExtra(SearchManager.ACTION_KEY)}. Not all +keys are supported for a search action, as many of them are used for typing, navigation, or system +functions.</dd> + <dt><code>android:queryActionMsg</code></dt> <dd><em>String</em>. An action message to be sent if the action key is pressed while the -user is simply entering query text. This will be added to the - {@link android.content.Intent#ACTION_SEARCH ACTION_SEARCH} Intent that is - passed to your searchable Activity. To examine the string, use +user is entering query text. This is added to the + {@link android.content.Intent#ACTION_SEARCH ACTION_SEARCH} Intent that the Search Manager + passes to your searchable Activity. To examine the string, use {@link android.content.Intent#getStringExtra getStringExtra(SearchManager.ACTION_MSG)}.</dd> + <dt><code>android:suggestActionMsg</code></dt> <dd><em>String</em>. An action message to be sent if the action key is pressed while a - suggestion is focused. This will be added to the - Intent that is passed to your searchable Activity (using the action you've defined for - the suggestion). To examine the string, + suggestion is in focus. This is added to the + Intent that that the Search Manager passes to your searchable Activity (using the action +you've defined for the suggestion). To examine the string, use {@link android.content.Intent#getStringExtra - getStringExtra(SearchManager.ACTION_MSG)}. Note that this should only be used if all your + getStringExtra(SearchManager.ACTION_MSG)}. This should only be used if all your suggestions support this action key. If not all suggestions can handle the same action key, then you must instead use the following {@code android:suggestActionMsgColumn} attribute.</dd> + <dt><code>android:suggestActionMsgColumn</code></dt> <dd><em>String</em>. The name of the column in your content provider that defines the -action message for this action key, which is to be sent if the action key is pressed while a - suggestion is focused. This attribute lets you control the +action message for this action key, which is to be sent if the user presses the action key while a + suggestion is in focus. This attribute lets you control the action key on a suggestion-by-suggestion basis, because, instead of using the {@code android:suggestActionMsg} attribute to define the action message for all suggestions, each entry in -your content provider provides its own action message. First, you must define a column in your +your content provider provides its own action message. + <p>First, you must define a column in your content provider for each suggestion to provide an action message, then provide the name of that -column in this attribute. The search manager will look at your suggestion cursor, - using the string provided here in order to select your action message column, and - then select the action message string from the cursor. That string will be added to the - Intent that is passed to your searchable Activity (using the action you've defined for - suggestions). To examine the string, use {@link +column in this attribute. The Search Manager looks at your suggestion cursor, + using the string provided here to select your action message column, and + then select the action message string from the Cursor. That string is added to the + Intent that the Search Manager passes to your searchable Activity (using the action you've +defined for suggestions). To examine the string, use {@link android.content.Intent#getStringExtra getStringExtra(SearchManager.ACTION_MSG)}. If the data -does not exist for the selected suggestion, the action key will be ignored.</dd> +does not exist for the selected suggestion, the action key is ignored.</dd> </dl> </dd><!-- end action key --> </dl> |