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 <application> 145 <provider android:name=".MySuggestionProvider" 146 android:authorities="com.example.MySuggestionProvider" /> 147 ... 148 </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 <searchable>} element in your searchable configuration file. For example:</p> 158 159 <pre> 160 <?xml version="1.0" encoding="utf-8"?> 161 <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 </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 @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