一、前言

        Android 8.0 为“设置”菜单添加了经过扩展的搜索功能。本文档介绍了如何添加快速索引,以及如何确保正确地将其加入“设置”搜索的索引中。

二、创建快速索引

 如果需要为每个“设置Fragment”  编入索引的话,就需要实现 Indexable 接口, 对应的静态字段(SEARCH_INDEX_DATA_PROVIDER),    格式模板如下:

public static final Indexable.SearchIndexProvider SEARCH_INDEX_DATA_PROVIDER

如下代码:

public static final Indexable.SearchIndexProvider SEARCH_INDEX_DATA_PROVIDER =
            new BaseSearchIndexProvider() {
                @Override
                public List<SearchIndexableResource> getXmlResourcesToIndex(Context context,
                        boolean enabled) {
                    final ArrayList<SearchIndexableResource> result = new ArrayList<>();

                    final SearchIndexableResource sir = new SearchIndexableResource(context);
                    sir.xmlResId = R.xml.display_settings;
                    result.add(sir);
                    return result;
                }

                @Override
                public List<AbstractPreferenceController> createPreferenceControllers(
                        Context context) {
                    return buildPreferenceControllers(context, null);
                }
            };

为您的片段进行设置以编入索引后,将其添加到以下位置中的 SearchIndexableResources
packages/apps/Settings/src/com/android/settings/search/SearchIndexableResources.java

三、创建方法

此 SearchIndexProvider 接口有以下四种可选方法:

3.1 getXmlResourcesToIndex

  • 如果您的片段内容来自 preference xml,请替换此方法
  • 以要编入索引的列表形式返回 XML 偏好设置

XML 资源示例,我们已  设置----显示 加载的display_settings.xml  布局文件为例

public List<SearchIndexableResource> getXmlResourcesToIndex(Context context, boolean enabled) {
    ArrayList<SearchIndexableResource> result =  new ArrayList<SearchIndexableResource>();
SearchIndexableResource sir = new SearchIndexableResource(context);
        sir.xmlResId = R.xml.display_settings;
        result.add(sir);

    return result;
}

此方法一般都会复写,就是把该界面的菜单选项 对应的关键字加入到快速搜索的字段列表中。

3.2 getRawDataToIndex

  • 如果你的片段内容并非来自 preference xml,请替换此方法:
  • 返回要编入索引的原始数据 (SearchIndexableRaw) 列表。

原始数据示例:

public List<SearchIndexableRaw> getRawDataToIndex(Context context, boolean enabled) {
              final List<SearchIndexableRaw> result = new ArrayList<>();
              final Resources res = context.getResources();

              // Add fragment title
       SearchIndexableRaw data = new SearchIndexableRaw(context);
       data.title = res.getString(R.string.wifi_settings);
       data.screenTitle = res.getString(R.string.wifi_settings);
       data.keywords = res.getString(R.string.keywords_wifi);
       data.key = DATA_KEY_REFERENCE;
       result.add(data);

       return result;
}

这样子可以把自定义的Preference 的 title  加入到快速搜索列表中,用户可以通过此title快速搜素到此选项。

3.3 getNonIndexableKeys

  • 如果您的 fragment 为 DashboardFragment,很少需要替换此方法。
  • 返回满足以下条件的键列表:对应的结果不应显示给定用户、设备、配置等内容。此处提供的键应与 SearchIndexableResource 和 SearchIndexableRaw 中的 KEY 字段匹配。
  • 例如:不应向从未在其设备中使用 SIM 卡的用户显示“流量消耗”。

不可编入索引的键示例:

public List<String> getNonIndexableKeys(Context context) {
      final List<String> keys = super.getNonIndexableKeys(context);
              if (!checkIntentAction(context, "android.settings.TERMS")) {
                  keys.add(KEY_TERMS);
              }
              if (!checkIntentAction(context, "android.settings.LICENSE")) {
                  keys.add(KEY_LICENSE);
              }
              if (!checkIntentAction(context, "android.settings.COPYRIGHT")) {
                  keys.add(KEY_COPYRIGHT);
              }
              if (!checkIntentAction(context, "android.settings.WEBVIEW_LICENSE")) {
                  keys.add(KEY_WEBVIEW_LICENSE);
              }
              return keys;
}

此方法就是 移除掉搜索关键字,比如有些定制移动设备,硬件上不支持蓝牙,WLAN ,我们除了要移除设置界面中的蓝牙 WLAN菜单外,还需要移除搜索的关键字,避免用户在搜索栏输入"蓝牙"关键字还可以找出菜单。

3.4 getPreferenceControllers

返回与此 fragment 相关联的偏好设置控制器列表。 此列表用于形成内嵌结果、更新不可编入索引的内容等。

因此,您希望在搜索中显示的所有内容都必须包含在getXmlResourcesToIndex 或 getRawDataToIndex 中。

四、为设置菜单添加关键字

为确保设置易于搜索,请添加与设置相关、用户可能用来搜索该设置的关键字。

添加关键字时请注意以下事项:

  • 关键字是具有以下特征的词语的列表:用户不一定会看到,但可能属于在脑中构想相应设置的工作原理时会用到的字词。
  • 关键字是用户可能会输入以访问您的设置的字词。
  • 关键字可以是同义词,或者与设置相关联的任何字词。
  • 例如,可以使用“静音”来查找“音量”设置。

五、避免重复内容

如果您要无条件地排除某个设置页面,请移除原始页面的索引,以避免出现重复的结果。

  1. 找到您要排除的页面的 PreferenceFragment
  2. 移除 SearchIndexProvider

六、验证方法

要测试新设置的可搜索性,请执行以下操作:

  1. 在设备上安装最新版本的 Android O 版本( >= Android 8.0) 
  2. 通过依次选择以下各项让数据库重新编制索引:设置 > 应用和通知 > 应用信息 > 设置 > 存储 > 清除数据
  3. 验证目标设置是否显示在搜索结果中
    搜索设置的标题前缀将与该设置匹配。