Settings 搜索是调用的 SettingsIntelligence 应用的 SearchActivity,路径:android/packages/apps/SettingsIntelligence
流程图如下
在 PreIndexDataCollector.java 中的最后 get*** 函数中创建 ContentResolver 来查询获取数据。
而数据的来源就是 Settings 中 SettingsSearchIndexablesProvider , SettingsSearchIndexablesProvider 继承自 android.provider.SearchIndexablesProvider.java ,
<provider
android:name=".search.SettingsSearchIndexablesProvider"
android:authorities="com.android.settings"
android:multiprocess="false"
android:grantUriPermissions="true"
android:permission="android.permission.READ_SEARCH_INDEXABLES"
android:exported="true">
<intent-filter>
<action android:name="android.content.action.SEARCH_INDEXABLES_PROVIDER" />
</intent-filter>
</provider>
SearchIndexablesProvider 中只有一个 query 是有作用的,其他几个 insert delete update 操作都是抛出异常。 query 中对上面 PreIndexDataCollector 中的请求进行具体处理如下。
//SearchIndexablesProvider.java
@Override
public Cursor query(Uri uri, String[] projection, String selection, String[] selectionArgs,
String sortOrder) {
try {
switch (mMatcher.match(uri)) {
case MATCH_RES_CODE:
return queryXmlResources(null);
case MATCH_RAW_CODE:
return queryRawData(null);
case MATCH_NON_INDEXABLE_KEYS_CODE:
return queryNonIndexableKeys(null);
case MATCH_SITE_MAP_PAIRS_CODE:
return querySiteMapPairs();
case MATCH_SLICE_URI_PAIRS_CODE:
return querySliceUriPairs();
case MATCH_DYNAMIC_RAW_CODE:
return queryDynamicRawData(null);
default:
throw new UnsupportedOperationException("Unknown Uri " + uri);
}
} catch (UnsupportedOperationException e) {
throw e;
} catch (Exception e) {
Log.e(TAG, "Provider querying exception:", e);
return null;
}
}
queryXmlResources 等几个操作具体实现就回到 Settings 应用模块中了,在 SettingsSearchIndexablesProvider 中进行实现,以 queryXmlResources 为例
//SettingsSearchIndexablesProvider.java
@Override
public Cursor queryXmlResources(String[] projection) {
final MatrixCursor cursor = new MatrixCursor(INDEXABLES_XML_RES_COLUMNS);
final List<SearchIndexableResource> resources =
getSearchIndexableResourcesFromProvider(getContext());
for (SearchIndexableResource val : resources) {
final Object[] ref = new Object[INDEXABLES_XML_RES_COLUMNS.length];
ref[COLUMN_INDEX_XML_RES_RANK] = val.rank;
ref[COLUMN_INDEX_XML_RES_RESID] = val.xmlResId;
ref[COLUMN_INDEX_XML_RES_CLASS_NAME] = val.className;
ref[COLUMN_INDEX_XML_RES_ICON_RESID] = val.iconResId;
ref[COLUMN_INDEX_XML_RES_INTENT_ACTION] = val.intentAction;
ref[COLUMN_INDEX_XML_RES_INTENT_TARGET_PACKAGE] = val.intentTargetPackage;
ref[COLUMN_INDEX_XML_RES_INTENT_TARGET_CLASS] = null; // intent target class
cursor.addRow(ref);
}
return cursor;
}
... ...
private List<SearchIndexableResource> getSearchIndexableResourcesFromProvider(Context context) {
final Collection<SearchIndexableData> bundles = FeatureFactory.getFactory(context)
.getSearchFeatureProvider().getSearchIndexableResources().getProviderValues();
List<SearchIndexableResource> resourceList = new ArrayList<>();
for (SearchIndexableData bundle : bundles) {
Indexable.SearchIndexProvider provider = bundle.getSearchIndexProvider();
final List<SearchIndexableResource> resList =
provider.getXmlResourcesToIndex(context, true);
if (resList == null) {
continue;
}
for (SearchIndexableResource item : resList) {
item.className = TextUtils.isEmpty(item.className)
? bundle.getTargetClass().getName()
: item.className;
}
resourceList.addAll(resList);
}
return resourceList;
}
最终通过 getProviderValues() 获取所有的带 @SearchIndexable 注释的类。再获取里面的 Indexable.SearchIndexProvider 内部类,所有的相关类里面的这个内部类都是一样的命名,好找
public static final BaseSearchIndexProvider SEARCH_INDEX_DATA_PROVIDER =
new BaseSearchIndexProvider(R.xml.display_settings) {
@Override
public List<String> getNonIndexableKeys(Context context) {
final List<String> keys = super.getNonIndexableKeys(context);
keys.add("auto_brightness_entry");
return keys;
}
@Override
protected boolean isPageSearchEnabled(Context context) {
return true;
}
};
这里面重要的几个方法功能大致介绍下。首先构造函数中的 R.xml.display_settings ,这可以看下 BaseSearchIndexProvider 类中,其实就是给定 getXmlResourcesToIndex 方法的xml参数。添加xml中所有 key 的搜索项目。
getNonIndexableKeys 这个方法中返回就是无需搜索的,从搜索列表中移除的 key 的集合。
isPageSearchEnabled 这个返回 false 则表示这个 display_settings xml 中所有的 key 都不需要的搜索,全部移除。具体使用是在 BaseSearchIndexProvider 中。
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)