Android CarrierConfig 参数项和正则匹配逻辑

背景

在编写CarrierConfig的时候经常出现配置不生效的情况,比如运营商支持大范围的imsi,或者是测试人员写卡位数的问题等等,因此就需要模式匹配(包含但不限于正则表达式)。

  1. 基本概念:

    • 模式匹配涉及定义一个“模式”,该模式可以是一个字符串、正则表达式或其他结构。系统将此模式应用于目标数据,找出符合该模式的部分。
  2. 应用场景:

    • 字符串匹配: 查找特定字符序列或模式,例如在文本中查找单词或短语。
    • 数据解析: 分析和提取数据,例如从 JSON 或 XML 文档中提取信息。
    • 正则表达式: 使用正则表达式进行复杂的字符串匹配和替换操作。
    • 逻辑匹配: 例如在函数式编程中,使用模式匹配来简化条件语句。
  3. 编程语言中的模式匹配实现:

    很多编程语言都支持模式匹配的特性,例如:
    • Haskell: 强大的模式匹配功能,可用于列表、元组等数据结构。        
    • Scala: 提供内置的模式匹配语法,用于匹配类型和结构。
    • Java: 使用 Pattern 和 Matcher 类进行正则表达式匹配。
    • Python: 使用 re 模块进行正则表达式匹配。

解析逻辑

packages/apps/CarrierConfig/src/com/android/carrierconfig/DefaultCarrierConfigService.java

详细代码

  1. 参数解析:

    • xmlImsi: 这是从 XML 资源中获取的 IMSI 表达式,它可能是一个正则表达式。
    • id: 这是一个 CarrierIdentifier 对象,提供了当前的 IMSI。
  2. 获取当前 IMSI:

    • String currentImsi = id.getImsi();: 该行代码从 CarrierIdentifier 对象中获取当前的 IMSI 字符串。
  3. 正则表达式匹配:

    • Pattern imsiPattern = Pattern.compile(xmlImsi, Pattern.CASE_INSENSITIVE);: 这行代码将 XML 中的 IMSI 表达式编译成正则表达式模式,并设置为不区分大小写(尽管在 IMSI 字符串中通常不涉及大小写问题)。
    • Matcher matcher = imsiPattern.matcher(currentImsi);: 这行代码创建一个 Matcher 对象,用于比较当前 IMSI。
  4. 执行匹配:

    • matchFound = matcher.matches();: 这个方法检查当前 IMSI 是否与正则表达式匹配。

参数检查 

checkFilters检查的参数包含:

