Android 8.0 adds expanded search capabilities for the Settings menu. This document describes how to add a setting and ensure it is properly indexed for Settings search.
Create indexable settings
Each Settings fragment that needs to be indexed implements the
Indexableinterface, AND requires the static
field:
public static final SearchIndexProvider SEARCH_INDEX_DATA_PROVIDER
After you have your fragment set up for indexing, add it to
SearchIndexableResources found at:
packages/apps/Settings/src/com/android/settings/search/SearchIndexableResources.java
Optional methods
This SearchIndexProviderinterface has four optional
methods.
getXmlResourcesToIndex
- Override this if your fragment content is from:
preference xml - Returns an XML preference as a list to be indexed.
XML resources example:
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
- Override this if your fragment content is NOT from:
preference xml - Returns a list of Raw data (
SearchIndexableRaw) to be indexed.
Raw data example:
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
- If your fragment is a
DashboardFragment, you rarely need to override this. - 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
SearchIndexableResourceandSearchIndexableRaw. - For example: Data Usage should not show up for users who have never had a SIM card in their device.
Non-indexable keys example:
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
Returns a list of preference controllers associated with this fragment. This list is used to form inline results, update non-indexables, etc.
Thus, everything you want to show up in search must be included in either
getXmlResourcesToIndex or getRawDataToIndex.
Add keywords for your settings
To ensure a setting is easily searchable, add keywords that are relevant for the setting that a user may use to search for the setting.
Things to consider when adding keywords:
- 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.
- These are words that the user might type to get to your setting.
- They can be synonyms or any words associated to the setting can be used.
- For example, "mute" might be used to find the Volume setting.
Avoid duplication
If you are unconditionally suppressing a settings page, remove the indexing of the original page to avoid duplication of results.
- Find the
PreferenceFragmentof the page you are suppressing. - Remove the
SearchIndexProvider.
Validation
To test the searchability of a new setting:
- Instal a recent version of O on the device.
- Reindex the database by selecting: Settings > Apps & Notifications > Apps info > Settings > Storage > Clear Data
- Verify the target settings shows up in search.
Searching for a prefix of the title of a setting will match it.
These robolectric tests may be run to validate the implementation of this
feature:
packages/apps/Settings/tests/robotests/src/com/android/settings/search
The build target is: RunSettingsRoboTests