| page.title=Adding Recent Query Suggestions |
| parent.title=Search |
| parent.link=index.html |
| @jd:body |
| |
| <div id="qv-wrapper"> |
| <div id="qv"> |
| <h2>In this document</h2> |
| <ol> |
| <li><a href="#TheBasics">The Basics</a></li> |
| <li><a href="#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>See also</h2> |
| <ol> |
| <li><a href="searchable-config.html">Searchable Configuration</a></li> |
| </ol> |
| </div> |
| </div> |
| |
| <p>When using the Android search dialog or search widget, 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 or a search widget for basic searches |
| in your application. |
| If you haven't, see <a href="search-dialog.html">Creating a Search Interface</a>.</p> |
| |
| |
| |
| <h2 id="TheBasics">The Basics</h2> |
| |
| <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 receives a {@link |
| android.content.Intent#ACTION_SEARCH} intent with the suggestion as the search query, which your |
| searchable activity already handles (as described in <a href="search-dialog.html">Creating a Search |
| Interface</a>).</p> |
| |
| <p>To provide recent queries suggestions, you need to:</p> |
| |
| <ul> |
| <li>Implement a searchable activity, as described in <a |
| href="{@docRoot}guide/topics/search/search-dialog.html">Creating a Search Interface</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 that |
| provides search suggestions.</li> |
| <li>Save queries to your content provider each time a search is executed.</li> |
| </ul> |
| |
| <p>Just as the Android system displays the search dialog, it also displays the |
| search suggestions below the dialog or search widget. All you need to do is provide a source from |
| which the system can retrieve suggestions.</p> |
| |
| <p>When the system identifies that your activity is searchable and provides search |
| suggestions, the following procedure takes place as soon as the user begins typing a query:</p> |
| |
| <ol> |
| <li>The system 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>The system 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>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, an |
| {@link android.content.Intent#ACTION_SEARCH} intent is delivered to your searchable activity using |
| the suggested text as the query.</li> |
| </ul> |
| |
| <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="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 = "com.example.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) |
| 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 adds another column |
| to the suggestions table that allows you to provide a second line of text with each suggestion. For |
| 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>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="com.example.MySuggestionProvider" /> |
| ... |
| </application> |
| </pre> |
| |
| |
| |
| <h2 id="RecentQuerySearchableConfiguration">Modifying the Searchable Configuration</h2> |
| |
| <p>To configure the system 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) 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 |
| 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>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) |
| 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 (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 is also matched against this second line when the system |
| looks for matching suggestions.</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 query history, call {@link |
| android.provider.SearchRecentSuggestions#clearHistory()}. For example:</p> |
| |
| <pre> |
| SearchRecentSuggestions suggestions = new SearchRecentSuggestions(this, |
| HelloSuggestionProvider.AUTHORITY, HelloSuggestionProvider.MODE); |
| suggestions.clearHistory(); |
| </pre> |
| |
| <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> |
| |