添加自定义建议

使用 Android 搜索对话框或搜索微件时,您可以提供根据应用中的数据创建的自定义搜索建议。例如,如果您的应用是一部字典,则可以建议该字典中与用户到目前为止输入的文本匹配的字词。这些是最有价值的建议,因为您可以有效地预测用户想要的内容并让用户能够立即访问该内容。图 1 显示了包含自定义建议的搜索对话框的示例。

提供自定义建议后,您还可以将其提供给系统范围的快速搜索框,从而让用户能够从您的应用外部访问您的内容。

在开始按照本指南中的说明添加自定义建议之前,您需要已实现 Android 搜索对话框或搜索微件,以便在您的应用中搜索。如果您还没有实现,请参阅创建搜索界面。您还应参阅内容提供程序文档。

基础知识

图 1. 包含自定义搜索建议的搜索对话框的屏幕截图。

当用户选择自定义建议时,Android 系统会将 Intent 发送到您的可搜索 Activity。正常的搜索查询会发送包含 ACTION_SEARCH 操作的 intent,而您可以将自定义建议定义为使用 ACTION_VIEW(或其他任何 intent 操作),还可以添加与选定建议相关的数据。继续以字典为例,当用户选择一条建议时,您的应用可以立即打开该字词的定义,而不是在字典中搜索匹配项。

要提供自定义建议,请执行以下操作:

  • 实现一个基本的可搜索 Activity,如创建搜索界面中所述。
  • 使用有关用于提供自定义建议的内容提供程序的信息来修改可搜索配置。
  • 为建议构建一个表格(例如,在 SQLiteDatabase 中),并设置该表格的格式,使其包含所需的列。
  • 创建一个可访问建议表格的内容提供程序,并在清单中声明该提供程序。
  • 声明要在用户选择某条建议时发送的 Intent 类型(包括自定义操作和自定义数据)。

就像 Android 系统显示搜索对话框一样,它也会显示搜索建议。您只需要一个内容提供程序,系统可从其检索建议。如果您不熟悉如何创建内容提供程序,请先阅读内容提供程序开发者指南,然后再继续。

如果系统发现您的 Activity 可搜索并提供搜索建议,在用户输入查询时会发生以下过程:

  1. 系统获取搜索查询文本(用户到目前为止已输入的所有内容),并对管理建议的内容提供程序执行查询。
  2. 内容提供程序返回一个 Cursor,它指向与搜索查询文本相关的所有建议。
  3. 系统显示由该 Cursor 提供的建议的列表。

显示自定义建议后,可能会发生以下情况:

  • 如果用户输入其他键或以任何方式更改查询,系统会重复执行上述步骤,并视情况更新建议列表。
  • 如果用户执行搜索,系统会忽略建议,并使用正常的 ACTION_SEARCH intent 将搜索传递给可搜索 Activity。
  • 如果用户选择某条建议,系统会将一个 intent 发送到您的可搜索 Activity,该 intent 带有自定义操作和自定义数据,以便您的应用可以打开建议的内容。

修改可搜索配置

要添加对自定义建议的支持,请在可搜索配置文件中将 android:searchSuggestAuthority 属性添加到 <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.MyCustomSuggestionProvider">
    </searchable>
    

您可能需要一些其他属性,具体取决于您附加到每条建议的 intent 类型,以及您要如何设置对内容提供程序的查询的格式。下面几部分介绍了其他可选属性。

创建内容提供程序

要为自定义建议创建内容提供程序,您先前必须对内容提供程序有所了解,内容提供程序开发者指南对此进行了介绍。自定义建议的内容提供程序与其他任何内容提供程序大致相同。不过,对于您提供的每条建议,Cursor 中的相应行必须包含系统理解并用来设置建议格式的特定列。

当用户开始在搜索对话框或搜索微件中输入内容时,用户每次输入一个字母,系统就会通过调用 query() 向内容提供程序查询建议。在 query() 实现中,内容提供程序必须搜索建议数据并返回一个 Cursor(指向您认为是合适的建议的行)。

