1 /* 2 * Copyright (C) 2010 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17 package com.android.common; 18 19 import android.app.SearchManager; 20 import android.app.SearchableInfo; 21 import android.content.ContentResolver; 22 import android.content.Context; 23 import android.database.Cursor; 24 import android.net.Uri; 25 26 /** 27 * Utilities for search implementations. 28 * 29 * @see android.app.SearchManager 30 */ 31 public class Search { 32 33 /** 34 * Key for the source identifier set by the application that launched a search intent. 35 * The identifier is search-source specific string. It can be used 36 * by the search provider to keep statistics of where searches are started from. 37 * 38 * The source identifier is stored in the {@link android.app.SearchManager#APP_DATA} 39 * Bundle in {@link android.content.Intent#ACTION_SEARCH} and 40 * {@link android.content.Intent#ACTION_WEB_SEARCH} intents. 41 */ 42 public final static String SOURCE = "source"; 43 44 /** 45 * Column name for suggestions cursor. <i>Optional.</i> This column may be 46 * used to specify the time in {@link System#currentTimeMillis 47 * System.currentTimeMillis()} (wall time in UTC) when an item was last 48 * accessed within the results-providing application. If set, this may be 49 * used to show more-recently-used items first. 50 * 51 * See {@code SearchManager.SUGGEST_COLUMN_LAST_ACCESS_HINT} in ICS. 52 */ 53 public final static String SUGGEST_COLUMN_LAST_ACCESS_HINT = "suggest_last_access_hint"; 54 Search()55 private Search() { } // don't instantiate 56 57 /** 58 * Gets a cursor with search suggestions. 59 * 60 * @param searchable Information about how to get the suggestions. 61 * @param query The search text entered (so far). 62 * @return a cursor with suggestions, or <code>null</null> the suggestion query failed. 63 */ getSuggestions(Context context, SearchableInfo searchable, String query)64 public static Cursor getSuggestions(Context context, SearchableInfo searchable, String query) { 65 return getSuggestions(context, searchable, query, -1); 66 } 67 68 /** 69 * Gets a cursor with search suggestions. 70 * 71 * @param searchable Information about how to get the suggestions. 72 * @param query The search text entered (so far). 73 * @param limit The query limit to pass to the suggestion provider. This is advisory, 74 * the returned cursor may contain more rows. Pass {@code -1} for no limit. 75 * @return a cursor with suggestions, or <code>null</null> the suggestion query failed. 76 */ getSuggestions(Context context, SearchableInfo searchable, String query, int limit)77 public static Cursor getSuggestions(Context context, SearchableInfo searchable, 78 String query, int limit) { 79 if (searchable == null) { 80 return null; 81 } 82 83 String authority = searchable.getSuggestAuthority(); 84 if (authority == null) { 85 return null; 86 } 87 88 Uri.Builder uriBuilder = new Uri.Builder() 89 .scheme(ContentResolver.SCHEME_CONTENT) 90 .authority(authority) 91 .query("") // TODO: Remove, workaround for a bug in Uri.writeToParcel() 92 .fragment(""); // TODO: Remove, workaround for a bug in Uri.writeToParcel() 93 94 // if content path provided, insert it now 95 final String contentPath = searchable.getSuggestPath(); 96 if (contentPath != null) { 97 uriBuilder.appendEncodedPath(contentPath); 98 } 99 100 // append standard suggestion query path 101 uriBuilder.appendPath(SearchManager.SUGGEST_URI_PATH_QUERY); 102 103 // get the query selection, may be null 104 String selection = searchable.getSuggestSelection(); 105 // inject query, either as selection args or inline 106 String[] selArgs = null; 107 if (selection != null) { 108 selArgs = new String[] { query }; 109 } else { // no selection, use REST pattern 110 uriBuilder.appendPath(query); 111 } 112 113 if (limit > 0) { 114 uriBuilder.appendQueryParameter(SearchManager.SUGGEST_PARAMETER_LIMIT, 115 String.valueOf(limit)); 116 } 117 118 Uri uri = uriBuilder.build(); 119 120 // finally, make the query 121 return context.getContentResolver().query(uri, null, selection, selArgs, null); 122 } 123 124 } 125