I’m working on search activity for Beermapa and because I did not find any topic covering reading access to SearchRecentSuggestions and I needed to load saved suggestions and fill a ListView with them, so I did some research and wrote this post.

What I want to achieve is an input for writing search query, which displays custom suggestions (based on searching query) and also ListView placed right under input box, which displays recent search queries.

SearchView with ListView

SearchView with ListView

My first try was with EditText and TextWatcher, which after each written character filtered my listAdapter backing ListView, something like this:

searchEditText.addTextChangedListener(new TextWatcher() {
    public void afterTextChanged(Editable s) {}

    public void beforeTextChanged(CharSequence s, int start, int count, int after) {}

    public void onTextChanged(CharSequence s, int start, int before, int count) {

But since Android has pretty good Search Interface, I was wondering how to use it with my search (because of possible future use of voice search etc.). Adding recent query suggestion is described in tutorial, also custom suggestion is. But there is nothing about how to access saved queries another way then in SearchView whispering box. Saving is really easy:

SearchRecentSuggestions suggestions = new SearchRecentSuggestions(getApplicationContext(), MySuggestionProvider.AUTHORITY, MySuggestionProvider.MODE);

suggestions.saveRecentQuery(query, null);

First solution which came on my mind was to implement own saveRecentQuery routine, which saves last queries to local database, but that’s not the way – why to write already written code again?

Finally – there is possibility to access those saved queries through ContentResolver, which returns Cursor:

ContentResolver contentResolver = getApplicationContext().getContentResolver();

String contentUri = "content://" + MySuggestionProvider.AUTHORITY + '/' + SearchManager.SUGGEST_URI_PATH_QUERY;
Uri uri = Uri.parse(uriStr);

Cursor cursor = contentResolver.query(uri, null, null, new String[] { query }, null);

Where query is String representing searching query, or null for returning all records. Now with received cursor it’s simple to populate ListView:


String[] columns = new String[] { SearchManager.SUGGEST_COLUMN_TEXT_1 };
int[] views = new int[] { R.id.name };

ListAdapter listAdapter = new SimpleCursorAdapter(this, R.layout.component_pub_row, cursor, columns, views, 0);

Note that last parameter in SimpleCursorAdapter – it’s there because of deprecation of constructor with FLAG_AUTO_REQUERY, for more details see this Stack Overflow topic.