下面两部分详细介绍了如何为自定义建议创建内容提供程序:

处理建议查询
系统如何向内容提供程序发送请求以及如何处理请求
构建建议表格
如何定义系统要求随每次查询返回的 Cursor 中包含的列

处理建议查询

当系统从内容提供程序请求建议时,它会调用内容提供程序的 query() 方法。您必须实现此方法来搜索建议数据并返回一个 Cursor(指向您认为相关的建议)。

下面简要介绍了系统传递给 query() 方法的参数(按顺序列出):

uri
始终为内容 Uri,格式如下:
    content://your.authority/optional.suggest.path/SUGGEST_URI_PATH_QUERY
    

默认行为是系统传递此 URI 并在其后面附加查询文本。例如:

    content://your.authority/optional.suggest.path/SUGGEST_URI_PATH_QUERY/puppies
    

末尾的查询文本使用 URI 编码规则进行了编码,因此您可能需要在执行搜索之前将其解码。

仅当您在可搜索配置文件中使用 android:searchSuggestPath 属性设置了相应路径时,optional.suggest.path 部分才会包含在 URI 中。仅当您将同一内容提供程序用于多个可搜索 Activity 时(在这种情况下,您需要消除建议查询来源的歧义),才需要此参数。

注意SUGGEST_URI_PATH_QUERY 不是在 URI 中提供的字面量字符串,而是在您需要引用此路径时应使用的常量。

projection
始终为 null
selection
在可搜索配置文件的 android:searchSuggestSelection 属性中提供的值;如果您尚未声明 android:searchSuggestSelection 属性,则为 null。下文详细介绍了如何使用此参数来获取查询
selectionArgs
如果您已在可搜索配置中声明 android:searchSuggestSelection 属性,则包含搜索查询作为数组的第一个(也是唯一一个)元素。如果您尚未声明 android:searchSuggestSelection,则此参数为 null。下文详细介绍了如何使用此参数来获取查询
sortOrder
始终为 null

系统可以通过两种方式向您发送搜索查询文本。默认方式是包含查询文本作为在 uri 参数中传递的内容 URI 的最后一个路径。不过,如果可搜索配置的 android:searchSuggestSelection 属性中包含选择值,则会将查询文本作为 selectionArgs 字符串数组的第一个元素传递。接下来对这两种方式进行了总结。

在 Uri 中获取查询

默认情况下,查询附加为 uri 参数(Uri 对象)的最后一段。要在这种情况下检索查询文本,只需使用 getLastPathSegment() 即可。例如:

Kotlin

    val query: String = uri.lastPathSegment.toLowerCase()
    

Java

    String query = uri.getLastPathSegment().toLowerCase();
    

此方法将返回 Uri 的最后一段,也就是用户输入的查询文本。

在选择参数中获取查询

您可能决定更合理的做法是让 query() 方法接收执行查询所需的一切内容,并且希望 selectionselectionArgs 参数携带适当的值,而不是使用 URI。在这种情况下,请使用 SQLite 选择字符串将 android:searchSuggestSelection 属性添加到可搜索配置。在选择字符串中,添加一个问号(“?”)作为实际搜索查询的占位符。系统调用 query() 时,将选择字符串作为 selection 参数,并将搜索查询作为 selectionArgs 数组中的第一个元素。

例如,您可以按如下方式形成 android:searchSuggestSelection 属性来创建全文搜索语句:

    <?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.MyCustomSuggestionProvider"
        android:searchSuggestIntentAction="android.intent.action.VIEW"
        android:searchSuggestSelection="word MATCH ?">
    </searchable>
    

借助此配置,您的 query() 方法将 selection 参数作为 "word MATCH ?" 传递,并将 selectionArgs 参数作为搜索查询传递。当您将这些传递给 SQLite query() 方法(作为它们各自的参数)时,它们会合成在一起(问号会替换为查询文本)。如果您选择以这种方式接收建议查询,并且需要向查询文本添加通配符,请将其附加到 selectionArgs 参数和/或将其加在该参数前面作为前缀,因为此值会用引号引起来,并且会插入此值来代替问号。

