Home | History | Annotate | Download | only in search
      1 page.title=Adding Recent Query Suggestions
      2 parent.title=Search
      3 parent.link=index.html
      4 @jd:body
      5 
      6 <div id="qv-wrapper">
      7 <div id="qv">
      8 <h2>Key classes</h2>
      9 <ol>
     10 <li>{@link android.provider.SearchRecentSuggestions}</li>
     11 <li>{@link android.content.SearchRecentSuggestionsProvider}</li>
     12 </ol>
     13 <h2>In this document</h2>
     14 <ol>
     15 <li><a href="#TheBasics">The Basics</a></li>
     16 <li><a href="#RecentQuerySearchableConfiguration">Modifying the searchable
     17 configuration</a></li>
     18 <li><a href="#RecentQueryContentProvider">Creating a Content Provider</a></li>
     19 <li><a href="#SavingQueries">Saving queries</a></li>
     20 <li><a href="#ClearingSuggestionData">Clearing the suggestion data</a></li>
     21 </ol>
     22 <h2>See also</h2>
     23 <ol>
     24 <li><a href="searchable-config.html">Searchable Configuration</a></li>
     25 </ol>
     26 </div>
     27 </div>
     28 
     29 <p>The Android search framework provides the ability for your application to
     30 provide suggestions while the user types into the Android search dialog. In this guide, you'll learn
     31 how to create recent query suggestions. These are suggestions based
     32 on queries previously entered by the user. So, if the user previously searched for "puppies" then it
     33 will appear as a suggestion as they begin typing the same string of text. The screenshot below
     34 shows an example of recent query suggestions.</p>
     35 
     36 <p>Before you begin, you need to have implemented the Android search dialog for searches in your
     37 application. If you haven't done this, see <a href="search-dialog.html">Using the Android Search
     38 Dialog</a>.</p>
     39 
     40 
     41 <h2 id="TheBasics">The Basics</h2>
     42 
     43 <img src="{@docRoot}images/search/search-suggest-recent-queries.png" alt="" height="417"
     44 style="float:right;clear:right;" />
     45 
     46 <p>Recent query suggestions are simply saved searches. When the user selects one of
     47 the suggestions, your searchable Activity will receive a normal {@link
     48 android.content.Intent#ACTION_SEARCH} Intent with the suggestion as the search query, which your
     49 searchable Activity will already handle.</p>
     50 
     51 <p>To provide recent queries suggestions, you need to:</p>
     52 
     53 <ul>
     54   <li>Implement a basic searchable Activity, as documented in <a
     55 href="{@docRoot}guide/topics/search/search-dialog.html">Using the Android Search Dialog</a>.</li>
     56   <li>Create a content provider that extends {@link
     57 android.content.SearchRecentSuggestionsProvider} and declare it in your application manifest.</li>
     58   <li>Modify the searchable configuration with information about the content provider.</li>
     59   <li>Save queries to your content provider each time a search is made.</li>
     60 </ul>
     61 
     62 <p>Just like the Search Manager handles the rendering of the search dialog, it will also do the work
     63 to display all search suggestions below the search dialog. All you need to do is provide a source
     64 from which the suggestions can be retrieved.</p>
     65 
     66 <p>When the Search Manager identifies that your Activity is searchable and also provides search
     67 suggestions, the following procedure will take place as soon as the user types into the Android
     68 search box:</p>
     69 
     70 <ul>
     71   <li>The Search Manager takes the search query text (whatever has been typed so far) and performs a
     72 query to the content provider that manages your suggestions.</li>
     73   <li>Your content provider then returns a {@link android.database.Cursor} that points to all
     74 suggestions that are relevant to the search query text.</li>
     75   <li>The Search Manager then displays the list of suggestions provided by the Cursor (as
     76 demonstrated in the screenshot to the right).</li>
     77 </ul>
     78 
     79 <p>At this point, the following may happen:</p>
     80 
     81 <ul>
     82   <li>If the user types another key, or changes the query in any way, the above steps are repeated
     83 and the suggestion list is updated as appropriate.</li>
     84   <li>If the user executes the search, the suggestions are ignored and the search is delivered
     85 to your searchable Activity using the normal {@link android.content.Intent#ACTION_SEARCH}
     86 Intent.</li>
     87   <li>If the user selects a suggestion, a normal
     88 {@link android.content.Intent#ACTION_SEARCH} Intent is triggered, using the suggested text as the
     89 query.</li>
     90 </ul>
     91 
     92 <p>As you'll soon discover, the {@link android.content.SearchRecentSuggestionsProvider} class that
     93 you'll extend for your content provider will automatically do the work described above, so there's
     94 actually very little code to write.</p>
     95 
     96 
     97 <h2 id="RecentQuerySearchableConfiguration">Modifying the searchable configuration</h2>
     98 
     99 <p>First, you need to add the {@code android:searchSuggestAuthority} and
    100 {@code android:searchSuggestSelection} attributes to the {@code &lt;searchable&gt;} element in your
    101 searchable configuration file. For example:</p>
    102 
    103 <pre>
    104 &lt;?xml version="1.0" encoding="utf-8"?>
    105 &lt;searchable xmlns:android="http://schemas.android.com/apk/res/android"
    106     android:label="@string/app_label"
    107     android:hint="@string/search_hint"
    108     android:searchSuggestAuthority="my.package.MySuggestionProvider"
    109     android:searchSuggestSelection=" ?" >
    110 &lt;/searchable>
    111 </pre>
    112 
    113 <p>The value for {@code android:searchSuggestAuthority} should be a fully-qualified name for
    114 your content provider: your application package name followed by the name of your content provider.
    115 This string must match the authority used in the content provider (discussed in the next section).
    116 </p>
    117 
    118 <p>The value for {@code android:searchSuggestSelection} must be a single question-mark, preceded by
    119 a space (" ?"), which is simply a placeholder for the SQLite selection argument (which will be
    120 automatically replaced by the query text entered by the user).</p>
    121 
    122 
    123 <h2 id="RecentQueryContentProvider">Creating a Content Provider</h2>
    124 
    125 <p>The content provider that you need for recent query suggestions must be an implementation
    126 of {@link android.content.SearchRecentSuggestionsProvider}. This class does practically everything
    127 for you. All you have to do is write a class constructor that executes one line of code.</p>
    128 
    129 <p>For example, here's a complete implementation of a content provider for recent query
    130 suggestions:</p>
    131 
    132 <pre>
    133 public class MySuggestionProvider extends SearchRecentSuggestionsProvider {
    134     public final static String AUTHORITY = "my.package.MySuggestionProvider";
    135     public final static int MODE = DATABASE_MODE_QUERIES;
    136 
    137     public MySuggestionProvider() {
    138         setupSuggestions(AUTHORITY, MODE);
    139     }
    140 }
    141 </pre>
    142 
    143 <p>The call to {@link android.content.SearchRecentSuggestionsProvider#setupSuggestions(String,int)}
    144 passes the name of the search authority (matching the one in the searchable configuration) and a
    145 database mode. The database mode must include {@link
    146 android.content.SearchRecentSuggestionsProvider#DATABASE_MODE_QUERIES} and can optionally include
    147 {@link
    148 android.content.SearchRecentSuggestionsProvider#DATABASE_MODE_2LINES}, which will add another column
    149 to the suggestions table that allows you to provide a second line of text with each suggestion. For
    150 example:</p>
    151 <pre>
    152 public final static int MODE = DATABASE_MODE_QUERIES | DATABASE_MODE_2LINES;
    153 </pre>
    154 
    155 <p>In the following section, you'll see how to save both lines of text.</p>
    156 
    157 <p>Now simply declare the content provider in your application manifest with the same authority
    158 string used in the class (and in the searchable configuration). For example:</p>
    159 
    160 <pre>
    161 &lt;application>
    162     &lt;provider android:name=".MySuggestionProvider"
    163               android:authorities="my.package.authority" />
    164     ...
    165 &lt;/application>
    166 </pre>
    167 
    168 
    169 <h2 id="SavingQueries">Saving queries</h2>
    170 
    171 <p>In order to populate your collection of recent queries, you need to add each query
    172 received by your searchable Activity to the content provider you've just built. To do this, create
    173 an instance of {@link
    174 android.provider.SearchRecentSuggestions} and call {@link
    175 android.provider.SearchRecentSuggestions#saveRecentQuery(String,String)} each time your searchable
    176 Activity receives a query. For example, here's how you can save the query during your
    177 Activity's {@link android.app.Activity#onCreate(Bundle) onCreate()} method:</p>
    178 
    179 <pre>
    180 &#64;Override
    181 public void onCreate(Bundle savedInstanceState) {
    182     super.onCreate(savedInstanceState);
    183     setContentView(R.layout.main);
    184 
    185     Intent Intent  = getIntent();
    186 
    187     if (Intent.ACTION_SEARCH.equals(Intent .getAction())) {
    188         String query = Intent .getStringExtra(SearchManager.QUERY);
    189         SearchRecentSuggestions suggestions = new SearchRecentSuggestions(this,
    190                 MySuggestionProvider.AUTHORITY, MySuggestionProvider.MODE);
    191         suggestions.saveRecentQuery(query, null);
    192     }
    193 }
    194 </pre>
    195 
    196 <p>Notice that the {@link android.content.SearchRecentSuggestionsProvider} constructor requires the
    197 same authority and database mode declared by your content provider.</p>
    198 
    199 <p>The {@link android.provider.SearchRecentSuggestions#saveRecentQuery(String,String)} method takes
    200 the search query string as the first parameter and, optionally, a second string to include as the
    201 second line of the suggestion. The second parameter is only used if you've enabled two-line mode
    202 for the search suggestions with {@link
    203 android.content.SearchRecentSuggestionsProvider#DATABASE_MODE_2LINES}. If you have enabled
    204 two-line mode, then the query text will be matched against this second line as well.</p>
    205 
    206 <p>That's all that's needed to build a recent queries suggestion provider. However, there's one
    207 other important thing to do: provide the ability for the user to clear this search history.</p>
    208 
    209 
    210 <h2 id="ClearingSuggestionData">Clearing the suggestion data</h2>
    211 
    212 <p>To protect the user's privacy, you should always provide a way for the user to clear the recent
    213 query suggestions. To clear the recent queries, simply call {@link
    214 android.provider.SearchRecentSuggestions#clearHistory()}. For example:</p>
    215 
    216 <pre>
    217 SearchRecentSuggestions suggestions = new SearchRecentSuggestions(this,
    218         HelloSuggestionProvider.AUTHORITY, HelloSuggestionProvider.MODE);
    219 suggestions.clearHistory();
    220 </pre>
    221 
    222 <p>Simply execute this from your choice of a "Clear Search History" menu item,
    223 preference item, or button. You should also provide a confirmation dialog when this is pressed, to
    224 verify that the user wants to delete their search history.</p>
    225 
    226