Android R Settings搜索框功能流程

2023-05-16

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(使用前将#替换为@)

Android R Settings搜索框功能流程 的相关文章

  • 模拟器中 Google Wear 上的语音识别器没有语音输入

    我试图使用 Google Wear 网站上的自由形式语音输入 在 hello world 示例中 我刚刚添加了对 textView 的单击 它确实从语音意图中调出 立即发言 活动 但模拟器无法检测到我的麦克风发出的任何声音 我使用的是 Ma
  • 通过代码在创建时突出显示 ListView 项目

    我想在创建 listView 时突出显示 ListView 的第一行 0 我尝试了不同的方法 就像您在注释代码中看到的那样 但没有任何效果 这很奇怪 因为 OnItemClickListener 中的突出显示工作正常 它通过 xml 选择器
  • Android中将JSON数据存储到本地数据库

    好的 我创建了一个应用程序 它使用 JSON 从我的服务器检索数据 现在我想将检索到的数据存储在手机的本地存储 数据库中 我该怎么做 我是android编程新手 这是我从服务器收到的 JSON messages id 44 issender
  • 为什么不能在 Fragment 中使用 ViewPager?它实际上是

    有信息无法使用ViewPager在一个Fragment在许多来源中 例如 Android 开发者繁忙编码指南 http commonsware com 作者 Mark Murphy 或者类似的帖子this https stackoverfl
  • 如何在 Android 应用程序中隐藏 Flutterwave API 密钥

    我正在构建一个 Android 应用程序 目前正在将 Flutterwave 集成到我的应用程序中以进行支付 建议我永远不要将 Flutterwave API 密钥放在我的应用程序上 那么我该如何隐藏这些键呢 我正在使用 Retrofit
  • 蓝牙 BLE Android 以最大吞吐量写入外设

    我们公司开发了一个具有蓝牙 BLE 的硬件单元 并且我们在 Nexus 7 2013 中有一个服务应用程序 我们希望使用它向该单元发送固件文件 文件最大可达 500kb BT芯片是德州仪器CC2540 我浏览了大量的页面 并扫描了 Stac
  • 如何使用 Google 的 GithubBrowserSample 方法在片段之间共享视图模型?

    我对 Android 架构组件的使用非常陌生 因此我决定使用 GithubBrowserSample 来构建我的应用程序来实现我的许多用例 但我有一个问题 我不知道使用这种方法在片段之间共享视图模型的正确方法是什么 我想共享视图模型 因为我
  • 如何清除Android剪贴板?

    我发现的方法都不起作用 这是我尝试过的 1 使用clearPrimaryClip 的方法ClipboardManager class ClipboardManager clipboard ClipboardManager getSystem
  • Android 和 Google 地图内部片段以及其他控件和 viewpager

    我是android编程新手 我有一个带有 3 个页面 片段 的小应用程序 使用 pageradapter 和 viewpager 在它们之间滑动 其中一个页面包含复选框 和其他控件 和地图 我的问题是程序在启动时崩溃 Fragment co
  • 如何在android中的谷歌地图上聚焦标记

    我只是想知道我们是否可以关注 Android 应用程序中添加的标记 如果是 怎么办 或者有没有其他方法可以完成这项任务 可以说我使用下面的代码添加了一个标记 map addMarker new MarkerOptions title tit
  • 如何在 60 分钟后删除共享首选项

    我想存储登录数据 但希望在 60 分钟后删除该数据 执行此操作的正确方法是什么 在这 60 分钟内可以关闭 停止 打开应用程序 我不想使用内部数据库 这是我的访问代码SharedPreferences sharedpreferences g
  • Android - 存储对ApplicationContext的引用

    我有一个静态 Preferences 类 其中包含一些应用程序首选项和类似的内容 可以在那里存储对 ApplicationContext 的引用吗 我需要该引用 以便我可以在不继承 Activity 的类中获取缓存文件夹和类似内容 你使用的
  • 以 HTML 格式发送电子邮件

    我想发送 HTML 格式的电子邮件 如下图所示 我怎样才能做到这一点 请帮我 提前致谢 String body new String table tr td br header td tr br br Get b Best Score b
  • Android 中 Activity 之间的 3D 动画

    How to create animation between two Activity look like As Screen shot in android 搜索jazzyviewpager 这是link https github co
  • Android计算两个日期之间的天数

    我编写了以下代码来查找两个日期之间的天数 startDateValue new Date startDate endDateValue new Date endDate long diff endDateValue getTime star
  • Android ScrollView,检查当前是否滚动

    有没有办法检查标准 ScrollView 当前是否正在滚动 方向是向上还是向下并不重要 我只需要检查它当前是否正在滚动 ScrollView当前形式不提供用于检测滚动事件的回调 有两种解决方法可用 1 Use a ListView并实施On
  • 调试android数据绑定?

    谁能告诉我如何调试或找到数据绑定生成的代码 从this https www youtube com watch v NBbeQMOcnZ0链接我发现它生成了所需的代码 我猜您正在寻找自动生成的绑定 java 文件 我也在寻找他们 最后我在这
  • Android AppWidgetManager 方法 updateAppWidget 无法设置意图、加载数据。而且它是随机发生的

    我的小部件由 2 个按钮和一个显示数据的列表视图组成 大多数时候 当调用小部件提供程序的 onUpdate 方法时 一切都会正常加载 每个人都很高兴 但是我注意到有时在调用更新方法后 小部件完全无法加载其数据 列表视图为空 所有按钮均无响应
  • Android:透明活动问题

    最近 在我们的一款生产应用程序上 透明活动已停止工作 我的意思是它变成了黑色背景而不是透明背景 当我将活动的背景颜色设置为纯色 即红色 绿色等 时 它的应用不会出现问题 该问题可能是由于迁移到 AndroidX 引起的 但我没有这方面的证据
  • 如何用LoaderManager自动重新查询

    我有一个应用程序显示来自 SQLite DB 的数据 并且数据不断变化 所以显然 我认为我应该使用 LoaderManager 来显示数据 我读过一些关于将 LoaderManager 与 SQLite 结合使用的内容 然后看到了亚历克斯

随机推荐

  • 传统CD车机面板操作说明

    转自http bbs hifidiy net thread 675597 1 1 html 一般CD车机带USB SD卡的面板操作说明 1 1 控制面板外观图 2 0 基本 共同 功能操作说明 2 1 开启和关闭电源 静音开关 按 钮为开启
  • 汽车总线系统通信协议

    天合汽车零部件 xff08 上海 xff09 有限公司 上海交通大学区域光纤通信网与新型光通信系统国家重点实验室 xff08 上网时间 xff1a 2006 11 xff09 摘要 xff1a 本文主要针对汽车电子控制系统和车载多媒体系统
  • 算法——连续性后处理(把26邻域连续的变成6邻域连续的)

    文章目录 1 概念 1 1 6邻域连续 1 2 18邻域连续 1 3 26邻域连续 1 4 总结 2 目标 3 严格一点的 3 1 原理描述 3 1 1 18邻域连续补充 3 1 2 26邻域连续补充 3 2 代码实现 C 4 宽松一点的
  • RedHat Linux下安装JDK1.7报错Permission denied

    在RedHat Linux5 中安装JDK1 7时 xff0c 当我解压jdk xff0c 并且配置好了环境变量 xff0c 测试的时候 xff0c 报以下错误 root 64 jingfeng01 java version Error d
  • 几种压缩算法的压缩和速度比较

    Quick Benchmark Gzip vs Bzip2 vs LZMA vs XZ vs LZ4 vs LZO EDIT Add zstd Contents hide 1 Selected archives2 Test conditio
  • DDR低功耗模式

    DDR规格 xff1a DDR工作状态图 xff1a DDR 刷新描述 xff1a 电特性 xff1a 工作模式简介 xff1a 1 1 自刷新模式 xff08 Self Refresh Mode xff09 DDR4 SDRAM中自刷新超
  • 嵌入式Linux的低功耗策略

    引 言 由于Linux系统具备嵌入式操作系统需要的很多特色 xff0c 如适应于多种CPU和多种硬件平台 性能稳定 可裁剪性很好 源码开放 研发和使用简单等 现在 xff0c 基于Linux应用的嵌入式设备日益增多 xff0c Linux正
  • libevent实现的HTTP Server

    在使用C语言编码时 有时候需要实现一个HTTP接口 我们可以选择使用libevent库来实现 以下代码演示了使用libevent 并同时支持多线程处理HTTP的请求 头文件 引入的头文件 span class token macro pro
  • Python爬虫完整案例 - 爬取百度百科词条信息

    概述 一个完整的爬虫 xff0c 一般由以下5个组件构成 1 URL管理器 负责维护待爬取URL队列 和已爬取URL队列 xff0c 必须拥有去重功能 2 HTML下载器 负责根据调度器从URL管理器中取出的url xff0c 下载html
  • android apk 签名(平台和普通签名)

    因为做了太多的终端项目 xff0c 客户总会有自己的apk提供 xff0c 这时候各种签名问题就来了 xff0c 最近整理了一下相关知识 xff0c 分享给大家 签名的用处 xff1a 1 应用程序升级 xff1a 如果你希望用户无缝升级到
  • scikit-learn介绍

    在机器学习和数据挖掘的应用中 xff0c scikit learn是一个功能强大的python包 在数据量不是过大的情况下 xff0c 可以解决大部分问题 学习使用scikit learn的过程中 xff0c 我自己也在补充着机器学习和数据
  • 【JUC】CompletableFuture超时处理 配置线程池

    CompletableFuture 简介使用方法代码 简介 xff1a 项目中一个统计的业务场景 xff0c 使用原生的CompletableFuture异步多个任务查询mysql数据 xff0c 少量请求无问题 xff0c 但是测试过程中
  • 使用mysql命令行导出导入MariaDB库数据中文乱码问题解决

    问题 xff1a 到MariaDB bin目录下 xff0c 使用shit 43 右键打开powershell xff0c 执行mysqldump命令导出ems2库数据为sql文件 xff0c 命令中设置字符集为utf8 xff0c 则生成
  • :app:checkDebugDuplicateClasses Execute taskAction

    今天把AS从2 3 3升为3 4 2后 xff0c 导入项后发现报这个 app checkDebugDuplicateClasses的错 xff1a 然后查看了日志 xff0c 真是长篇大论 xff0c 一头雾水 org gradle ap
  • 3D Slicer/ITK-SNAP常见使用

    不是医生 是程序员 使用侧重点不一定相同 文章目录 1 3D Slicer使用 1 0 常见快捷键 1 1 三视图联动 1 2 在model视图查看三视图 1 3 最大化某个视图 1 4 改segment的标号 label 1 5 常见插件
  • 某些.csh .sh脚本无法在shell下执行的问题解决

    背景 最近换了一个环境 xff0c 登录后执行一个环境相关配置的 csh脚本时发现某些执行字段无法识别 xff0c 这种一般就是不同bash支持的脚本语言的差异问题 解决 查询当前shell的bash xff1a echo SHELL 当前
  • Linux 权能综述

    为了执行权限检查 xff0c 传统的 UNIX 实现区分两种类型的进程 xff1a 特权进程 xff08 其有效用户 ID 为0 xff0c 称为超级用户或 root xff09 xff0c 和非特权用户 xff08 其有效 UID 非0
  • EGL Context 创建

    继续 EGL context 创建的分析 eglInitialize 来看 EGL10 eglInitialize 的实现 com google android gles jni EGLImpl 中 xff0c 这个方法的实现如下 xff1
  • 【嵌入式】如何使用JLINK RTT打印log日志

    没有串口的情况下可以使用JLINK的RTT即 Real Time Transfer功能 RTT的工作原理大致就是在内存里面创建一个RTT控制块RTT Control Block xff0c 即SEGGER RTT CB结构体 这个结构体里面
  • Android R Settings搜索框功能流程

    Settings 搜索是调用的 SettingsIntelligence 应用的 SearchActivity xff0c 路径 xff1a android packages apps SettingsIntelligence 流程图如下