上例中的另一个新属性是 android:searchSuggestIntentAction,该属性定义在用户选择某条建议时随每个 intent 发送的 intent 操作。介绍如何为建议声明 Intent 的部分对其进行了详细说明。

提示:如果您不想在 android:searchSuggestSelection 属性中定义选择子句,但仍希望在 selectionArgs 参数中接收查询文本,只需为 android:searchSuggestSelection 属性提供非 null 值即可。这样会触发要在 selectionArgs 中传递的查询,并且您可以忽略 selection 参数。这样一来,您可以在较低级别定义实际选择子句,内容提供程序就不必处理它了。

构建建议表格

当您使用 Cursor 向系统返回建议时,系统要求每行中包含特定的列。因此,无论您决定将建议数据存储在设备上的 SQLite 数据库中、网络服务器上的数据库中,还是以其他格式存储在设备或网络上,都必须将建议的格式设为表格中的行并使用 Cursor 来显示。

注意:如果您的搜索建议未使用系统所需的列以表格(如 SQLite 表格)格式存储,则您可以在建议数据中搜索匹配项,然后根据每个请求将其格式设为必要的表格。为此,请使用所需的列名称创建一个 MatrixCursor,然后使用 addRow(Object[]) 为每条建议添加一行。从内容提供程序的 query() 方法返回最终产物。

系统理解几列,但其中只有两列是必需的:

_ID
每条建议的唯一整数行 ID。系统需要此 ID 是为了在 ListView 中显示建议。
SUGGEST_COLUMN_TEXT_1
显示为建议的字符串。

下面几列都是可选的(下面几部分对其中的大多数列进行了详细介绍):

SUGGEST_COLUMN_TEXT_2
一个字符串。如果 Cursor 包含此列,则所有建议都以两行格式提供。此列中的字符串显示为主要建议文本下面的第二行较小的文本。它可以为 null 或为空,表示没有次要文本。
SUGGEST_COLUMN_ICON_1
一个可绘制资源、内容或文件 URI 字符串。如果 Cursor 包含此列,则所有建议都以图标加文本格式提供,且可绘制图标在左侧。此列可以为 null 或为 0,表示此行中没有图标。
SUGGEST_COLUMN_ICON_2
一个可绘制资源、内容或文件 URI 字符串。如果 Cursor 包含此列,则所有建议都以图标加文本格式提供,且图标在右侧。此列可以为 null 或为 0,表示此行中没有图标。
SUGGEST_COLUMN_INTENT_ACTION
一个 intent 操作字符串。如果此列存在且在给定行中包含值,则形成建议的 intent 时会使用此处定义的操作。如果未提供该元素,则会从可搜索配置中的 android:searchSuggestIntentAction 字段获取操作。如果您的操作对于所有建议都是相同的,则比较高效的做法是使用 android:searchSuggestIntentAction 指定操作而省略此列。
SUGGEST_COLUMN_INTENT_DATA
一个数据 URI 字符串。如果此列存在且在给定行中包含值,则这是形成建议的 intent 时使用的数据。如果未提供该元素,则会从可搜索配置中的 android:searchSuggestIntentData 字段获取数据。如果这两个来源均未提供,则 intent 的数据字段为 null。如果您的数据对于所有建议都是相同的,或者可以使用常量部分和特定 ID 进行描述,则比较高效的做法是使用 android:searchSuggestIntentData 指定数据而省略此列。
SUGGEST_COLUMN_INTENT_DATA_ID
一个 URI 路径字符串。如果此列存在且在给定行中包含值,则会将“/”和此值附加到 intent 中的数据字段。仅当已将由可搜索配置中的 android:searchSuggestIntentData 属性指定的数据字段设为适当的基字符串时,才应使用此列。
SUGGEST_COLUMN_INTENT_EXTRA_DATA
任意数据。如果此列存在且在给定行中包含值,则这是形成建议的 intent 时使用的额外数据。如果未提供,则 intent 的额外数据字段为 null。此列允许建议提供附加数据,这些数据以 extra 形式包含在 intent 的 EXTRA_DATA_KEY 键中。
SUGGEST_COLUMN_QUERY
如果此列存在且在给定行中存在此元素,则这是形成建议的查询时使用的数据,这些数据以 extra 形式包含在 intent 的 QUERY 键中。如果建议的操作为 ACTION_SEARCH,则此列是必需的;否则,此列是可选的。
SUGGEST_COLUMN_SHORTCUT_ID
仅当为快速搜索框提供建议时,才使用此列。此列指明是否应将搜索建议存储为快捷方式以及是否应对其进行验证。当用户从快速搜索框中点击建议时,通常会形成快捷方式。如果缺少此列,则结果会存储为快捷方式且从不刷新。如果设为 SUGGEST_NEVER_MAKE_SHORTCUT,则结果不会存储为快捷方式。否则,会使用快捷方式 ID 通过 SUGGEST_URI_PATH_SHORTCUT 回来检查是否有最新建议。
SUGGEST_COLUMN_SPINNER_WHILE_REFRESHING
仅当为快速搜索框提供建议时,才使用此列。此列指定当此建议的快捷方式正在快速搜索框中进行刷新时应显示旋转图标而不是 SUGGEST_COLUMN_ICON_2 中的图标。

