Search >

Adding Recent Query Suggestions

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.

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

The Basics

Recent query suggestions are simply saved searches. When the user selects one of the suggestions, your searchable Activity will receive a normal ACTION_SEARCH Intent with the suggestion as the search query, which your searchable Activity will already handle.

To provide recent queries suggestions, you need to:

  • Implement a basic searchable Activity, as documented in Using the Android Search Dialog.
  • Create a content provider that extends SearchRecentSuggestionsProvider and declare it in your application manifest.
  • Modify the searchable configuration with information about the content provider.
  • Save queries to your content provider each time a search is made.

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.

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:

  • 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.
  • Your content provider then returns a Cursor that points to all suggestions that are relevant to the search query text.
  • The Search Manager then displays the list of suggestions provided by the Cursor (as demonstrated in the screenshot to the right).

At this point, the following may happen:

  • 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.
  • If the user executes the search, the suggestions are ignored and the search is delivered to your searchable Activity using the normal ACTION_SEARCH Intent.
  • If the user selects a suggestion, a normal ACTION_SEARCH Intent is triggered, using the suggested text as the query.

As you'll soon discover, the 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.

Modifying the searchable configuration

First, you need to add the android:searchSuggestAuthority and android:searchSuggestSelection attributes to the <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="my.package.MySuggestionProvider"
    android:searchSuggestSelection=" ?" >
</searchable>

The value for 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).

The value for 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).

Creating a Content Provider

The content provider that you need for recent query suggestions must be an implementation of 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 = "my.package.MySuggestionProvider";
    public final static int MODE = DATABASE_MODE_QUERIES;

    public MySuggestionProvider() {
        setupSuggestions(AUTHORITY, MODE);
    }
}

The call to 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 DATABASE_MODE_QUERIES and can optionally include 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:

public final static int MODE = DATABASE_MODE_QUERIES | DATABASE_MODE_2LINES;

In the following section, you'll see how to save both lines of text.

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:

<application>
    <provider android:name=".MySuggestionProvider"
              android:authorities="my.package.authority" />
    ...
</application>

Saving queries

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 SearchRecentSuggestions and call 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 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);
    }
}

Notice that the SearchRecentSuggestionsProvider constructor requires the same authority and database mode declared by your content provider.

The 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 DATABASE_MODE_2LINES. If you have enabled two-line mode, then the query text will be matched against this second line as well.

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.

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 recent queries, simply call clearHistory(). For example:

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

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.

↑ Go to top

← Back to Search