SearchRecentSuggestions.java revision 3aef8e1d1b2f0b87d470bcccf37ba4ebb6560c45
19066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project/* 29066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Copyright (C) 2008 The Android Open Source Project 39066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 49066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Licensed under the Apache License, Version 2.0 (the "License"); 59066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * you may not use this file except in compliance with the License. 69066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * You may obtain a copy of the License at 79066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 89066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * http://www.apache.org/licenses/LICENSE-2.0 99066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Unless required by applicable law or agreed to in writing, software 119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * distributed under the License is distributed on an "AS IS" BASIS, 129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * See the License for the specific language governing permissions and 149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * limitations under the License. 159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectpackage android.provider; 189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.content.ContentResolver; 209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.content.ContentValues; 219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.content.Context; 229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.content.SearchRecentSuggestionsProvider; 239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.net.Uri; 249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.text.TextUtils; 259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.util.Log; 269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 27553a53ef9ff789dff8b5a74dfea4d6f37feeb263Ficus Kirkpatrickimport java.util.concurrent.Semaphore; 28553a53ef9ff789dff8b5a74dfea4d6f37feeb263Ficus Kirkpatrick 299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project/** 30553a53ef9ff789dff8b5a74dfea4d6f37feeb263Ficus Kirkpatrick * This is a utility class providing access to 319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * {@link android.content.SearchRecentSuggestionsProvider}. 32553a53ef9ff789dff8b5a74dfea4d6f37feeb263Ficus Kirkpatrick * 339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * <p>Unlike some utility classes, this one must be instantiated and properly initialized, so that 349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * it can be configured to operate with the search suggestions provider that you have created. 35553a53ef9ff789dff8b5a74dfea4d6f37feeb263Ficus Kirkpatrick * 369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * <p>Typically, you will do this in your searchable activity, each time you receive an incoming 379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * {@link android.content.Intent#ACTION_SEARCH ACTION_SEARCH} Intent. The code to record each 389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * incoming query is as follows: 399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * <pre class="prettyprint"> 40553a53ef9ff789dff8b5a74dfea4d6f37feeb263Ficus Kirkpatrick * SearchSuggestions suggestions = new SearchSuggestions(this, 419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * MySuggestionsProvider.AUTHORITY, MySuggestionsProvider.MODE); 429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * suggestions.saveRecentQuery(queryString, null); 439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * </pre> 44553a53ef9ff789dff8b5a74dfea4d6f37feeb263Ficus Kirkpatrick * 459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * <p>For a working example, see SearchSuggestionSampleProvider and SearchQueryResults in 469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * samples/ApiDemos/app. 473aef8e1d1b2f0b87d470bcccf37ba4ebb6560c45Joe Fernandez * 483aef8e1d1b2f0b87d470bcccf37ba4ebb6560c45Joe Fernandez * <div class="special reference"> 493aef8e1d1b2f0b87d470bcccf37ba4ebb6560c45Joe Fernandez * <h3>Developer Guides</h3> 503aef8e1d1b2f0b87d470bcccf37ba4ebb6560c45Joe Fernandez * <p>For information about using search suggestions in your application, read the 513aef8e1d1b2f0b87d470bcccf37ba4ebb6560c45Joe Fernandez * <a href="{@docRoot}guide/topics/search/adding-recent-query-suggestions.html">Adding Recent Query 523aef8e1d1b2f0b87d470bcccf37ba4ebb6560c45Joe Fernandez * Suggestions</a> developer guide.</p> 533aef8e1d1b2f0b87d470bcccf37ba4ebb6560c45Joe Fernandez * </div> 549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectpublic class SearchRecentSuggestions { 569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // debugging support 579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private static final String LOG_TAG = "SearchSuggestions"; 58553a53ef9ff789dff8b5a74dfea4d6f37feeb263Ficus Kirkpatrick 599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // This is a superset of all possible column names (need not all be in table) 609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private static class SuggestionColumns implements BaseColumns { 619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public static final String DISPLAY1 = "display1"; 629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public static final String DISPLAY2 = "display2"; 639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public static final String QUERY = "query"; 649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public static final String DATE = "date"; 659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 66553a53ef9ff789dff8b5a74dfea4d6f37feeb263Ficus Kirkpatrick 679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /* if you change column order you must also change indices below */ 689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * This is the database projection that can be used to view saved queries, when 709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * configured for one-line operation. 719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public static final String[] QUERIES_PROJECTION_1LINE = new String[] { 73553a53ef9ff789dff8b5a74dfea4d6f37feeb263Ficus Kirkpatrick SuggestionColumns._ID, 749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project SuggestionColumns.DATE, 75553a53ef9ff789dff8b5a74dfea4d6f37feeb263Ficus Kirkpatrick SuggestionColumns.QUERY, 769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project SuggestionColumns.DISPLAY1, 779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project }; 78553a53ef9ff789dff8b5a74dfea4d6f37feeb263Ficus Kirkpatrick 799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /* if you change column order you must also change indices below */ 809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * This is the database projection that can be used to view saved queries, when 829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * configured for two-line operation. 839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public static final String[] QUERIES_PROJECTION_2LINE = new String[] { 85553a53ef9ff789dff8b5a74dfea4d6f37feeb263Ficus Kirkpatrick SuggestionColumns._ID, 869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project SuggestionColumns.DATE, 87553a53ef9ff789dff8b5a74dfea4d6f37feeb263Ficus Kirkpatrick SuggestionColumns.QUERY, 889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project SuggestionColumns.DISPLAY1, 899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project SuggestionColumns.DISPLAY2, 909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project }; 919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /* these indices depend on QUERIES_PROJECTION_xxx */ 939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** Index into the provided query projections. For use with Cursor.update methods. */ 949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public static final int QUERIES_PROJECTION_DATE_INDEX = 1; 959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** Index into the provided query projections. For use with Cursor.update methods. */ 969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public static final int QUERIES_PROJECTION_QUERY_INDEX = 2; 979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** Index into the provided query projections. For use with Cursor.update methods. */ 989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public static final int QUERIES_PROJECTION_DISPLAY1_INDEX = 3; 999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** Index into the provided query projections. For use with Cursor.update methods. */ 1009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public static final int QUERIES_PROJECTION_DISPLAY2_INDEX = 4; // only when 2line active 1019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /* 1039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Set a cap on the count of items in the suggestions table, to 1049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * prevent db and layout operations from dragging to a crawl. Revisit this 1059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * cap when/if db/layout performance improvements are made. 1069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 1079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private static final int MAX_HISTORY_COUNT = 250; 108553a53ef9ff789dff8b5a74dfea4d6f37feeb263Ficus Kirkpatrick 1099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // client-provided configuration values 110553a53ef9ff789dff8b5a74dfea4d6f37feeb263Ficus Kirkpatrick private final Context mContext; 111553a53ef9ff789dff8b5a74dfea4d6f37feeb263Ficus Kirkpatrick private final String mAuthority; 112553a53ef9ff789dff8b5a74dfea4d6f37feeb263Ficus Kirkpatrick private final boolean mTwoLineDisplay; 113553a53ef9ff789dff8b5a74dfea4d6f37feeb263Ficus Kirkpatrick private final Uri mSuggestionsUri; 114553a53ef9ff789dff8b5a74dfea4d6f37feeb263Ficus Kirkpatrick 115553a53ef9ff789dff8b5a74dfea4d6f37feeb263Ficus Kirkpatrick /** Released once per completion of async write. Used for tests. */ 116553a53ef9ff789dff8b5a74dfea4d6f37feeb263Ficus Kirkpatrick private static final Semaphore sWritesInProgress = new Semaphore(0); 1179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 1199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Although provider utility classes are typically static, this one must be constructed 120553a53ef9ff789dff8b5a74dfea4d6f37feeb263Ficus Kirkpatrick * because it needs to be initialized using the same values that you provided in your 121553a53ef9ff789dff8b5a74dfea4d6f37feeb263Ficus Kirkpatrick * {@link android.content.SearchRecentSuggestionsProvider}. 122553a53ef9ff789dff8b5a74dfea4d6f37feeb263Ficus Kirkpatrick * 1239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @param authority This must match the authority that you've declared in your manifest. 1249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @param mode You can use mode flags here to determine certain functional aspects of your 1259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * database. Note, this value should not change from run to run, because when it does change, 1269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * your suggestions database may be wiped. 127553a53ef9ff789dff8b5a74dfea4d6f37feeb263Ficus Kirkpatrick * 1289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @see android.content.SearchRecentSuggestionsProvider 1299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @see android.content.SearchRecentSuggestionsProvider#setupSuggestions 1309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 1319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public SearchRecentSuggestions(Context context, String authority, int mode) { 132553a53ef9ff789dff8b5a74dfea4d6f37feeb263Ficus Kirkpatrick if (TextUtils.isEmpty(authority) || 1339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project ((mode & SearchRecentSuggestionsProvider.DATABASE_MODE_QUERIES) == 0)) { 1349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project throw new IllegalArgumentException(); 1359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 1369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // unpack mode flags 1379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mTwoLineDisplay = (0 != (mode & SearchRecentSuggestionsProvider.DATABASE_MODE_2LINES)); 138553a53ef9ff789dff8b5a74dfea4d6f37feeb263Ficus Kirkpatrick 1399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // saved values 1409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mContext = context; 1419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mAuthority = new String(authority); 142553a53ef9ff789dff8b5a74dfea4d6f37feeb263Ficus Kirkpatrick 1439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // derived values 1449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mSuggestionsUri = Uri.parse("content://" + mAuthority + "/suggestions"); 1459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 1469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 148553a53ef9ff789dff8b5a74dfea4d6f37feeb263Ficus Kirkpatrick * Add a query to the recent queries list. Returns immediately, performing the save 149553a53ef9ff789dff8b5a74dfea4d6f37feeb263Ficus Kirkpatrick * in the background. 150553a53ef9ff789dff8b5a74dfea4d6f37feeb263Ficus Kirkpatrick * 1519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @param queryString The string as typed by the user. This string will be displayed as 1529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * the suggestion, and if the user clicks on the suggestion, this string will be sent to your 1539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * searchable activity (as a new search query). 154553a53ef9ff789dff8b5a74dfea4d6f37feeb263Ficus Kirkpatrick * @param line2 If you have configured your recent suggestions provider with 155553a53ef9ff789dff8b5a74dfea4d6f37feeb263Ficus Kirkpatrick * {@link android.content.SearchRecentSuggestionsProvider#DATABASE_MODE_2LINES}, you can 1569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * pass a second line of text here. It will be shown in a smaller font, below the primary 1579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * suggestion. When typing, matches in either line of text will be displayed in the list. 1589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * If you did not configure two-line mode, or if a given suggestion does not have any 1599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * additional text to display, you can pass null here. 1609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 161553a53ef9ff789dff8b5a74dfea4d6f37feeb263Ficus Kirkpatrick public void saveRecentQuery(final String queryString, final String line2) { 1629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (TextUtils.isEmpty(queryString)) { 1639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return; 1649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 1659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (!mTwoLineDisplay && !TextUtils.isEmpty(line2)) { 1669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project throw new IllegalArgumentException(); 1679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 168553a53ef9ff789dff8b5a74dfea4d6f37feeb263Ficus Kirkpatrick 169553a53ef9ff789dff8b5a74dfea4d6f37feeb263Ficus Kirkpatrick new Thread("saveRecentQuery") { 170553a53ef9ff789dff8b5a74dfea4d6f37feeb263Ficus Kirkpatrick @Override 171553a53ef9ff789dff8b5a74dfea4d6f37feeb263Ficus Kirkpatrick public void run() { 172553a53ef9ff789dff8b5a74dfea4d6f37feeb263Ficus Kirkpatrick saveRecentQueryBlocking(queryString, line2); 173553a53ef9ff789dff8b5a74dfea4d6f37feeb263Ficus Kirkpatrick sWritesInProgress.release(); 174553a53ef9ff789dff8b5a74dfea4d6f37feeb263Ficus Kirkpatrick } 175553a53ef9ff789dff8b5a74dfea4d6f37feeb263Ficus Kirkpatrick }.start(); 176553a53ef9ff789dff8b5a74dfea4d6f37feeb263Ficus Kirkpatrick } 177553a53ef9ff789dff8b5a74dfea4d6f37feeb263Ficus Kirkpatrick 178553a53ef9ff789dff8b5a74dfea4d6f37feeb263Ficus Kirkpatrick // Visible for testing. 179553a53ef9ff789dff8b5a74dfea4d6f37feeb263Ficus Kirkpatrick void waitForSave() { 180553a53ef9ff789dff8b5a74dfea4d6f37feeb263Ficus Kirkpatrick // Acquire writes semaphore until there is nothing available. 181553a53ef9ff789dff8b5a74dfea4d6f37feeb263Ficus Kirkpatrick // This is to clean up after any previous callers to saveRecentQuery 182553a53ef9ff789dff8b5a74dfea4d6f37feeb263Ficus Kirkpatrick // who did not also call waitForSave(). 183553a53ef9ff789dff8b5a74dfea4d6f37feeb263Ficus Kirkpatrick do { 184553a53ef9ff789dff8b5a74dfea4d6f37feeb263Ficus Kirkpatrick sWritesInProgress.acquireUninterruptibly(); 185553a53ef9ff789dff8b5a74dfea4d6f37feeb263Ficus Kirkpatrick } while (sWritesInProgress.availablePermits() > 0); 186553a53ef9ff789dff8b5a74dfea4d6f37feeb263Ficus Kirkpatrick } 187553a53ef9ff789dff8b5a74dfea4d6f37feeb263Ficus Kirkpatrick 188553a53ef9ff789dff8b5a74dfea4d6f37feeb263Ficus Kirkpatrick private void saveRecentQueryBlocking(String queryString, String line2) { 1899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project ContentResolver cr = mContext.getContentResolver(); 1909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project long now = System.currentTimeMillis(); 191553a53ef9ff789dff8b5a74dfea4d6f37feeb263Ficus Kirkpatrick 1929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // Use content resolver (not cursor) to insert/update this query 1939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project try { 1949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project ContentValues values = new ContentValues(); 1959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project values.put(SuggestionColumns.DISPLAY1, queryString); 1969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (mTwoLineDisplay) { 1979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project values.put(SuggestionColumns.DISPLAY2, line2); 1989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 1999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project values.put(SuggestionColumns.QUERY, queryString); 2009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project values.put(SuggestionColumns.DATE, now); 2019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project cr.insert(mSuggestionsUri, values); 2029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } catch (RuntimeException e) { 2039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project Log.e(LOG_TAG, "saveRecentQuery", e); 2049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 205553a53ef9ff789dff8b5a74dfea4d6f37feeb263Ficus Kirkpatrick 2069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // Shorten the list (if it has become too long) 2079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project truncateHistory(cr, MAX_HISTORY_COUNT); 2089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 209553a53ef9ff789dff8b5a74dfea4d6f37feeb263Ficus Kirkpatrick 2109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 2119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Completely delete the history. Use this call to implement a "clear history" UI. 212553a53ef9ff789dff8b5a74dfea4d6f37feeb263Ficus Kirkpatrick * 2139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Any application that implements search suggestions based on previous actions (such as 2149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * recent queries, page/items viewed, etc.) should provide a way for the user to clear the 2159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * history. This gives the user a measure of privacy, if they do not wish for their recent 2169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * searches to be replayed by other users of the device (via suggestions). 2179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 2189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public void clearHistory() { 2199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project ContentResolver cr = mContext.getContentResolver(); 2209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project truncateHistory(cr, 0); 2219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 2229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 2239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 2249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Reduces the length of the history table, to prevent it from growing too large. 225553a53ef9ff789dff8b5a74dfea4d6f37feeb263Ficus Kirkpatrick * 2269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @param cr Convenience copy of the content resolver. 2279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @param maxEntries Max entries to leave in the table. 0 means remove all entries. 2289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 2299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project protected void truncateHistory(ContentResolver cr, int maxEntries) { 2309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (maxEntries < 0) { 2319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project throw new IllegalArgumentException(); 2329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 233553a53ef9ff789dff8b5a74dfea4d6f37feeb263Ficus Kirkpatrick 2349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project try { 2359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // null means "delete all". otherwise "delete but leave n newest" 2369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project String selection = null; 2379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (maxEntries > 0) { 2389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project selection = "_id IN " + 2399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project "(SELECT _id FROM suggestions" + 2409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project " ORDER BY " + SuggestionColumns.DATE + " DESC" + 2419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project " LIMIT -1 OFFSET " + String.valueOf(maxEntries) + ")"; 2429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 2439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project cr.delete(mSuggestionsUri, selection, null); 2449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } catch (RuntimeException e) { 2459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project Log.e(LOG_TAG, "truncateHistory", e); 2469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 2479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 2489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project} 249