下面几部分详细介绍了其中的某些列。

为建议声明 Intent

当用户从显示在搜索对话框或搜索微件下方的列表中选择某条建议时,系统会将一个自定义 Intent 发送到您的可搜索 Activity。您必须定义该 intent 的操作和数据。

声明 intent 操作

自定义建议的最常见的 intent 操作是 ACTION_VIEW,当您要打开某些内容(如某个字词的定义、某人的联系信息或某个网页)时,此操作非常合适。不过,intent 操作可以是其他任何操作,甚至对于每条建议可以有所不同。

根据您是否希望所有建议使用同一 intent 操作,您可以通过两种方式来定义操作:

  1. 使用可搜索配置文件的 android:searchSuggestIntentAction 属性为所有建议定义操作。

    例如:

        <?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.MyCustomSuggestionProvider"
            android:searchSuggestIntentAction="android.intent.action.VIEW" >
        </searchable>
        
  2. 使用 SUGGEST_COLUMN_INTENT_ACTION 列为各条建议定义操作。

    SUGGEST_COLUMN_INTENT_ACTION 列添加到建议表格,并针对每条建议在其中添加要使用的操作(如 "android.intent.action.VIEW")。

您还可以结合使用这两种方法。例如,您可以在 android:searchSuggestIntentAction 属性中添加一项默认用于所有建议的操作,然后通过在 SUGGEST_COLUMN_INTENT_ACTION 列中声明其他操作来为某些建议替换此操作。如果您未在 SUGGEST_COLUMN_INTENT_ACTION 列中添加值,则会使用在 android:searchSuggestIntentAction 属性中提供的 intent。

注意:如果您未在可搜索配置中添加 android:searchSuggestIntentAction 属性,则必须针对每条建议在 SUGGEST_COLUMN_INTENT_ACTION 列中添加一个值,否则 intent 将会失败。

声明 intent 数据

当用户选择某条建议时,您的可搜索 Activity 会接收包含您已定义的操作的 intent(如上一部分中所述),但 intent 还必须携带数据,您的 Activity 才能识别用户选择了哪条建议。具体来说,对于每条建议,数据应该是唯一的,如 SQLite 表格中建议的行 ID。接收 intent 后,您可以使用 getData()getDataString() 来检索附加的数据。

