android5.0系统设置搜索功能简析
一、目的:
简单介绍系统设置搜索功能实现,初步熟悉搜索数据库构建规则以及匹配逻辑。
二、相关问题解答
1、系统设置可对那些设置项进行构建搜索数据库?
答:系统设置对数据项的构建规则在com.android.settings.search.SearchIndexableResources类中进行定义,例如如下,将wifi设置,wifi高级设置设置项假如搜索数据匹配库。
sResMap.put(WifiSettings.class.getName(),
new SearchIndexableResource(
Ranking.getRankForClassName(WifiSettings.class.getName()),
NO_DATA_RES_ID,
WifiSettings.class.getName(),
R.drawable.ic_settings_wireless));
sResMap.put(AdvancedWifiSettings.class.getName(),
new SearchIndexableResource(
Ranking.getRankForClassName(AdvancedWifiSettings.class.getName()),
R.xml.wifi_advanced_settings,
AdvancedWifiSettings.class.getName(),
R.drawable.ic_settings_wireless)
);
2、进行关键字搜索时,有多个匹配项,在展示时,他们的排序规则是什么?
答:com.android.settings.search.Ranking,其中定义了每个设置项对应的RAND_ID.例如:
sRankMap.put(WifiSettings.class.getName(), RANK_WIFI);
sRankMap.put(AdvancedWifiSettings.class.getName(), RANK_WIFI);
sRankMap.put(SavedAccessPointsWifiSettings.class.getName(), RANK_WIFI);
在进行搜索匹配时,会根据RANK_ID进行排序:
private String buildSearchSQL(String query, String[] colums, boolean withOrderBy) {
StringBuilder sb = new StringBuilder();
sb.append(buildSearchSQLForColumn(query, colums));
if (withOrderBy) {
sb.append(" ORDER BY ");
sb.append(IndexColumns.DATA_RANK);
}
return sb.toString();
}
3、设置中的设置项如何被解析并加入到搜索匹配数据库中的?
共两类:
类一:
如,下图代码所示,为wifi高级设置项:
sResMap.put(AdvancedWifiSettings.class.getName(),
new SearchIndexableResource(
Ranking.getRankForClassName(AdvancedWifiSettings.class.getName()),
R.xml.wifi_advanced_settings,
AdvancedWifiSettings.class.getName(),
R.drawable.ic_settings_wireless));
其中定义了R.xml.wifi_advanced_settings,,那么在Index.java中,会对该xml文件进行解析,并加入到搜索数据库中。如下图代码:
if (!nodeName.equals(NODE_NAME_CHECK_BOX_PREFERENCE)) {
summary = getDataSummary(context, attrs);
String entries = null;
if (nodeName.endsWith(NODE_NAME_LIST_PREFERENCE)) {
entries = getDataEntries(context, attrs);
}
// Insert rows for the child nodes of PreferenceScreen
updateOneRowWithFilteredData(database, localeStr, title, summary, null, entries,
fragmentName, screenTitle, iconResId, rank,
keywords, intentAction, intentTargetPackage, intentTargetClass,
true, key, -1 /* default user id */);
} else {
String summaryOn = getDataSummaryOn(context, attrs);
String summaryOff = getDataSummaryOff(context, attrs);
if (TextUtils.isEmpty(summaryOn) && TextUtils.isEmpty(summaryOff)) {
summaryOn = getDataSummary(context, attrs);
}
updateOneRowWithFilteredData(database, localeStr, title, summaryOn, summaryOff,
null, fragmentName, screenTitle, iconResId, rank,
keywords, intentAction, intentTargetPackage, intentTargetClass,
true, key, -1 /* default user id */);
}
非CheckBoxPreference的设置项,会解析preference的title以及summary。CheckBoxPreference类型的设置项会解析summaryOn,summaryOff等。也就是说解析存在细微差别。
详细解析流程可关注Index.java中的indexFromResource()方法。
类二:
如下图代码所示:
sResMap.put(WifiSettings.class.getName(),
new SearchIndexableResource(
Ranking.getRankForClassName(WifiSettings.class.getName()),
NO_DATA_RES_ID,
WifiSettings.class.getName(),
R.drawable.ic_settings_wireless));
这类与类一的不同在于,它没有明确指定xml文件,这里是:NO_DATA_RES_ID,。那么这种情况,其会在其类中定义名称为:SEARCH_INDEX_DATA_PROVIDER的SearchIndexProvider,在其中会定义加载那些设置项。
4、如何为一个设置项定义多个匹配名字?
答:匹配逻辑本身是弱匹配,我们看下设置的匹配逻辑会匹配以下几项:
private static final String[] MATCH_COLUMNS_PRIMARY = {
IndexColumns.DATA_TITLE,
IndexColumns.DATA_TITLE_NORMALIZED,
IndexColumns.DATA_KEYWORDS
};
title就是每个设置项的title名称,TITLE_NORMALIZED只是对title做了一些格式化操作。最重要的就是我们的keyword了,我们可以使用keywords来实现为一个设置项指定额外匹配名称,例如:
<PreferenceScreen
android:key="brightness"
android:title="@string/brightness"
settings:keywords="@string/keywords_display_brightness_level">
<intent android:action="android.intent.action.SHOW_BRIGHTNESS_DIALOG" />
</PreferenceScreen>
5、系统设置是否支持搜索匹配加载外部设置项?
答:系统设置存在搜索匹配外部应用设置项的功能。系统设置会加载所有应用中AndroidManifest.xml中配置了“android.content.action.SEARCH_INDEXABLES_PROVIDER”的provider,并从该provider中读取设置项到设置的数据库中。
由于android5.0初步实现了该功能,系统中很多应用还没有进行Provider的创建,故而搜索匹配其他应用的体验性不是很好。
三、我们如何将我们新开发的设置项加入到系统设置中。
1、首先如果,新增加的设置项在一级目录,或者多层级目录,并且该设置项为leui新增的,即原生不存在的。需要将该一级设置项加入到:SearchIndexableResources的sResMap成员变量中。
2、如果是在原有设置项内新增设置项,保持title一级summary,fragmeng等配置ok。
郑重声明:本站内容如果来自互联网及其他传播媒体,其版权均属原媒体及文章作者所有。转载目的在于传递更多信息及用于网络分享,并不代表本站赞同其观点和对其真实性负责,也不构成任何其他建议。