如下代码可见,支持正则匹配的只有imsi和sp。

    /*** Checks to see if an XML node matches carrier filters.** <p>This iterates over the attributes of the current tag pointed to by {@code parser} and* checks each one against {@code id} or {@link Build.DEVICE} or {@link R.string#sku_filter} or* {@link Build.BOARD}. Attributes that are not specified in the node will not be checked, so a* node with no attributes will always return true. The supported filter attributes are,* <ul>*   <li>mcc: {@link CarrierIdentifier#getMcc}</li>*   <li>mnc: {@link CarrierIdentifier#getMnc}</li>*   <li>gid1: {@link CarrierIdentifier#getGid1}</li>*   <li>gid2: {@link CarrierIdentifier#getGid2}</li>*   <li>spn: {@link CarrierIdentifier#getSpn}</li>*   <li>imsi: {@link CarrierIdentifier#getImsi}</li>*   <li>device: {@link Build.DEVICE}</li>*   <li>vendorSku: {@link SystemConfig.VENDOR_SKU_PROPERTY}</li>*   <li>hardwareSku: {@link SystemConfig.SKU_PROPERTY}</li>*   <li>board: {@link Build.BOARD}</li>*   <li>cid: {@link CarrierIdentifier#getCarrierId()}*   or {@link CarrierIdentifier#getSpecificCarrierId()}</li>*   <li>sku: {@link R.string#sku_filter} "sku_filter" that OEM customizable filter</li>* </ul>* </p>** <p>* The attributes imsi and spn can be expressed as regexp to filter on patterns.* The spn attribute can be set to the string "null" to allow matching against a SIM* with no spn set.* </p>** @param parser an XmlPullParser pointing at a START_TAG with the attributes to check.* @param id the carrier details to check against.* @param sku a filter to be customizable.* @return false if any XML attribute does not match the corresponding value.*/static boolean checkFilters(XmlPullParser parser, @Nullable CarrierIdentifier id, String sku) {String vendorSkuProperty = SystemProperties.get("ro.boot.product.vendor.sku", "");String hardwareSkuProperty = SystemProperties.get("ro.boot.product.hardware.sku", "");for (int i = 0; i < parser.getAttributeCount(); ++i) {boolean result = true;String attribute = parser.getAttributeName(i);String value = parser.getAttributeValue(i);switch (attribute) {case "mcc":result = (id == null) || value.equals(id.getMcc());break;case "mnc":result = (id == null) || value.equals(id.getMnc());break;case "gid1":result = (id == null) || value.equalsIgnoreCase(id.getGid1());break;case "gid2":result = (id == null) || value.equalsIgnoreCase(id.getGid2());break;case "spn":result = (id == null) || matchOnSP(value, id);break;case "imsi":result = (id == null) || matchOnImsi(value, id);break;case "device":result = value.equalsIgnoreCase(Build.DEVICE);break;case "vendorSku":result = value.equalsIgnoreCase(vendorSkuProperty);break;case "hardwareSku":result = value.equalsIgnoreCase(hardwareSkuProperty);break;case "board":result = value.equalsIgnoreCase(Build.BOARD);break;case "cid":result = (id == null) || (Integer.parseInt(value) == id.getCarrierId())|| (Integer.parseInt(value) == id.getSpecificCarrierId());break;case "name":// name is used together with cid for readability. ignore for filter.break;case "sku":result = value.equalsIgnoreCase(sku);break;default:Log.e(TAG, "Unknown attribute " + attribute + "=" + value);result = false;break;}if (!result) {return false;}}return true;}

IMSI的匹配逻辑

  1. 参数解析:

    • xmlImsi: 这是从 XML 资源中获取的 IMSI 表达式,它可能是一个正则表达式。
    • id: 这是一个 CarrierIdentifier 对象,提供了当前的 IMSI。
  2. 获取当前 IMSI:

    • String currentImsi = id.getImsi();: 该行代码从 CarrierIdentifier 对象中获取当前的 IMSI 字符串。
  3. 正则表达式匹配:

    • Pattern imsiPattern = Pattern.compile(xmlImsi, Pattern.CASE_INSENSITIVE);: 这行代码将 XML 中的 IMSI 表达式编译成正则表达式模式,并设置为不区分大小写(尽管在 IMSI 字符串中通常不涉及大小写问题)。
    • Matcher matcher = imsiPattern.matcher(currentImsi);: 这行代码创建一个 Matcher 对象,用于比较当前 IMSI。
  4. 执行匹配:

    • matchFound = matcher.matches();: 这个方法检查当前 IMSI 是否与正则表达式匹配。
    /*** Check to see if the IMSI expression from the XML matches the IMSI of the* Carrier.** @param xmlImsi IMSI expression fetched from the resource XML* @param id Id of the evaluated CarrierIdentifier* @return true if the XML IMSI matches the IMSI of CarrierIdentifier, false*         otherwise.*/static boolean matchOnImsi(String xmlImsi, CarrierIdentifier id) {boolean matchFound = false;String currentImsi = id.getImsi();// If we were able to retrieve current IMSI, see if it matches.if (currentImsi != null) {//使用 Pattern 和 Matcher 接口,//使用正则表达式来匹配 xmlImsi 与 currentImsi。//这允许 xmlImsi 采用正则表达式的形式,从而支持更复杂的匹配逻辑,比如匹配特定模式的 IMSI 字符串。Pattern imsiPattern = Pattern.compile(xmlImsi, Pattern.CASE_INSENSITIVE);Matcher matcher = imsiPattern.matcher(currentImsi);matchFound = matcher.matches();}return matchFound;}

资料

  • 展讯平台参考:CarrierConfig配置使用和加载流程简介-CSDN博客
  • AOSP:【Telephony】CarrierConfig加载流程解析&运营商ims配置增删查改(AOSP)-CSDN博客

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/web/59100.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

可编辑PPT | 指挥中心系统建设与应用方案

本方案是一份全面的指挥中心系统建设与应用方案&#xff0c;涵盖了建设方案分析、指挥调度、远程通讯、会务管理等多个方面&#xff0c;旨在通过整合语音、视频监控、会议、指挥调度等多种技术&#xff0c;构建一个现代化、网络化、智慧化的城市指挥中心&#xff0c;以提高应对…

【CentOS】中的Firewalld:全面介绍与实战应用(下)

&#x1f407;明明跟你说过&#xff1a;个人主页 &#x1f3c5;个人专栏&#xff1a;《Linux &#xff1a;从菜鸟到飞鸟的逆袭》&#x1f3c5; &#x1f516;行路有良友&#xff0c;便是天堂&#x1f516; 目录 一、引言 1、iptables 时代 2、firewalld 时代 二、服务管…

人工智能在智能家居中的应用

&#x1f493; 博客主页&#xff1a;瑕疵的CSDN主页 &#x1f4dd; Gitee主页&#xff1a;瑕疵的gitee主页 ⏩ 文章专栏&#xff1a;《热点资讯》 人工智能在智能家居中的应用 人工智能在智能家居中的应用 人工智能在智能家居中的应用 引言 人工智能概述 定义与原理 发展历程 …

qt QWidgetAction详解

1、概述 QWidgetAction是Qt框架中的一个类&#xff0c;它继承自QAction类。QWidgetAction允许开发者将自定义的小部件&#xff08;widget&#xff09;插入到基于QAction的容器中&#xff0c;如工具栏或菜单项中。这使得QWidgetAction成为创建复杂用户界面和自定义菜单项的强大…

一文了解什么是腾讯云开发

一文了解什么是腾讯云开发 关于云开发的猜想腾讯云开发腾讯云开发的优势无服务跨平台轻松托管节约成本 快速上手云开发环境快速搭建管理后台 云开发体验 关于云开发的猜想 说到云开发&#xff0c;作为开发者的大家是否大概就有了想法。比如说过去的开发工作都是在自己本地电脑…

2.操作系统常问面试题1

2.1 Linux 中查看进程运行状态的指令、查看内存使用情况的指令、tar解压文件的参数是什么 1、查看进程运行状态的指令&#xff1a; ps aux 列出所有进程的详细信息。 ps aux | grep PID &#xff0c;查看具体某PID进程状态。 在 Linux 中&#xff0c;可以使用以下指令来查看进…

LED和QLED的区别

文章目录 1. 基础背光技术2. 量子点技术的引入3. 色彩表现4. 亮度和对比度5. 能效6. 寿命7. 价格总结 LED和 QLED都是基于液晶显示&#xff08;LCD&#xff09;技术的电视类型&#xff0c;但它们在显示技术、色彩表现和亮度方面有一些关键区别。以下是两者的详细区别&#xff…

多路转接之poll

多路转接之poll 一、关于poll认识poll基于poll实现的服务器的原理 二、基于poll实现的服务器main.cpppollServer.hppsock.hppLog.hpppublic.hpp 一、关于poll 认识poll #include <poll.h> int poll(struct pollfd *fds, nfds_t nfds, int timeout);struct pollfd {int …

# filezilla连接 虚拟机ubuntu系统出错“尝试连接 ECONNREFUSED - 连接被服务器拒绝, 失败,无法连接服务器”解决方案

filezilla连接 虚拟机ubuntu系统出错“尝试连接 ECONNREFUSED - 连接被服务器拒绝&#xff0c; 失败&#xff0c;无法连接服务器”解决方案 一、问题描述&#xff1a; 当我们用filezilla客户端 连接 虚拟机ubuntu系统时&#xff0c;报错“尝试连接 ECONNREFUSED - 连接被服务…

TCP编程API

这里写自定义目录标题 主要的 TCP 编程 API 函数1.1 socket()1.2 bind()1.3 listen()1.4 accept()1.5 connect()1.6 send()1.7 recv()1.8 close() 主要的 TCP 编程 API 函数 1.1 socket() 创建一个新的套接字。 int socket(int domain, int type, int protocol);domain&…

STM32WB55RG开发(1)----开发板测试

STM32WB55RG开发----1.开发板测试 概述硬件准备视频教学样品申请源码下载产品特性参考程序生成STM32CUBEMX串口配置LED配置堆栈设置串口重定向主循环演示 概述 STM32WB55 & SENSOR是一款基于STM32WB55系列微控制器的评估套件。该套件采用先进的无线通信技术&#xff0c;支…

人工智能、机器学习与深度学习:层层递进的技术解读

引言 在当今科技快速发展的时代&#xff0c;人工智能&#xff08;AI&#xff09;已经成为一个热门话题&#xff0c;几乎渗透到了我们生活的方方面面。从智能手机的语音助手&#xff0c;到自动驾驶汽车&#xff0c;再到医疗诊断中的图像识别&#xff0c;人工智能的应用正在改变我…

【Java学习】电脑基础操作和编程环境配置

CMD 在Windows中用命令行的方式操作计算机。 打开CMD Win R输入CMD按下回车键 Win E 进入我的电脑 常用的CMD命令 盘符名称冒号 说明&#xff1a;盘符切换 举例&#xff1a;E:回车&#xff0c;表示切换到E盘 dir 说明&#xff1a;查看当前路径下的内容 cd目录 说明&a…

Mac中禁用系统更新

Mac中禁用系统更新 文章目录 Mac中禁用系统更新1. 修改hosts&#xff0c;屏蔽系统更新检测联网1. 去除系统偏好设置--系统更新已有的小红点标记 1. 修改hosts&#xff0c;屏蔽系统更新检测联网 打开终端&#xff0c;执行命令&#xff1a; sudo vim /etc/hosts127.0.0.1 swdis…

Unity3D UI 双击和长按

Unity3D 实现 UI 元素双击和长按功能。 UI 双击和长按 上一篇文章实现了拖拽接口&#xff0c;这篇文章来实现 UI 的双击和长按。 双击 创建脚本 UIDoubleClick.cs&#xff0c;创建一个 Image&#xff0c;并把脚本挂载到它身上。 在脚本中&#xff0c;继承 IPointerClickHa…

sql专题 之 where和join on

文章目录 前言where介绍使用过滤结果集关联两个表 连接外连接内连接自然连接 使用inner join和直接使用where关联两个表的区别总结 前言 从数据库查询数据时&#xff0c;一张表不足以查询到我们想要的数据&#xff0c;更多的时候我们需要联表查询。 联表查询我们一般会使用连接…

LeetCode 热题100之 动态规划1

对于动态规划的问题&#xff0c;解题步骤有以下几部(总结为动态规划五部曲&#xff1a;参考代码随想录动态规划 确定dp数组以及下标的含义&#xff1b;确定递推公式&#xff1b;dp数组如何初始化&#xff1b;确定遍历顺序&#xff1b;举例推导dp数组 下面的解题思路分析都将从…

python可视化将多张图整合到一起(画布)

这周有点事忙着&#xff0c;没时间重温刚结束的Mathurcup数学建模&#xff0c;这两天也是再看了下&#xff0c;论文还是赶紧挺烂的&#xff0c;但比国赛又有进步&#xff08;说起国赛又不得不抱怨了&#xff0c;基本其余省份都发了&#xff0c;但江西......哎&#xff09;。哎&…

MFC图形函数学习07——画扇形函数

绘制扇形函数是MFC中绘图的基本函数&#xff0c;它绘制的仍是由椭圆弧与椭圆中心连线构成的椭圆扇形&#xff0c;特例是由圆弧与圆心连线构成的圆扇形。 一、绘制扇形函数 原型&#xff1a;BOOL Pie(int x1,int y1,int x2,int y2,int x3,int y3,int x4,int y4); …

vue 依赖注入(Provide、Inject )和混入(mixins)

Prop 逐级透传问题​ 通常情况下&#xff0c;当我们需要从父组件向子组件传递数据时&#xff0c;会使用 props。想象一下这样的结构&#xff1a;有一些多层级嵌套的组件&#xff0c;形成了一棵巨大的组件树&#xff0c;而某个深层的子组件需要一个较远的祖先组件中的部分数据。…