您可以通过两种方式来定义 intent 中包含的数据:

  1. 在建议表格的 SUGGEST_COLUMN_INTENT_DATA 列中定义每条建议的数据。

    在建议表格中提供每个 intent 的所有必要数据信息,方法是添加 SUGGEST_COLUMN_INTENT_DATA 列,然后在其中填充每行的唯一数据。此列中的数据将完全按照您在此列中的定义附加到 intent。您随后可以使用 getData()getDataString() 来检索该数据。

    提示:通常最简单的做法是将表格的行 ID 用作 intent 数据,因为它始终都是唯一的。要做到这一点,最简单的方法是将 SUGGEST_COLUMN_INTENT_DATA 列名称用作行 ID 列的别名。请参阅可搜索字典示例应用,以查看一个示例,在该示例中,SQLiteQueryBuilder 创建了列名称到别名的投影映射。

  2. 将数据 URI 分为两部分:一个是所有建议共有的部分,一个是每条建议独有的部分。将这两部分分别放入可搜索配置的 android:searchSuggestintentData 属性和建议表格的 SUGGEST_COLUMN_INTENT_DATA_ID 列。

    在可搜索配置的 android:searchSuggestIntentData 属性中声明所有建议共有的 URI 部分。例如:

        <?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.MyCustomSuggestionProvider"
            android:searchSuggestIntentAction="android.intent.action.VIEW"
            android:searchSuggestIntentData="content://com.example/datatable" >
        </searchable>
        

    然后,在建议表格的 SUGGEST_COLUMN_INTENT_DATA_ID 列中添加每条建议的最终路径(独有部分)。当用户选择某条建议时,系统会获取 android:searchSuggestIntentData 中的字符串,附加一个正斜杠(“/”),然后添加 SUGGEST_COLUMN_INTENT_DATA_ID 列中的相应值,以形成完整的内容 URI。您随后可以使用 getData() 来检索 Uri

添加更多数据

如果您需要通过 intent 来表达更多信息,您可以再添加一个表格列 SUGGEST_COLUMN_INTENT_EXTRA_DATA,此列可以存储有关建议的附加信息。此列中保存的数据将放在 intent 的 extra 包的 EXTRA_DATA_KEY 中。

处理 Intent

现在您已经提供了自定义搜索建议与自定义 intent,接下来您需要让您的可搜索 Activity 在用户选择某条建议时处理这些 intent。这是除了处理 ACTION_SEARCH intent(您的可搜索 Activity 已经这样做了)之外,还需要执行的操作。以下示例展示了您如何在 Activity onCreate() 回调期间处理 intent:

Kotlin

    when(intent.action) {
        Intent.ACTION_SEARCH -> {
            // Handle the normal search query case
            intent.getStringExtra(SearchManager.QUERY)?.also { query ->
                doSearch(query)
            }
        }
        Intent.ACTION_VIEW -> {
            // Handle a suggestions click (because the suggestions all use ACTION_VIEW)
            showResult(intent.data)
        }
    }
    

Java

    Intent intent = getIntent();
    if (Intent.ACTION_SEARCH.equals(intent.getAction())) {
        // Handle the normal search query case
        String query = intent.getStringExtra(SearchManager.QUERY);
        doSearch(query);
    } else if (Intent.ACTION_VIEW.equals(intent.getAction())) {
        // Handle a suggestions click (because the suggestions all use ACTION_VIEW)
        Uri data = intent.getData();
        showResult(data);
    }
    

在本例中,intent 操作是 ACTION_VIEW 并且数据携带一个完整的 URI,该 URI 指向建议的内容(由 android:searchSuggestIntentData 字符串和 SUGGEST_COLUMN_INTENT_DATA_ID 列合成)。系统随后将该 URI 传递给本地 showResult() 方法,该方法向内容提供程序查询由该 URI 指定的内容。

注意:对于使用 android:searchSuggestIntentAction 属性或 SUGGEST_COLUMN_INTENT_ACTION 列定义的 intent 操作,您不需要向 Android 清单文件添加 intent 过滤器。系统将按名称打开您的可搜索 Activity 来传递建议的 intent,因此该 Activity 不需要声明接受的操作。

