am 2a8dd4e4
: Merge "docs: editorial revisions to Search guide" into froyo
Merge commit '2a8dd4e46f43c2bc5b3c1cfd2f350a83ea2b18b1' into gingerbread * commit '2a8dd4e46f43c2bc5b3c1cfd2f350a83ea2b18b1': docs: editorial revisions to Search guide
This commit is contained in:
@ -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>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>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>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>
|
||||
android.app.SearchManager#SUGGEST_COLUMN_INTENT_DATA} column of your suggestions table.
|
||||
|
||||
<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
|
||||
{@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} 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.</li>
|
||||
</ol>
|
||||
suggestions table, respectively.
|
||||
|
||||
<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 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
|
||||
{@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>
|
||||
|
||||
<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
|
||||
|
@ -5,20 +5,22 @@ parent.link=index.html
|
||||
|
||||
<div id="qv-wrapper">
|
||||
<div id="qv">
|
||||
<h2>In this document</h2>
|
||||
<ol>
|
||||
<li><a href="#TheBasics">The Basics</a></li>
|
||||
<li><a href="#RecentQueryContentProvider">Creating a Content Provider</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>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>
|
||||
</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>
|
||||
|
||||
<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>Once the recent query suggestions are displayed, the following might happen:</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>
|
||||
|
||||
<p>At this point, the following may 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>
|
||||
|
||||
<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>
|
||||
two-line mode, then the query text is also matched against this second line when the Search Manager
|
||||
looks for matching suggestions.</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>
|
||||
|
||||
|
@ -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 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>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>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>
|
||||
|
||||
|
@ -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 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, you need to override {@link
|
||||
android.app.Activity#onSearchRequested()} method for the Activity in which search will be invoked.
|
||||
<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>
|
||||
|
@ -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>
|
||||
|
Reference in New Issue
Block a user