Android 5.0 双卡信息管理分析

    首先,如前面的博文所讲的,Android5.0开始支持双卡了。另外,对于双卡的卡信息的管理,也有了实现,尽管还不是彻底完全完整,如卡的slot id, display name,iccid,color等,其设计思路居然跟以前接触到的一个平台是同样的,都是同不一样颜色来标识不一样的卡,让用户一目了然,只是5.0的实现目前还局限在FW框架里,应用层的实现尚未,相信,等到5.1或者再以后的版本中,咱们就能够在setting里看到对卡表示颜色、名称等进行设置的功能菜单啦。java

下面进入正题,来分析Android5.0的双卡信息是如何来维护的:android

1 卡信息的存储

    先说结论,5.0是将全部卡信息经过数据库进行保存的。数据库表URL:content://telephony/siminfo,对应到的数据库为telephony.db中的siminfo表,代码文件在TelephonyProvider.java,在这里能够看到createTable的详情,来看看这个表都包含哪些字段。git

 

总共设计了11个字段,下面这张图是从5.0模拟器上拉出来的telephony.db里截取到的,能够用来作示例:数据库

表名:设计模式

表数据示例:数组

下面分别介绍一下这些字段的含义。网络

1.1 _id

  这个自没必要说,android里的每一个db都有的,是数据库里的数据主key,这里的_id值也是之后代码里看到的subId,是在数据库中保存时所在的条目的惟一标识。有多少条数据,就说明保存了多少个sim卡的信息;框架

1.2 icc_id

  从卡上读取获得,是卡的惟一身份标识,世界上的全部sim卡,每一个卡都有不一样的iccid,就像身份证同样;如上面图中的16进制串89014103211118510720;ide

1.3 sim_id

  分配给卡的id序号,android设计从0开始,最大为卡槽个数,好比若是是双卡终端,那么只有多是0或者1;固然无卡时其值为-1,因此这里实际上是与卡槽固定对应的,卡槽若是有卡就取对应id,若是无卡,就设为-1;函数

1.4 display_name

  分配给卡的显示名字,从代码上来看开机后会尝试使用运营商名字,若是取不到,就使用简单的SUB 01这样的字串表示,等拿到运营商名字以后从新set,另外从下面的name_source字段的设计来看,android是容许用户来本身指定这个显示名的;

1.5 name_source

  代表display_name字段的来源,有两种来源,一是系统自动,name_source取值为0,另外一种就是来自用户指定,取值为1;

 1 /**
 2 * The name_source is the default
 3 * @hide
 4 */
 5 publicstaticfinalint NAME_SOURCE_DEFAULT_SOURCE =0;
 6 
 7 /**
 8 * The name_source is from the SIM
 9 * @hide
10 */
11 publicstaticfinalint NAME_SOURCE_SIM_SOURCE =1;
12 
13 /**
14 * The name_source is from the user
15 * @hide
16 */
17 publicstaticfinalint NAME_SOURCE_USER_INPUT =2;

 

1.6 color

  显示颜色,将使用颜色在UI上明显区分卡1和卡2;android设定每一个卡都只能从固定的几个颜色中取,以下:

 1 /** @hide */
 2 publicstaticfinal String COLOR ="color";
 3 
 4 /** @hide */
 5 publicstaticfinalint COLOR_1 =0;
 6 
 7 /** @hide */
 8 publicstaticfinalint COLOR_2 =1;
 9 
10 /** @hide */
11 publicstaticfinalint COLOR_3 =2;
12 
13 /** @hide */
14 publicstaticfinalint COLOR_4 =3;
15 
16 /** @hide */
17 publicstaticfinalint COLOR_DEFAULT = COLOR_1;

  这四种颜色根据主题是dark仍是light分别对应4种颜色,这些颜色其实并不是是色值,而是固定颜色的背景9.png图片,都定义在资源drawable里,看来是用来作backgroud用的。如

  sim_dark_blue sim_light_purple

其余几种颜色能够参考 SubscriptionController. setSimResource函数里去color资源数组的初始化。

1.7 number

  该卡对应的号码,phone number。 //TODO:研究一下这个是怎么获取到呢?

1.8 display_number_format

  标识number字段的格式,总共有固定的3种,取其一。

/** @hide */
publicstaticfinalint DISPLAY_NUMBER_NONE =0;

/** @hide */
publicstaticfinalint DISPLAY_NUMBER_FIRST =1;

/** @hide */
publicstaticfinalint DISPLAY_NUMBER_LAST =2;

/** @hide */
publicstaticfinalint DISLPAY_NUMBER_DEFAULT = DISPLAY_NUMBER_FIRST;

  从SubscriptionController. setDisplayNumberFormat()函数的注释能够看出点门道,

    *Set number display format. 0: none, 1: the first four digits, 2: the last four digits

  但搜了一下,对应的setDisplayNumber()函数并无跟这个format有关联,直接保存传入的number到数据库了。因此还不太清楚the first four digits 和 the last four digits的具体含义,等之后android应用层完善后应该能看到具体的使用方式。