重新编写查询文本

如果用户使用方向控件(例如,使用轨迹球或方向键)浏览建议列表,默认情况下查询文本不会更新。不过,您可以使用与当前获得焦点的建议匹配的查询来暂时重新编写显示在文本框中的用户查询文本。这样,用户就能看到当前建议的查询(如果适用),接着选择搜索框并修改查询,然后再将其作为搜索进行分派。

您可以通过以下方式重新编写查询文本:

  1. 向您的可搜索配置添加值为“queryRewriteFromText”的 android:searchMode 属性。在这种情况下,建议的 SUGGEST_COLUMN_TEXT_1 列中的内容会用于重新编写查询文本。
  2. 向您的可搜索配置添加值为“queryRewriteFromData”的 android:searchMode 属性。在这种情况下,建议的 SUGGEST_COLUMN_INTENT_DATA 列中的内容会用于重新编写查询文本。这只能与 URI 或会让用户可见的其他数据格式(如 HTTP 网址)一起使用。内部 URI 架构不得用于通过这种方式重新编写查询。
  3. 在建议表格的 SUGGEST_COLUMN_QUERY 列中提供唯一的查询文本字符串。如果此列存在且包含当前建议的值,则它会用于重新编写查询文本(并替换前面的任一实现)。

向快速搜索框提供搜索建议

将应用配置为提供自定义搜索建议后,将这些建议提供给全局可访问的快速搜索框非常简单,只需修改可搜索配置以添加 android:includeInGlobalSearch(设为“true”)即可。

只有在一种情况下需要执行额外的工作,那就是当内容提供程序要求读取权限时。在这种情况下,您需要为提供程序添加一个特殊的 <path-permission> 元素,以向快速搜索框授予对内容提供程序的读取访问权限。例如:

    <provider android:name="MySuggestionProvider"
              android:authorities="com.example.MyCustomSuggestionProvider"
              android:readPermission="com.example.provider.READ_MY_DATA"
              android:writePermission="com.example.provider.WRITE_MY_DATA">
      <path-permission android:pathPrefix="/search_suggest_query"
                       android:readPermission="android.permission.GLOBAL_SEARCH" />
    </provider>
    

在本例中,提供程序限制对内容进行读写访问。<path-permission> 元素修改了这项限制,方法是存在 "android.permission.GLOBAL_SEARCH" 权限时授予对 "/search_suggest_query" 路径前缀内的内容的读取访问权限。这样会向快速搜索框授予访问权限,以便它可以向内容提供程序查询建议。

如果内容提供程序未强制要求读取权限,则快速搜索框默认情况下可以读取它。

在设备上启用建议

将您的应用配置为在快速搜索框中提供建议后,默认情况下,实际上没有为其启用在快速搜索框中提供建议的功能。由用户选择是否在快速搜索框中包含来自您的应用的建议。要启用来自您的应用的搜索建议,用户必须打开“可搜索项”(在“设置”>“搜索”中),并将您的应用作为可搜索项启用。

可供快速搜索框使用的每个应用在“可搜索项”设置页面中都有一个对应的条目。该条目包含应用的名称和一段简短说明,这段说明将概括可以从应用中搜索哪些内容并使其成为快速搜索框中的建议。要为您的可搜索应用定义说明文本,请将 android:searchSettingsDescription 属性添加到您的可搜索配置。例如:

    <?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.MyCustomSuggestionProvider"
        android:searchSuggestIntentAction="android.intent.action.VIEW"
        android:includeInGlobalSearch="true"
        android:searchSettingsDescription="@string/search_description" >
    </searchable>
    

android:searchSettingsDescription 的字符串应尽可能简洁,并说明可搜索的内容。例如,音乐应用的说明文本为“音乐人、专辑和曲目”,记事本应用的说明文本为“保存的记事”。提供此说明非常重要,因为这样能让用户知道会提供什么样的建议。当 android:includeInGlobalSearch 为“true”时,应始终添加此属性。

