自 2025 年 3 月 27 日起,我们建议您使用 android-latest-release
而非 aosp-main
构建 AOSP 并为其做出贡献。如需了解详情,请参阅 AOSP 的变更。
通用搜索
使用集合让一切井井有条
根据您的偏好保存内容并对其进行分类。
Android 8.0 为“设置”菜单添加了经过扩展的搜索功能。本文档介绍了如何添加设置,以及如何确保正确地将其加入“设置”搜索的索引中。
创建可编入索引的设置
需要编入索引的每个“设置”片段都会实现 Indexable
接口,并且需要静态字段:
public static final SearchIndexProvider SEARCH_INDEX_DATA_PROVIDER
为 fragment 进行设置以编入索引后,将其添加到以下位置中的 SearchIndexableResources
:
packages/apps/Settings/src/com/android/settings/search/SearchIndexableResources.java
可选方法
此 SearchIndexProvider
接口有以下四种可选方法:
getXmlResourcesToIndex
- 如果您的片段内容来自
preference xml
,请替换此方法
- 以要编入索引的列表形式返回 XML 偏好设置。
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;
}
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;
}
getNonIndexableKeys
- 如果您的 fragment 为
DashboardFragment
,很少需要替换此方法。
- 返回满足以下条件的键列表:对应的结果不应显示给定用户、设备、配置等内容。此处提供的键应与
SearchIndexableResource
和 SearchIndexableRaw
中的 KEY 字段匹配。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;
}
getPreferenceControllers
返回与此 fragment 相关联的偏好设置控制器列表。
此列表用于形成内嵌结果、更新不可编入索引的内容等。
因此,您希望在搜索中显示的所有内容都必须包含在 getXmlResourcesToIndex
或 getRawDataToIndex
中。
为设置添加关键字
为确保设置易于搜索,请添加与设置相关、用户可能用来搜索该设置的关键字。
添加关键字时请注意以下事项:
- 关键字是具有以下特征的词语的列表:用户不一定会看到,但可能属于在脑中构想相应设置的工作原理时会用到的字词。
- 关键字是用户可能会输入以访问您的设置的字词。
- 关键字可以是同义词,或者与设置相关联的任何字词。
- 例如,可以使用“静音”来查找“音量”设置。
避免重复
如果您要无条件地排除某个设置页面,请移除原始页面的索引,以避免出现重复的结果。
- 找到您要排除的页面的
PreferenceFragment
。
- 移除
SearchIndexProvider
。
验证
要测试新设置的可搜索性,请执行以下操作:
- 在设备上安装最新版本的 Android O。
- 通过依次选择以下各项让数据库重新编制索引:
设置 > 应用和通知 > 应用信息 > 设置 > 存储 > 清除数据- 验证目标设置是否显示在搜索结果中。
搜索设置的标题前缀将与该设置匹配。
可以运行以下 robolectric 测试以验证此功能的实现:
packages/apps/Settings/tests/robotests/src/com/android/settings/search
构建目标为:RunSettingsRoboTests
本页面上的内容和代码示例受内容许可部分所述许可的限制。Java 和 OpenJDK 是 Oracle 和/或其关联公司的注册商标。
最后更新时间 (UTC):2025-08-26。
[[["易于理解","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"]],["最后更新时间 (UTC):2025-08-26。"],[],[],null,["# Universal search\n\nAndroid 8.0 adds expanded search capabilities for the *Settings* menu. This\ndocument describes how to add a setting and ensure it is properly indexed for\nSettings search.\n\nCreate indexable settings\n-------------------------\n\n\nEach Settings fragment that needs to be indexed implements the\n`Indexable`interface, AND requires the static\nfield:\n\n```scdoc\npublic static final SearchIndexProvider SEARCH_INDEX_DATA_PROVIDER\n```\n\n\nAfter you have your fragment set up for indexing, add it to\n`SearchIndexableResources` found at: \n\n`packages/apps/Settings/src/com/android/settings/search/SearchIndexableResources.java\n`\n\nOptional methods\n----------------\n\nThis `SearchIndexProvider`interface has four optional\nmethods.\n\n### getXmlResourcesToIndex\n\n- Override this if your fragment content is from: `preference xml`\n- Returns an XML preference as a list to be indexed.\n\nXML resources example: \n\n```world-of-warcraft-toc\npublic List\u003cSearchIndexableResource\u003e getXmlResourcesToIndex(Context context, boolean enabled) {\n ArrayList\u003cSearchIndexableResource\u003e result = new ArrayList\u003cSearchIndexableResource\u003e();\nSearchIndexableResource sir = new SearchIndexableResource(context);\n\tsir.xmlResId = R.xml.display_settings;\n\tresult.add(sir);\n\n return result;\n}\n```\n\n### getRawDataToIndex\n\n- Override this if your fragment content is NOT from: `preference\n xml`\n- Returns a list of Raw data (`SearchIndexableRaw`) to be indexed.\n\nRaw data example: \n\n```scdoc\npublic List\u003cSearchIndexableRaw\u003e getRawDataToIndex(Context context, boolean enabled) {\n final List\u003cSearchIndexableRaw\u003e result = new ArrayList\u003c\u003e();\n final Resources res = context.getResources();\n\n // Add fragment title\n SearchIndexableRaw data = new SearchIndexableRaw(context);\n data.title = res.getString(R.string.wifi_settings);\n data.screenTitle = res.getString(R.string.wifi_settings);\n data.keywords = res.getString(R.string.keywords_wifi);\n data.key = DATA_KEY_REFERENCE;\n result.add(data);\n\n return result;\n}\n```\n\n### getNonIndexableKeys\n\n- If your fragment is a `DashboardFragment`, you rarely need to override this.\n- Returns a list of keys that corresponds to results that should not show up for the given user, device, configuration, etc.The keys provided here should match the *KEY* field in `SearchIndexableResource` and `SearchIndexableRaw`.\n- For example: Data Usage should not show up for users who have never had a SIM card in their device.\n\nNon-indexable keys example: \n\n```scdoc\npublic List\u003cString\u003e getNonIndexableKeys(Context context) {\n final List\u003cString\u003e keys = super.getNonIndexableKeys(context);\n if (!checkIntentAction(context, \"android.settings.TERMS\")) {\n keys.add(KEY_TERMS);\n }\n if (!checkIntentAction(context, \"android.settings.LICENSE\")) {\n keys.add(KEY_LICENSE);\n }\n if (!checkIntentAction(context, \"android.settings.COPYRIGHT\")) {\n keys.add(KEY_COPYRIGHT);\n }\n if (!checkIntentAction(context, \"android.settings.WEBVIEW_LICENSE\")) {\n keys.add(KEY_WEBVIEW_LICENSE);\n }\n return keys;\n}\n```\n\n### getPreferenceControllers\n\n\nReturns a list of preference controllers associated with this fragment.\nThis list is used to form inline results, update non-indexables, etc.\n\n\nThus, everything you want to show up in search must be included in either\n`getXmlResourcesToIndex` or `getRawDataToIndex`.\n\nAdd keywords for your settings\n------------------------------\n\n\nTo ensure a setting is easily searchable, add keywords that are relevant for the\nsetting that a user may use to search for the setting.\n\n\nThings to consider when adding keywords:\n\n- Keywords are a list of words that the user does not necessarily see but may be part of their mental model for how the setting works.\n- These are words that the user might type to get to your setting.\n- They can be synonyms or any words associated to the setting can be used.\n- For example, \"mute\" might be used to find the Volume setting.\n\nAvoid duplication\n-----------------\n\n\nIf you are unconditionally suppressing a settings page, remove the indexing of\nthe original page to avoid duplication of results.\n\n1. Find the `PreferenceFragment` of the page you are suppressing.\n2. Remove the `SearchIndexProvider`.\n\nValidation\n----------\n\n\nTo test the searchability of a new setting:\n\n1. Instal a recent version of O on the device.\n2. Reindex the database by selecting:\n*Settings \\\u003e Apps \\& Notifications \\\u003e Apps info \\\u003e Settings \\\u003e Storage \\\u003e\n**Clear Data***\n3. Verify the target settings shows up in search. \n Searching for a prefix of the title of a setting will match it.\n\n\nThese robolectric tests may be run to validate the implementation of this\nfeature: \n\n`packages/apps/Settings/tests/robotests/src/com/android/settings/search`\n\n\nThe build target is: `RunSettingsRoboTests`"]]