page.title=Adding Recent Query Suggestions parent.title=Search parent.link=index.html @jd:body

In this document

  1. The Basics
  2. Creating a Content Provider
  3. Modifying the Searchable Configuration
  4. Saving Queries
  5. Clearing the Suggestion Data

Key classes

  1. {@link android.provider.SearchRecentSuggestions}
  2. {@link android.content.SearchRecentSuggestionsProvider}

See also

  1. Searchable Configuration

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.

Before you begin, you need to implement the search dialog for basic searches in your application. If you haven't, see Using the Android Search Dialog.

The Basics

Figure 1. Screenshot of a search dialog with recent query suggestions.

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 Using the Android Search Dialog).

To provide recent queries suggestions, you need to:

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.

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:

  1. 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.
  2. Your content provider returns a {@link android.database.Cursor} that points to all suggestions that match the search query text.
  3. Search Manager displays the list of suggestions provided by the Cursor.

Once the recent query suggestions are displayed, the following might happen:

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.

Creating a Content Provider

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.

For example, here's a complete implementation of a content provider for recent query suggestions:

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);
    }
}

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:

public final static int MODE = DATABASE_MODE_QUERIES | DATABASE_MODE_2LINES;

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:

<application>
    <provider android:name=".MySuggestionProvider"
              android:authorities="com.example.MySuggestionProvider" />
    ...
</application>

Modifying the Searchable Configuration

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:

<?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="com.example.MySuggestionProvider"
    android:searchSuggestSelection=" ?" >
</searchable>

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).

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).

Saving Queries

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:

@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);
    }
}

The {@link android.content.SearchRecentSuggestionsProvider} constructor requires the same authority and database mode declared by your content provider.

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 Search Manager looks for matching suggestions.

Clearing the Suggestion Data

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:

SearchRecentSuggestions suggestions = new SearchRecentSuggestions(this,
        HelloSuggestionProvider.AUTHORITY, HelloSuggestionProvider.MODE);
suggestions.clearHistory();

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.