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
Indexable
interface, 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 SearchIndexProvider
interface 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
SearchIndexableResource
andSearchIndexableRaw
. - 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
PreferenceFragment
of 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