新增自訂搜尋建議
透過集合功能整理內容
你可以依據偏好儲存及分類內容。
試試 Compose
Jetpack Compose 是 Android 推薦的 UI 工具包。瞭解如何在 Compose 中新增搜尋功能。
您可以根據 Android 搜尋對話方塊或搜尋小工具中的近期搜尋查詢,提供搜尋建議。舉例來說,如果使用者查詢「小狗」,當他們再次輸入相同查詢時,系統就會顯示建議。圖 1 顯示搜尋對話方塊範例,其中包含最近查詢建議。
開始前,請先在應用程式中導入搜尋對話方塊或搜尋小工具,以進行基本搜尋。如需操作說明,請參閱「建立搜尋介面」。
基本概念
圖 1. 螢幕截圖:搜尋對話方塊,顯示最近的查詢建議。
近期搜尋建議是已儲存的搜尋查詢。使用者選取建議後,可搜尋的活動會收到 ACTION_SEARCH
意圖,建議會做為可搜尋活動已處理的搜尋查詢。
如要提供近期查詢建議,請按照下列步驟操作:
Android 系統會顯示搜尋對話方塊,並在對話方塊或搜尋小工具下方顯示搜尋建議。您提供來源,系統會從中擷取建議。
當系統判斷您的活動可供搜尋並提供搜尋建議時,使用者輸入查詢內容時會發生下列情況:
- 系統會擷取搜尋查詢文字 (使用者開始輸入的任何內容),並對含有建議的內容供應程式執行查詢。
- 內容供應商會傳回
Cursor
,指向與搜尋查詢文字相符的所有建議。
- 系統會顯示
Cursor
提供的建議清單。
顯示最近的查詢建議後,可能會發生下列情況:
- 如果使用者輸入其他鍵或以任何方式變更查詢,系統會重複上述步驟,並更新建議清單。
- 如果使用者執行搜尋,系統會忽略建議,並使用正常的
ACTION_SEARCH
意圖,將搜尋結果傳送至可搜尋的活動。
- 如果使用者選取建議,系統會將
ACTION_SEARCH
意圖傳送至可搜尋的活動,並以建議的文字做為查詢。
您為內容供應器擴充的 SearchRecentSuggestionsProvider
類別會自動執行上述步驟中的工作,因此您幾乎不需要編寫程式碼。
建立內容供應器
您需要內容供應器 (實作 SearchRecentSuggestionsProvider
),才能提供近期查詢建議。這個類別會為您處理所有事項。您只需要編寫類別建構函式,執行一行程式碼即可。
舉例來說,以下是最近查詢建議的內容供應器完整實作項目:
Kotlin
class MySuggestionProvider : SearchRecentSuggestionsProvider() {
init {
setupSuggestions(AUTHORITY, MODE)
}
companion object {
const val AUTHORITY = "com.example.MySuggestionProvider"
const val MODE: Int = SearchRecentSuggestionsProvider.DATABASE_MODE_QUERIES
}
}
Java
public class MySuggestionProvider extends SearchRecentSuggestionsProvider {
public final static String AUTHORITY = "com.example.MySuggestionProvider";
public final static int MODE = DATABASE_MODE_QUERIES;
public MySuggestionProvider() {
setupSuggestions(AUTHORITY, MODE);
}
}
對
setupSuggestions()
的呼叫會傳遞搜尋授權單位名稱和資料庫模式。搜尋授權可以是任何不重複的字串,但最佳做法是使用內容供應器的完整名稱,例如套件名稱,後面加上供應器的類別名稱。例如 "com.example.MySuggestionProvider"
。
資料庫模式必須包含 DATABASE_MODE_QUERIES
,且可視需要包含 DATABASE_MODE_2LINES
,這會在建議表格中新增資料欄,方便您為每項建議提供第二行文字。如要在每個建議中提供兩行文字,請參閱下列範例:
Kotlin
const val MODE: Int = DATABASE_MODE_QUERIES or DATABASE_MODE_2LINES
Java
public final static int MODE = DATABASE_MODE_QUERIES | DATABASE_MODE_2LINES;
在應用程式資訊清單中宣告內容供應器,並使用與 SearchRecentSuggestionsProvider
類別和可搜尋設定中相同的授權字串。例如:
<application>
<provider android:name=".MySuggestionProvider"
android:authorities="com.example.MySuggestionProvider" />
...
</application>
修改可供搜尋的設定
如要設定系統使用建議提供者,請在可搜尋的設定檔中,將 android:searchSuggestAuthority
和 android:searchSuggestSelection
屬性新增至 <searchable>
元素。例如:
<?xml version="1.0" encoding="utf-8"?>
<searchable xmlns:android="http://schemas.android.com/apk/res/android"
android:label="@string/app_label"
android:hint="@string/search_hint"
android:searchSuggestAuthority="com.example.MySuggestionProvider"
android:searchSuggestSelection=" ?" >
</searchable>
android:searchSuggestAuthority
的值必須是內容供應商的完整名稱,且與內容供應商中使用的授權完全一致,例如上述範例中的 "com.example.MySuggestionProvider"
。
android:searchSuggestSelection
的值必須是單一問號,且前面要加上空格:" ?"
。這是 SQLite 選取引數的預留位置,系統會自動將其替換為使用者輸入的查詢文字。
儲存查詢
如要填入近期查詢的集合,請將可搜尋活動收到的每項查詢新增至 SearchRecentSuggestionsProvider
。如要執行這項操作,請建立 SearchRecentSuggestions
的例項,並在可搜尋活動每次收到查詢時呼叫 saveRecentQuery()
。舉例來說,以下說明如何在活動的 onCreate()
方法中儲存查詢:
Kotlin
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.main)
if (Intent.ACTION_SEARCH == intent.action) {
intent.getStringExtra(SearchManager.QUERY)?.also { query ->
SearchRecentSuggestions(this, MySuggestionProvider.AUTHORITY, MySuggestionProvider.MODE)
.saveRecentQuery(query, null)
}
}
}
Java
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
Intent intent = getIntent();
if (Intent.ACTION_SEARCH.equals(intent.getAction())) {
String query = intent.getStringExtra(SearchManager.QUERY);
SearchRecentSuggestions suggestions = new SearchRecentSuggestions(this,
MySuggestionProvider.AUTHORITY, MySuggestionProvider.MODE);
suggestions.saveRecentQuery(query, null);
}
}
SearchRecentSuggestionsProvider
建構函式需要與內容供應商宣告的授權和資料庫模式相同。
saveRecentQuery()
方法會將搜尋查詢字串做為第一個參數,並視需要將第二個字串做為建議的第二行或空值。只有在您使用 DATABASE_MODE_2LINES
為搜尋建議啟用雙行模式時,才會用到第二個參數。如果啟用雙行模式,系統在尋找相符的建議時,會比對查詢文字與第二行。
清除建議資料
為保護使用者隱私,請務必提供清除近期查詢建議的方法。如要清除查詢記錄,請呼叫
clearHistory()
。
例如:
Kotlin
SearchRecentSuggestions(this, HelloSuggestionsProvider.AUTHORITY, HelloSuggestionsProvider.MODE)
.clearHistory()
Java
SearchRecentSuggestions suggestions = new SearchRecentSuggestions(this,
HelloSuggestionProvider.AUTHORITY, HelloSuggestionProvider.MODE);
suggestions.clearHistory();
從「清除搜尋記錄」選單項目、偏好設定項目或按鈕中執行此操作。
提供確認對話方塊,確認使用者是否要刪除搜尋記錄。
這個頁面中的內容和程式碼範例均受《內容授權》中的授權所規範。Java 與 OpenJDK 是 Oracle 和/或其關係企業的商標或註冊商標。
上次更新時間:2025-08-27 (世界標準時間)。
[[["容易理解","easyToUnderstand","thumb-up"],["確實解決了我的問題","solvedMyProblem","thumb-up"],["其他","otherUp","thumb-up"]],[["缺少我需要的資訊","missingTheInformationINeed","thumb-down"],["過於複雜/步驟過多","tooComplicatedTooManySteps","thumb-down"],["過時","outOfDate","thumb-down"],["翻譯問題","translationIssue","thumb-down"],["示例/程式碼問題","samplesCodeIssue","thumb-down"],["其他","otherDown","thumb-down"]],["上次更新時間:2025-08-27 (世界標準時間)。"],[],[],null,["Try the Compose way \nJetpack Compose is the recommended UI toolkit for Android. Learn how to add search functionality in Compose. \n[Search bar →](/develop/ui/compose/components/search-bar) \n\nYou can provide search suggestions based on recent search queries in the Android search dialog or\nsearch widget. For example, if a user queries \"puppies,\" the query appears as a suggestion when they\ntype the same query again. Figure 1 shows an example of a search dialog with recent query\nsuggestions.\n\nBefore you begin, implement the search dialog or a search widget for basic searches\nin your application. To learn how, see\n[Create a search interface](/develop/ui/views/search/search-dialog).\n\nThe basics \n\n**Figure 1.** Screenshot of a search dialog with recent query\nsuggestions.\n\nRecent query suggestions are saved searches. When the user selects a suggestion, your searchable\nactivity receives an\n[ACTION_SEARCH](/reference/android/content/Intent#ACTION_SEARCH) intent\nwith the suggestion as the search query that your searchable activity already handles.\n\nTo provide recent queries suggestions, you need to:\n\n- Implement a searchable activity.\n- Create a content provider that extends [SearchRecentSuggestionsProvider](/reference/android/content/SearchRecentSuggestionsProvider) and declare it in your application manifest.\n- Modify the searchable configuration with information about the content provider that provides search suggestions.\n- Save queries to your content provider each time a search is executed.\n\nJust as the Android system displays the search dialog, it displays the search suggestions below\nthe dialog or search widget. You provide the source the system retrieves the suggestions from.\n\nWhen the system identifies that your activity is searchable and provides search suggestions, the\nfollowing happens when the user types a query:\n\n1. The system takes the search query text---whatever the user begins typing---and performs a query to the content provider that contains your suggestions.\n2. Your content provider returns a [Cursor](/reference/android/database/Cursor) that points to all suggestions that match the search query text.\n3. The system displays the list of suggestions provided by the `Cursor`.\n\nOnce the recent query suggestions are displayed, the following might happen:\n\n- If the user types another key or changes the query in any way, the preceding steps are repeated and the suggestion list is updated.\n- If the user executes the search, the suggestions are ignored and the search is delivered to your searchable activity using the normal `ACTION_SEARCH` intent.\n- If the user selects a suggestion, an `ACTION_SEARCH` intent is delivered to your searchable activity using the suggested text as the query.\n\nThe `SearchRecentSuggestionsProvider` class that you extend for your content provider\nautomatically does the work in the preceding steps, so there's little code to write.\n\nCreate a content provider\n\nThe content provider you need for recent query suggestions is an implementation of\n`SearchRecentSuggestionsProvider`. This class does everything for you. You just need to\nwrite a class constructor that executes one line of code.\n\nFor example, here's a complete implementation of a content provider for recent query\nsuggestions: \n\nKotlin \n\n```kotlin\nclass MySuggestionProvider : SearchRecentSuggestionsProvider() {\n init {\n setupSuggestions(AUTHORITY, MODE)\n }\n\n companion object {\n const val AUTHORITY = \"com.example.MySuggestionProvider\"\n const val MODE: Int = SearchRecentSuggestionsProvider.DATABASE_MODE_QUERIES\n }\n}\n```\n\nJava \n\n```java\npublic class MySuggestionProvider extends SearchRecentSuggestionsProvider {\n public final static String AUTHORITY = \"com.example.MySuggestionProvider\";\n public final static int MODE = DATABASE_MODE_QUERIES;\n\n public MySuggestionProvider() {\n setupSuggestions(AUTHORITY, MODE);\n }\n}\n```\n\nThe call to\n[setupSuggestions()](/reference/android/content/SearchRecentSuggestionsProvider#setupSuggestions(java.lang.String, int))\npasses the name of the search authority and a database mode. The search authority can be any unique\nstring, but the best practice is to use a fully qualified name for your content provider, such as\nthe package name followed by the provider's class name. For example,\n`\"com.example.MySuggestionProvider\"`.\n\nThe database mode must include\n[DATABASE_MODE_QUERIES](/reference/android/content/SearchRecentSuggestionsProvider#DATABASE_MODE_QUERIES)\nand can optionally include\n[DATABASE_MODE_2LINES](/reference/android/content/SearchRecentSuggestionsProvider#DATABASE_MODE_2LINES),\nwhich adds a column to the suggestions table so you can provide a second line of text with each\nsuggestion. If you want to provide two lines in each suggestion, see the following example: \n\nKotlin \n\n```kotlin\nconst val MODE: Int = DATABASE_MODE_QUERIES or DATABASE_MODE_2LINES\n```\n\nJava \n\n```java\npublic final static int MODE = DATABASE_MODE_QUERIES | DATABASE_MODE_2LINES;\n```\n\nDeclare the content provider in your application manifest with the same authority string used in\nyour `SearchRecentSuggestionsProvider` class and in the searchable configuration. For\nexample: \n\n```xml\n\u003capplication\u003e\n \u003cprovider android:name=\".MySuggestionProvider\"\n android:authorities=\"com.example.MySuggestionProvider\" /\u003e\n ...\n\u003c/application\u003e\n```\n\nModify the searchable configuration\n\nTo configure the system to use your suggestions provider, add the\n`android:searchSuggestAuthority` and `android:searchSuggestSelection`\nattributes to the `\u003csearchable\u003e` element in your searchable configuration file. For\nexample: \n\n```xml\n\u003c?xml version=\"1.0\" encoding=\"utf-8\"?\u003e\n\u003csearchable xmlns:android=\"http://schemas.android.com/apk/res/android\"\n android:label=\"@string/app_label\"\n android:hint=\"@string/search_hint\"\n android:searchSuggestAuthority=\"com.example.MySuggestionProvider\"\n android:searchSuggestSelection=\" ?\" \u003e\n\u003c/searchable\u003e\n```\n\nThe value for `android:searchSuggestAuthority` must be a fully qualified name for your\ncontent provider that exactly matches the authority used in the content provider, such as\n`\"com.example.MySuggestionProvider\"` in the preceding examples.\n\nThe value for `android:searchSuggestSelection` must be a single question mark preceded\nby a space: `\" ?\"`. This is a placeholder for the SQLite selection argument, and it is\nautomatically replaced by the query text entered by the user.\n\nSave queries\n\nTo populate your collection of recent queries, add each query received by your searchable\nactivity to your `SearchRecentSuggestionsProvider`. To do this, create an instance of\n[SearchRecentSuggestions](/reference/android/provider/SearchRecentSuggestions)\nand call\n[saveRecentQuery()](/reference/android/provider/SearchRecentSuggestions#saveRecentQuery(java.lang.String, java.lang.String))\neach time your searchable activity receives a query. For example, here's how you can save the query\nduring your activity's\n[onCreate()](/reference/android/app/Activity#onCreate(android.os.Bundle))\nmethod: \n\nKotlin \n\n```kotlin\noverride fun onCreate(savedInstanceState: Bundle?) {\n super.onCreate(savedInstanceState)\n setContentView(R.layout.main)\n\n if (Intent.ACTION_SEARCH == intent.action) {\n intent.getStringExtra(SearchManager.QUERY)?.also { query -\u003e\n SearchRecentSuggestions(this, MySuggestionProvider.AUTHORITY, MySuggestionProvider.MODE)\n .saveRecentQuery(query, null)\n }\n }\n}\n```\n\nJava \n\n```java\n@Override\npublic void onCreate(Bundle savedInstanceState) {\n super.onCreate(savedInstanceState);\n setContentView(R.layout.main);\n\n Intent intent = getIntent();\n\n if (Intent.ACTION_SEARCH.equals(intent.getAction())) {\n String query = intent.getStringExtra(SearchManager.QUERY);\n SearchRecentSuggestions suggestions = new SearchRecentSuggestions(this,\n MySuggestionProvider.AUTHORITY, MySuggestionProvider.MODE);\n suggestions.saveRecentQuery(query, null);\n }\n}\n```\n\nThe `SearchRecentSuggestionsProvider` constructor requires the\nsame authority and database mode declared by your content provider.\n\nThe `saveRecentQuery()` method takes the search query string as the first parameter\nand, optionally, a second string to include as the second line of the suggestion or null. The second\nparameter is only used if you enable two-line mode for the search suggestions with\n`DATABASE_MODE_2LINES`. If you enable two-line mode, then the query text matches against\nthe second line when the system looks for matching suggestions.\n\nClear the suggestion data\n\nTo protect the user's privacy, always provide a way for the user to clear the recent query\nsuggestions. To clear the query history, call\n[clearHistory()](/reference/android/provider/SearchRecentSuggestions#clearHistory()).\nFor example: \n\nKotlin \n\n```kotlin\nSearchRecentSuggestions(this, HelloSuggestionsProvider.AUTHORITY, HelloSuggestionsProvider.MODE)\n .clearHistory()\n```\n\nJava \n\n```java\nSearchRecentSuggestions suggestions = new SearchRecentSuggestions(this,\n HelloSuggestionProvider.AUTHORITY, HelloSuggestionProvider.MODE);\nsuggestions.clearHistory();\n```\n\nExecute this from your choice of a \"Clear Search History\" menu item, preference item, or button.\nProvide a confirmation dialog to verify that the user wants to delete their search history."]]