| page.title=Adding Recent Query Suggestions |
| parent.title=Search |
| parent.link=index.html |
| @jd:body |
| |
| <div id="qv-wrapper"> |
| <div id="qv"> |
| <h2>Key classes</h2> |
| <ol> |
| <li>{@link android.provider.SearchRecentSuggestions}</li> |
| <li>{@link android.content.SearchRecentSuggestionsProvider}</li> |
| </ol> |
| <h2>In this document</h2> |
| <ol> |
| <li><a href="#TheBasics">The Basics</a></li> |
| <li><a href="#RecentQuerySearchableConfiguration">Modifying the searchable |
| configuration</a></li> |
| <li><a href="#RecentQueryContentProvider">Creating a Content Provider</a></li> |
| <li><a href="#SavingQueries">Saving queries</a></li> |
| <li><a href="#ClearingSuggestionData">Clearing the suggestion data</a></li> |
| </ol> |
| <h2>See also</h2> |
| <ol> |
| <li><a href="searchable-config.html">Searchable Configuration</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 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>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;" /> |
| |
| <p>Recent query suggestions are simply saved searches. When the user selects one of |
| the suggestions, your searchable Activity will receive a normal {@link |
| android.content.Intent#ACTION_SEARCH} Intent with the suggestion as the search query, which your |
| searchable Activity will already handle.</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>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> |
| </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>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> |
| |
| <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 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> |
| </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 |
| 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> |
| |
| <p>The content provider that you need for recent query suggestions must be an implementation |
| of {@link android.content.SearchRecentSuggestionsProvider}. This class does practically everything |
| for you. All you have to do is write a class constructor that executes one line of code.</p> |
| |
| <p>For example, here's a complete implementation of a content provider for recent query |
| suggestions:</p> |
| |
| <pre> |
| public class MySuggestionProvider extends SearchRecentSuggestionsProvider { |
| public final static String AUTHORITY = "my.package.MySuggestionProvider"; |
| public final static int MODE = DATABASE_MODE_QUERIES; |
| |
| public MySuggestionProvider() { |
| setupSuggestions(AUTHORITY, MODE); |
| } |
| } |
| </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 |
| android.content.SearchRecentSuggestionsProvider#DATABASE_MODE_QUERIES} and can optionally include |
| {@link |
| android.content.SearchRecentSuggestionsProvider#DATABASE_MODE_2LINES}, which will add another column |
| to the suggestions table that allows you to provide a second line of text with each suggestion. For |
| example:</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> |
| |
| <pre> |
| <application> |
| <provider android:name=".MySuggestionProvider" |
| android:authorities="my.package.authority" /> |
| ... |
| </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 |
| 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> |
| |
| <pre> |
| @Override |
| public void onCreate(Bundle savedInstanceState) { |
| super.onCreate(savedInstanceState); |
| setContentView(R.layout.main); |
| |
| Intent Intent = getIntent(); |
| |
| if (Intent.ACTION_SEARCH.equals(Intent .getAction())) { |
| String query = Intent .getStringExtra(SearchManager.QUERY); |
| SearchRecentSuggestions suggestions = new SearchRecentSuggestions(this, |
| MySuggestionProvider.AUTHORITY, MySuggestionProvider.MODE); |
| suggestions.saveRecentQuery(query, null); |
| } |
| } |
| </pre> |
| |
| <p>Notice that 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 |
| 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 |
| 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> |
| |
| |
| <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 |
| android.provider.SearchRecentSuggestions#clearHistory()}. For example:</p> |
| |
| <pre> |
| SearchRecentSuggestions suggestions = new SearchRecentSuggestions(this, |
| HelloSuggestionProvider.AUTHORITY, HelloSuggestionProvider.MODE); |
| 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 |
| verify that the user wants to delete their search history.</p> |
| |