1.9 data_roaming

  是否容许这张卡进行数据漫游,默认禁止漫游。

1 /** @hide */
2 publicstaticfinalint DATA_ROAMING_ENABLE =1;
3 
4 /** @hide */
5 publicstaticfinalint DATA_ROAMING_DISABLE =0;
6 
7 /** @hide */
8 publicstaticfinalint DATA_ROAMING_DEFAULT = DATA_ROAMING_DISABLE;

 

1.10 mcc

 移动国家码,从卡上读取获得,卡的mcc码;

1.11 mnc

移动网络码,从卡上读取获得,卡的mnc码。度娘到对于mcc和mnc的解释:

 

MCC 是 Mobile Country Code 的缩写,译为移动国家代码。它由三位数字组成。用于标识一个国家,但一个国家能够被分配多个 MCC 。好比美国的 MCC 有 310,311,和316。中国的 MCC 只有 460。 MNC 是 Mobile Network Code 的缩写,译为移动网络代码。它由二到三位数字组成。MNC和 MCC 合在一块儿惟一标识一个移动网络提供者。好比中国移动的 MNC 是 00,中国联通的 MNC 是 01,中国联通 CDMA 的 MNC 是 03,中国卫星全球星网的 MNC 是 04。 所以,460 00 就惟一标识了中国移动。

  因此卡的displayname应该也是经过mcc+mnc获得的。

 

2 主要工做类

  上面介绍了卡信息的数据设计,接下来看看有哪些类围绕着这些数据来对外提供接口和功能。

功能介绍

TelephonyProvider

siminfo数据库provider,直接操做DB,实现siminfo表的增删改查。

SubscriptionController

实现为远程service,在phone初始化时被建立,做为数据库的对外接口提供功能,其内部维护从数据库读取到的siminfo list,并实现了大量的如getSubId getDisplayName setDisplayName等getter和setter方法,这些方法维护siminfo list以及经过URL访问数据库来实现功能。

SubscriptionManager

该类全部的内部接口都实现为了static,也就是该类是一个纯粹提供接口的静态类,其内部并不实现具体的逻辑,只是经过调用SubscriptionController这个service的对应接口来完成工做,因此该类是一个对外接口的封装,APP能够直接经过SubscriptionManager.getSubId等来实现功能,不须要直接操做service。目前仍是Hide的,估计之后会开放给SDK。这种设计模式,android FW层用的不少,如SmsMnager、TelephonyManager等。

SubInfoRecordUpdater

卡信息变化的监听者和更新者,其在PhoneFactory中建立完phones以后被建立,起来以后会注册对 ACTION_SIM_STATE_CHANGED 的监听,收到监听以后更新对应siminfo的信息,如iccid、displayname(运营商名)、phonenumber。而且在本身内部维护了每一个卡的卡状态,这里的卡状态区别与ACTION_SIM_STATE_CHANGED所携带的卡状态,ACTION_SIM_STATE_CHANGED的卡状态有 LOCKED、READY、NOT READY、ABSENT等,是指的卡的具体状态,而这里的卡状态是指 有没有插卡、该卡槽的卡是否是变过了(换了一张卡)、卡槽的卡是一张没见过的新卡、卡槽的卡是位置互换啦、卡槽的卡没变化。【状态还真有点绕,管的挺多的啊。。。】这些状态是在收到ACTION_SIM_STATE_CHANGED以后,根据卡状态以及卡的iccid等一些信息算出来的,若是发现有新卡插入会进行广播。

SubInfoRecord

subinfo的可序列化实现,封装数据库数据。

 

  另外,在代码中还能够看到 Subscription 和 SubscriptionData这两个类,这两个其实只是数据封装,并不直接跟卡信息管理相关,其只是保存了一些卡的数据来提供给phone等使用,目前还找不到组织他们的接口,全局搜索会发现,好多地方google都注释掉了,逻辑还没完整。SubscriptionData是Subscription list,目前从代码来看,这两个尚未真正用起来,因此能够先无视了,不过要吐槽下google的代码,起名咋这么绕啊。另外还有个 CdmaSubscriptionSourceManager的类,这个是跟CDMA的卡提供者信息有关的,会影响到具体的网络行为,也跟本文的双卡信息管理无关。

3 工做流程

  经过上面主要类的介绍,基本上整个双卡信息管理的框架就出来了,画了一个图方便理解。

 

4总结

  5.0经过DB来保存和维护双卡信息,SubInfoRecordUpdater经过监听卡的变化动态更新数据库里的卡数据;SubscriptionController和SubscriptionManager经过各类接口来向外提供卡信息的查询和修改,这样看来逻辑仍是比较清晰明了的。

相关文章
相关标签/搜索