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 <searchable>} element in your 101 searchable configuration file. For example:</p> 102 103 <pre> 104 <?xml version="1.0" encoding="utf-8"?> 105 <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 </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 <application> 162 <provider android:name=".MySuggestionProvider" 163 android:authorities="my.package.authority" /> 164 ... 165 </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 @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