8

I've read all of the documentation online about building search interfaces and adding custom suggestions... but I'm still unclear on how this works. The documentation says that I must "Build a table (such as in an SQLiteDatabase) for your suggestions and format the table with required columns". I'm assuming the system will eventually fill this table with the appropriate suggestions on its own... but which process/class is responsible for this, and when will the actual insertions occur (before any query is made by the user, after a query has been made by the user, etc.)?

And while I'm asking a question up here, if someone could clarify the difference between an AutoCompleteTextView and a SearchView w/ custom suggestions... that'd be awesome. AutoCompleteTextView seems suspiciously easy to implement compared to the SearchView (which requires changes to be made to the ContentProvider, SQLiteDatabase helper class, etc.).

Alex Lockwood
  • 83,063
  • 39
  • 206
  • 250

1 Answers1

5

You have to create a content provider which delivers your custom suggestions based on a query so far entered in the search view. In your searchable.xml you configure the minimum length of the search expression, which must be reached before asking for suggestions. This content provider is called a suggestion provider (it still extends ContentProvider). The content provider's authority is also configured in searchable.xml.

There is no limitation on how the suggestion provider computes its suggestions. You can search the web query a database or read a file. But the answer to the query is in the format of a table. If the suggestions is directly queried from a database you can use the cursor answered by the database query to deliver the result in the content provider's query() method. If the result is computed from one or more sources you can create a table on the fly by using a MatrixCursor.

The rows of the answer from the suggestion provider are used by the search mechanism to display the suggestion, they are stored in a table. The format of the rows is as follows:

private static final String[] COLUMNS = {
    "_id",
    SearchManager.SUGGEST_COLUMN_ICON_1,        // ID of a drawable (icon) as String
    SearchManager.SUGGEST_COLUMN_TEXT_1,        // main text for suggestion display
    SearchManager.SUGGEST_COLUMN_TEXT_2,        // secondary text for suggestion display
    SearchManager.SUGGEST_COLUMN_INTENT_DATA,   // this could be an URI to access the suggestion as used in an intent with a VIEW action
    SearchManager.SUGGEST_COLUMN_INTENT_ACTION, // this could be Intent.ACTION_VIEW
    SearchManager.SUGGEST_COLUMN_SHORTCUT_ID    // e.g. SearchManager.SUGGEST_NEVER_MAKE_SHORTCUT
};

Searching is described here in more detail: http://developer.android.com/guide/topics/search/index.html

Stefan
  • 4,645
  • 1
  • 19
  • 35
  • OK... I think I am beginning to understand. But when/where are suggestions inserted into a table, and what format do the suggestions have? That's what I'm confused about. I would assume that this sort of "auto-complete"/suggestion feature would be implemented using a Trie or something... – Alex Lockwood Jan 29 '12 at 16:08
  • i.e. what does the suggestion table look like? or is the resulting table not necessarily human-readable? when is this table created (do you need to create it using `execSQL`)? – Alex Lockwood Jan 29 '12 at 16:23
  • i would like to get a simple "auto-complete/suggest-complete" search feature over a certain column in my database... but if it means changing up my entire database and messing with a bunch of files, i could always return to it at a later date (although i still believe this thing shouldn't take that long to implement! all i want is the system to auto-complete over a single column of strings in my database!). – Alex Lockwood Jan 29 '12 at 16:27
  • I updated the answer wrt. to the suggestion rows (table). The word table is used only to refer to the schema (columns, see answer). It is not a table in database you are using or which you have to manage. You need not change your database: You just have to write a suggestion provider which may use your database to compute the suggestion. But the result must be transformed into the given columns. Please note that search and auto-completion may work differently (I have not used auto-completion yet, so I have not bothered to research how it works). – Stefan Jan 29 '12 at 16:55
  • Awesome, I think I got it. Let me make sure I'm not misunderstanding one more time. *(1)* You type something in the search bar. *(2)* The SearchManager sees this and queries your ContentProvider with the appropriate `SearchManager.SUGGEST_URI_PATH_QUERY` uri. *(3)* By default, the query text will be appended to this uri. You would then query the database for the given query text and return a Cursor over the suggestions. – Alex Lockwood Jan 29 '12 at 17:43
  • One last question: how do you perform the query for suggestions once you have the query text? Do I just need to search the suggestions column for potential matches? i.e. pass in a "where" clause such as "suggest_column = queryText"? will this return all of the correct matches for me? – Alex Lockwood Jan 29 '12 at 17:48
  • I really appreciate your help by the way... thanks so much for walking me through this! (I'd have up-voted/accepted you by now but believe it or not I've already used all 30 of my votes today... give it a couple more hours :P) – Alex Lockwood Jan 29 '12 at 17:49
  • Your question two comments above: extract the search text which the user entered until now from the URI (similar to the ID in the URI path of a "normal" content provider. Then query the database using this text. You can query what ever you want. In may example I assume the search text is the prefix of a call-sign and I query my flight log for matching entries. For every match construct a row in the answer of the suggestion provider (the example uses the MatrixCursor to do that). I added a more detailed column description in the example, see above. – Stefan Jan 30 '12 at 07:53