请注意,用户必须先访问设置菜单来为您的应用启用搜索建议,然后您的搜索建议才会显示在快速搜索框中。因此,如果搜索是您的应用的一个重要方面,则您可能需要考虑一种方法来向用户传达这一点 - 您可以在用户首次启动应用时提供一条说明,指导他们如何为快速搜索框启用搜索建议。

管理快速搜索框建议快捷方式

用户从快速搜索框中选择的建议可以自动变为快捷方式。这些是系统从您的内容提供程序复制的建议,因此它可以快速访问相应建议,而无需重新查询您的内容提供程序。

默认情况下,系统会为快速搜索框检索的所有建议启用此功能,但如果您的建议数据随时间发生变化,则您可以请求刷新相应的快捷方式。例如,如果您的建议引用动态数据(如联系人的在线状态),则您应请求在向用户显示建议快捷方式时对其进行刷新。为此,请在您的建议表格中添加 SUGGEST_COLUMN_SHORTCUT_ID。使用此列,您可以通过以下某种方式来配置每条建议的快捷方式行为:

  1. 让快速搜索框向您的内容提供程序重新查询建议快捷方式的最新版本。

    SUGGEST_COLUMN_SHORTCUT_ID 列中提供一个值,每次显示快捷方式时,都会重新查询建议的最新版本。系统会使用最近可用的数据快速显示快捷方式,直到刷新查询返回结果,届时会使用新信息来刷新建议。系统会使用 URI 路径 SUGGEST_URI_PATH_SHORTCUT(而不是 SUGGEST_URI_PATH_QUERY)将刷新查询发送到您的内容提供程序。

    您返回的 Cursor 应包含一条建议,它使用的列与原始建议相同;也可以为空,表明快捷方式不再有效(在这种情况下,建议会消失并且快捷方式会被移除)。

    如果建议引用的数据需要较长时间进行刷新(如基于网络的刷新),您也可以向建议表格中添加 SUGGEST_COLUMN_SPINNER_WHILE_REFRESHING 列(值为“true”),以便在右侧显示一个进度旋转图标,直到刷新完成。如果设为除“true”以外的其他任何值,则不会显示进度旋转图标。

  2. 完全阻止将建议复制到快捷方式。

    SUGGEST_COLUMN_SHORTCUT_ID 列中提供 SUGGEST_NEVER_MAKE_SHORTCUT 值。在这种情况下,绝不会将建议复制到快捷方式。只有在您绝对不希望显示先前复制的建议时,才有必要这样做。(前面已经提到,如果您为该列提供一个正常值,则只有在刷新查询返回结果后,才会显示建议快捷方式。)

  3. 允许应用默认快捷方式行为。

    对于不会发生变化且可保存为快捷方式的每条建议,将 SUGGEST_COLUMN_SHORTCUT_ID 留空。

如果您的所有建议都从不发生变化,则您根本不需要 SUGGEST_COLUMN_SHORTCUT_ID 列。

注意:快速搜索框最终决定是否为建议创建快捷方式,将这些值视为来自您的应用的强烈要求 - 不能保证您为建议快捷方式请求的行为将得到遵循。

关于快速搜索框建议排名

将您的应用的搜索建议提供给快速搜索框后,快速搜索框建议排名决定了如何针对特定查询向用户显示这些建议。这可能取决于有多少其他应用可以提供该查询的结果,以及与其他应用提供的结果相比,用户选择您的结果的频率。不能保证如何对您的建议排名,也不能保证是否针对给定的查询显示您的应用的建议。一般来说,如果应用提供的结果质量较高,那么将其建议放在显眼位置的可能性就越高;如果应用提供的建议质量较低,那么建议更有可能排名较低或根本不显示。

如需查看自定义搜索建议的完整演示,请参阅可搜索字典示例应用