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