android5.0系統設定搜尋功能簡析,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。