android 信号研究(包括信号图标和信号优化)

一.手机信号相关概念

二.信号优化

三.信号图标

 

一.手机信号相关概念

1.手机信号的传播    

        首先,我们了解手机信号是怎样传播的:以电磁波的形式在空气中进行传播。当手机拨打电话时,会把语音转化成信号,然后通过电磁波的形式,发送到距离最近的基站,基站接收到信号之后,再通过交换机转发到覆盖对方手机信号的基站,然后再把信号发送给对方手机,手机接收到信号之后再把信号转换成语音,从而实现双方通话。简而言之,手机与手机之前的通信是通过基站传播。

        其次,了解基站分布:由于信号是以电磁波的形式通过基站在不同区域之间进行传播的,但是电磁波传输会随着距离的增加而递减。因此为让信号能够覆盖的范围足够广,需设立很多经过精密计算分布为六边形的基站。

        再次,手机信号减弱的原因:一是信号传播随距离增加而递减;二是信号传播是直线传播,途中如遇阻碍并不会拐弯,故此会影响信号强弱。

 

2.相关单位

dBm(1毫瓦的分贝数):      衡量手机信号强度的通用指标

asu(alone signal unit 独立信号单元):Google给android手机定义的特有信号单位

换算:dBm =-113+2*asu

EC/N0 : 信噪比(越大越好)

RSCP (Received Signal Code Power):  接收信号码功率,即信号强度

 

详细介绍下dBm和asu两者:        

asu:alone signal unit 独立信号单元,是一种模拟信号。asu仅仅代表手机将它的位置传递给附近的信号塔的速率。它和dbm测量的是一样的东西,但是是以一种更加线性的方式来表示。

dbm:是一个表示功率绝对值的值(也可以认为是以1mw功率为基准的一个比值),计算公式为:10log(功率值/1mw)。        

[例] 如果功率p为1mw,折算为dbm后为0dbm。        

[例] 对于0.01mw的功率,按dbm单位进行折算后的值应为: 10log(0.01/1)=-20dbm。      

这个数值越大,表明信号越好。由于手机信号强度一般较小,折算成为dbm一般都是负数。 中国移动的规范规定,手机接收电平>=(城市取-90dbm;乡村取-94dbm) 时,则满足覆盖要求, 也就是说此处无线信号强度满足覆盖要求.-67dbm要比-90dbm信号要强20多个db, 那么它在打电话接通成功率和通话过程中的话音质量都会好的多。再引入一个相关概念db。        

db:是一个表征相对值的值,纯粹的比值,只表示两个量的相对大小关系,没有单位,当考虑甲的功率相比于乙功率大或小多少个db时,按下面的计算公式:10log(甲功率/乙功率),如果采用两者的电压 比计算,要用20log(甲电压/乙电压)。

[例] 甲功率比乙功率大一倍,那么10lg(甲功率/乙功率)=10lg2=3db,即甲的功率比乙的功率大3 db。反之,如果甲的功率是乙的功率的一半,则甲的功率比乙的功率小3 db。     总结:dbm是负数,越接近0信号强度越高,信号越好,但不可能为0。asu为正数,值越大信号越好。db是两个量之间的比值,表示两个量间的相对大小,而dbm则是表示功率绝对大小的值。

 

3.移动通信及其技术

最近这5G是火的不行啊,我们呢就以1G2G3G4G5G的区别来做开头开始这个信号研究的话题。

首先要了解在移动通信领域的两个概念:模拟通信系统和数字通信系统。

它们的区别:

具体说就是调制方式不同而已。

模拟通信,技术很成熟,就是将模拟信号与载波进行调制,使其带有一定载波特性,又不失模拟信号的独特性,接受端通过低通滤波器,还原初始模拟信号。
而数字信号,首先进行采样,对于采样幅值进行编码(0,1编码),然后进行调制,相移键控等。接受端还原即可。
区别在于,由于数字通信其传输数字抽样信号,在接受端可以得到还原,所以信号传输率高。而模拟信号,是对于信号的直接调制,与载波相乘,当传输途中有干扰时,对于系统的冲击,是不可修复的,所以造成失桢。相对而言,数字通信优于模拟通信。

这些个GGG的有啥区别呢:

1G:
第一代即我们所说的1G称为语音时代,简单来说就是“大哥大”时代,采用的技术是模拟通信系统,同时受制于技术和成本等因素,普及率并不高。
 
2G:
第二代无线蜂窝电话通讯协议
2g是数字通信(数字通信(digital telecommunications)是用数字信号作为载体来传输消息,或用数字信号对载波进行数字调制后再传输的通信方式。它可传输电报、数字数据等数字信号,也可传输经过数字化处理的语声和图像等模拟信号),当然3G4G5G也是,为3G和4G,5G奠定了一定的基础,比如分组域的引入,对空中兼容性的改造,使手机不再只有语音、短信等单一的业务,能够更有效率的连入互联网,但传输速率较低,网络不稳定,维护成本较高。
以上都是比较专业的解释,直观点说,2g网络用来看文字信息无压力,看图片就需要加载好长时间了,打开网页也非常慢,3G用来看图片看视频也可以,2G和3G都主要依靠基站控制连接无线资源管理器再连接核心网。4G对于2G和3G来说就是一个大的进步了,改成基站直连核心网,整个网络更加扁平化,降低时延,看视频都非常快不卡顿。而现在5G时代也在向我们走来,这可能会让我们的生活娱乐更便捷。
 
3G:
第三代无线蜂窝电话通讯协议
3g是第三代移动通信技术,是指支持高速数据传输的蜂窝移动通讯技术。3G服务能够同时传送声音及数据信息,速率一般在几百kps以上。相对于2G,3G扩展了频谱,增加了频谱利用率,提升了速率,更加利于Internet业务。
 
4G:
第四代无线蜂窝电话通讯协议
    1、2G是以无线通讯数字化为代表,能够进行窄带数据通讯。常见2G无线通讯协议有GSM频分多址(GPRS和EDGE)和CDMA 1X码分多址两种,传输速度很慢。
    2、3G,主要是在2G的基础上发展了高带宽的数据通信和提高了语音通话安全性。3G一般的数据通信带宽都在500Kb/s以上。常见的3G协议有WCDMA、CDMA2000和TD-SCDMA,传速速度相对较快,可以很好的满足手机上网等需求,不过播放高清视频较为吃力。
    3、4g,集3G与WLAN(无线局域网)于一体并能够传输高质量视频图像以及图像传输质量与高清晰度电视不相上下的技术产品。4G系统能够以100Mbps的速度下载,比拨号上网快2000倍,上传的速度也能达到20Mbps,并能够满足几乎所有用户对于无线服务的要求。对于用户而言,2G、3G、4G网络最大的区别在于传速速度不同,4G网络作为最新一代通讯技术,在传输速度上有着非常大的提升,理论上网速度是3G的50倍,实际体验也都在10倍左右,上网速度可以媲美20M家庭宽带,因此4G网络可以具备非常流畅的速度,观看高清电影、大数据传输速度都非常快(现在不是还有些说法吗,说啥4G出来之后3G运营商就会暗地里降速什么的,以前3G看个视频问题也不大,现在看个图片都要加载好久,当然我也没测过速,这些事也不好去说),只是资费是一大问题(当然现在不算是了,像什么腾讯王卡啥的都很便宜)
 
5G:
第五代无线蜂窝电话通讯协议
    5g网络将有更大的容量及更快的数据处理速度,通过手机、可穿戴设备及其它联网硬件推出更多的新服务。5G的容量预计是4G的1000倍,可以实现在手机上真正的实时在线玩游戏,这是有别于4G的。5G将会更多的为物联网做优化(这点对于我们公司来说其实很重要的,比如麦度那边就很多物联网设备,像我们这边法国业务组也有很多物联网设备)。

 

4.相关关键字

LTE: Long Term Evolution,长期演进

3GPP: The 3rd Generation Partnership Project,第三代合作伙伴计划 UMTS: Universal Mobile Telecommunications System,通用移动通信系统

USIM: Universal Subscriber Identity Module,通用用户身份识别模块。主要用在GSM、WCDMA与TD-SCDMA网络中;

UICC: Universal Integrated Circuit Card,通用集成电路卡。

SIM :  Subscriber Identity Module,用户身份识别模块。主要用在GSM、WCDMA与TD-SCDMA网络中。

DSDS:Dual SIM Dual Standby,双卡双待,指的是两张SIM卡可以同时待机等待接入电话,但是如果其中一个SIM卡已经建立通话连接,另一张SIM卡就不能使用;

DSDA:Dual SIM Dual Active,双卡双用,指的是设备可以同时连接至两个网络,且可以无缝在两个通话间进行切换,就是说如果你正在进行一个SIM卡的通话,你仍然可以接收到来自另一个SIM卡的电话

IMSI:international mobiles subscriber identity国际移动用户号码标识, 这个一般大家是不知道,GSM必须写在卡内相关文件中;

MSISDN:mobile subscriber ISDN用户号码,这个是我们说的139,136那个号码;

ICCID:ICC identity集成电路卡标识,这个是唯一标识一张卡片物理号码的; IMEI:international mobile Equipment identity手机唯一标识码;

 

二.信号优化

1.何为信号优化    

       各家手机厂商对于手机信号强弱与信号格数的换算关系并没有一个统一的标准,举个例子说,诺基亚的4格信号未必比iPhone的5格信号差。    

        所谓的信号优化,并不是真正的提高手机信号方面相关性能,而是在相同信号强度下使软件上层所表现出的、用户可以看到的信号图标的信号格数更多,从而在同等真实信号强度下给用户一种当前信号较好的感觉,改善用户体验。    

        手机实时真实的信号强度可以在:设置 —> 关于手机 —>状态信息 —>SIM卡状态 —> 信号强度(modem端未修改的情况下) 

        原因:相同的dbm和asu,华为等手机的信号显示效果比我们的好

 

2.原理和代码实现

2G优化原理:

a. modem底层上报信号参数RSSI给modem L4( L4:最初由Jochen Liedtke设计的微内核构架的操作系统内核,现在已经形成一个微内核家族。)

b.在modem L4中,用RSSI经过计算,得到上报给上层的asu值,asu的范围是0-31,计算公式为:     asu = (113 + RSSI) / 2 c.在AP端将asu值转化为信号格数。 modem端因为没有进行一系列的判断,直接是由公式计算出来后直接传到AP端,所以一般就不在modem端优化了,可以直接在AP端进行优化

注:RSSI(Received Signal Strength Indicator)是接收信号的强度指示,它的实现是在反向通道基带接收滤波器之后进行的。

 

2G代码实现:

2g信号优化方法(以下适用于L/M/N项目):

代码位置:alps/vendor/mediatek/proprietary/frameworks/base/packages/FwkPlugin/src/com/mediatek/op/telephony/DefaultServiceStateExt.java

public int mapGsmSignalLevel(int asu, int gsmRscpQdbm) {
        int level;
            // 2G network
            if (asu <= 2 || asu == 99) {
                level = SignalStrength.SIGNAL_STRENGTH_NONE_OR_UNKNOWN;
            } else if (asu >= 12) {
                level = SignalStrength.SIGNAL_STRENGTH_GREAT;
            } else if (asu >= 8) {
                level = SignalStrength.SIGNAL_STRENGTH_GOOD;
            } else if (asu >= 5) {
                level = SignalStrength.SIGNAL_STRENGTH_MODERATE;
            } else {
                level = SignalStrength.SIGNAL_STRENGTH_POOR;
            }
        }
        return level;
    }

2G代码实现:

2g信号优化方法(以下适用于O项目及以后):

代码位置:alps/frameworks/base/telephony/java/android/telephony/SignalStrength.java

    public int getGsmLevel() {
        int level;

        // ASU ranges from 0 to 31 - TS 27.007 Sec 8.5
        // asu = 0 (-113dB or less) is very weak
        // signal, its better to show 0 bars to the user in such cases.
        // asu = 99 is a special case, where the signal strength is unknown.
        int asu = getGsmSignalStrength();
        if (asu <= 2 || asu == 99) level = SIGNAL_STRENGTH_NONE_OR_UNKNOWN;
        else if (asu >= 12) level = SIGNAL_STRENGTH_GREAT;
        else if (asu >= 8)  level = SIGNAL_STRENGTH_GOOD;
        else if (asu >= 5)  level = SIGNAL_STRENGTH_MODERATE;
        else level = SIGNAL_STRENGTH_POOR;
        if (DBG) log("getGsmLevel=" + level);
        return level;
    }

 

3g优化原理:

上层信号格数的显示是与asu值的大小相匹配的,3G的运行情况是这样的:   

 a. modem底层上报信号参数RSCP与Ec/No两个参数给modem L4

b.在modem L4中,经过计算得到上报给上层的signal_level,也即asu,asu的范围是0-31,计算公式为:         

      signal_level = (Ec/N0 + 25) + (RSCP + 120) / 8     

c.在AP端将asu值转化为信号格数

 

3G代码实现: 适用于L/M/N:

步骤一、moden端优化(必须)

代码位置:custom/modem/common/ps/custom_l4_utility.c

修改前:
       #define CUSTOM_3G_SIGNAL_LEVEL_MINUS_1_THRESHOLD (-72)
       #define CUSTOM_3G_SIGNAL_LEVEL_MINUS_2_THRESHOLD  (-88)
       #define CUSTOM_3G_SIGNAL_LEVEL_MINUS_3_THRESHOLD  (-104)

修改后:
#if 宏控 
       #define CUSTOM_3G_SIGNAL_LEVEL_MINUS_1_THRESHOLD (-85)
       #define CUSTOM_3G_SIGNAL_LEVEL_MINUS_2_THRESHOLD  (-98)
       #define CUSTOM_3G_SIGNAL_LEVEL_MINUS_3_THRESHOLD  (-105)
#else 
       #define CUSTOM_3G_SIGNAL_LEVEL_MINUS_1_THRESHOLD (-72)
       #define CUSTOM_3G_SIGNAL_LEVEL_MINUS_2_THRESHOLD  (-88)
       #define CUSTOM_3G_SIGNAL_LEVEL_MINUS_3_THRESHOLD  (-104)
#endif

步骤二、AP端优化(若步骤一中modem端优化后无效果)

代码位置:alps/vendor/mediatek/proprietary/hardware/ril/mtk-ril/ril_nw.c

修改前:
       #define CUSTOM_3G_SIGNAL_LEVEL_MINUS_1_THRESHOLD (-72)
       #define CUSTOM_3G_SIGNAL_LEVEL_MINUS_2_THRESHOLD  (-88)
       #define CUSTOM_3G_SIGNAL_LEVEL_MINUS_3_THRESHOLD  (-104)

修改后:
#if 宏控
       #define CUSTOM_3G_SIGNAL_LEVEL_MINUS_1_THRESHOLD (-85)
       #define CUSTOM_3G_SIGNAL_LEVEL_MINUS_2_THRESHOLD  (-98)
       #define CUSTOM_3G_SIGNAL_LEVEL_MINUS_3_THRESHOLD  (-105)

#else 
       #define CUSTOM_3G_SIGNAL_LEVEL_MINUS_1_THRESHOLD (-72)
       #define CUSTOM_3G_SIGNAL_LEVEL_MINUS_2_THRESHOLD  (-88)
       #define CUSTOM_3G_SIGNAL_LEVEL_MINUS_3_THRESHOLD  (-104)
 
#endif

项目O及以后:

步骤二、AP端优化(若步骤一中modem端优化后无效果) 

还是在:alps/frameworks/base/telephony/java/android/telephony/SignalStrength.java
    public int getTdScdmaLevel() {
        final int tdScdmaDbm = getTdScdmaDbm();
        int level;

        if ((tdScdmaDbm > -25) || (tdScdmaDbm == SignalStrength.INVALID))
                level = SIGNAL_STRENGTH_NONE_OR_UNKNOWN;
        else if (tdScdmaDbm >= -49) level = SIGNAL_STRENGTH_GREAT;
        else if (tdScdmaDbm >= -73) level = SIGNAL_STRENGTH_GOOD;
        else if (tdScdmaDbm >= -97) level = SIGNAL_STRENGTH_MODERATE;
        else if (tdScdmaDbm >= -110) level = SIGNAL_STRENGTH_POOR;
        else level = SIGNAL_STRENGTH_NONE_OR_UNKNOWN;

        if (DBG) log("getTdScdmaLevel = " + level);
        return level;
     }

    还有
        if (tdScdmaDbm == INVALID) tdScdmaAsuLevel = 255;
        else tdScdmaAsuLevel = tdScdmaDbm + 120;//这个位置也要修改
        if (DBG) log("TD-SCDMA Asu level: " + tdScdmaAsuLevel);
        return tdScdmaAsuLevel;

4g优化代码

LNM项目,代码位置: 

alps/vendor/mediatek/proprietary/frameworks/base/packages/FwkPlugin/src/com/mediatek/op/telephony/DefaultServiceStateExt.java

public int mapLteSignalLevel(int mLteRsrp, int mLteRssnr, int mLteSignalStrength) {
        if (mLteRsrp > -44) {
            rsrpIconLevel = -1;
        } else if (mLteRsrp >= -97) {
            rsrpIconLevel = SignalStrength.SIGNAL_STRENGTH_GREAT;
        } else if (mLteRsrp >= -110) {
            rsrpIconLevel = SignalStrength.SIGNAL_STRENGTH_GOOD;
        } else if (mLteRsrp >= -115) {
            rsrpIconLevel = SignalStrength.SIGNAL_STRENGTH_MODERATE;
        } else if (mLteRsrp >= -122) {
            rsrpIconLevel = SignalStrength.SIGNAL_STRENGTH_POOR;
        } else if (mLteRsrp >= -140) {
            rsrpIconLevel = SignalStrength.SIGNAL_STRENGTH_NONE_OR_UNKNOWN;
        }

4g优化代码 O项目及以后,代码位置: 

alps/vendor/mediatek/proprietary/frameworks/opt/telephony-base/java/mediatek/telephony/SignalStrengthExt.java

    public int mapLteSignalLevel(int mLteRsrp, int mLteRssnr, int mLteSignalStrength) {
        int rssiIconLevel = SignalStrength.SIGNAL_STRENGTH_NONE_OR_UNKNOWN;
        int rsrpIconLevel = -1;
        int snrIconLevel = -1;

        if (mLteRsrp > -44) {
            rsrpIconLevel = -1;
        } else if (mLteRsrp >= -85) {
            rsrpIconLevel = SignalStrength.SIGNAL_STRENGTH_GREAT;
        } else if (mLteRsrp >= -95) {
            rsrpIconLevel = SignalStrength.SIGNAL_STRENGTH_GOOD;
        } else if (mLteRsrp >= -105) {
            rsrpIconLevel = SignalStrength.SIGNAL_STRENGTH_MODERATE;
        } else if (mLteRsrp >= -115) {
            rsrpIconLevel = SignalStrength.SIGNAL_STRENGTH_POOR;
        } else if (mLteRsrp >= -140) {
            rsrpIconLevel = SignalStrength.SIGNAL_STRENGTH_NONE_OR_UNKNOWN;
        }
        }

原理:直接在最上层显示信号图片的地方进行数据判定的修改,使信号显示效果更佳

 

三.信号图标

        前面讲过1,2,3,4,5G的概念,而在我们手机的信号栏会出现“ E ”、“ 4G ”,还有1X 、H 、H+ 、T 等字符,那这些字符有什么意义呢?      

比“ E ”更慢的是“ G ”:信号 G比信号 E 更早出现,即GPRS ,是第二代移动通信技术,介于2G和3G之间,也被称为2.5G ,传输速率只有114Kbps(下载速速约是15K/S )。      

E:是2G制式EDGE的缩写,属2.75G网络,一般下载速度20-30K/S 。      

1X:只会在电信手机中出现,属于电信2G网络。一般在通话过程中会使用到1X网络,如果是数据上网,会用3G 。当然,如果你所在的区域范围内信号不好,那手机也只能自动切换到1X网络了。

3G:即3G网络。        

T:即TD-SCDMA ,属3G网络,这一般是在中国移动用户手机上才会显示。这个标志着T的3G信号是比2G快一点,不过相对于电信和联通的另两个3G标准,移动的TD-SCDMA起步比较晚,在当时来说,网络技术不够成熟,虽比2G要快,但并没有快很多,而且不够稳定,所以整体体验也不够好。        

H:即HSDPA ,3.5G网络,主要为联通所用,它的下行速度很快,可达14.4Mb ,相对当时的3G还是快了不少。        

H+ :即HSPA+ ,是HSDPA的升级版,属3.75G网络,它的下行速率可以达到42Mb,速率提升了不少。但随着 3G的用户不断增多,实际几乎不可能达到如此高的速度,在测试中联通3G的下行速度达到10Mbps已经是非常令人满意的状态,大多情况下只有2至4Mbps 的速度。        

4G:即 4G网络,三大运营商使用的均是LTE制式,所以对应的手机信号标识也都是 4G或者LTE 。        

4G+:简单来说就是对4G的优化。相比4G网络100多兆的数据传输速度,4G+的速度是普通4G的2倍。

 

接下里就是信号图标的具体代码分析:

1.信号布局

alps/vendor/mediatek/proprietary/packages/apps/SystemUI/res/layout/signal_cluster_view.xml中有一个mobile_signal_group就是信号区域了:

    
    

它也对应一个布局 mobile_signal_group.xml,mobile_signal_group.xml中主要是信号图标、数据流量箭头等位置显示。

2.信号显示流程

从android 8.0开始,与之前的android版本信号显示不太一样了。8.0之后中信号图标都是代码画出来的矢量图,并非与之前版本一样,直接使用图片显示了。所以,在开发中,需要自己去修改,定制自己的信号样式,显示规格。

首先找到   alps/vendor/mediatek/proprietary/packages/apps/SystemUI/src/com/android/systemui/statusbar/SignalClusterView.java,它对应布局signal_cluster_view.xml,刚刚上面介绍过。在SignalClusterView.java完成控件的初始化、赋予图片显示。     

在SignalClusterView.java中有个内部类:PhoneState。   

 PhoneState中的apply()方法中对信号控件进行赋值。     

其中mMobile就是信号控件:

        public boolean apply(boolean isSecondaryIcon) {
            if (mMobileVisible && !mIsAirplaneMode) {
                if (mLastMobileStrengthId != mMobileStrengthId) {
                    mMobile.getDrawable().setLevel(mMobileStrengthId);
                    mMobileDark.getDrawable().setLevel(mMobileStrengthId);
                    mLastMobileStrengthId = mMobileStrengthId;
                }

接下来是mMobileStrengthId的值,在MobileSignalController.java中的方法notifyListeners()中调用:

callback.setMobileDataIndicators(
	statusIcon, qsIcon, typeIcon, networkIcon,volteIcon,qsTypeIcon,activityIn, 
    activityOut, dataContentDescription, description,
	icons.mIsWide, mSubscriptionInfo.getSubscriptionId(), mCurrentState.roaming);

即上面提到的SignalClusterView.java中setMobileDataIndicators()方法传过来的:

    @Override
    public void setMobileDataIndicators(IconState statusIcon, IconState qsIcon, int 
             statusType,int networkType, int volteIcon, int qsType, boolean activityIn, 
             boolean activityOut,String typeContentDescription, String description, 			boolean isWide, int subId,boolean roaming) {
        PhoneState state = getState(subId);
        if (state == null) {
            return;
        }
        state.mMobileVisible = statusIcon.visible && !mBlockMobile;
        state.mMobileStrengthId = statusIcon.icon; //就这儿了
        state.mMobileTypeId = statusType;
        state.mMobileDescription = statusIcon.contentDescription;
        state.mMobileTypeDescription = typeContentDescription;
        state.mIsMobileTypeIconWide = statusType != 0 && isWide;
        /// M: for big network icon and volte icon.
        state.mNetworkIcon = networkType;
        state.mVolteIcon = volteIcon;
        state.mRoaming = roaming;
        state.mActivityIn = activityIn && mActivityEnabled;
        state.mActivityOut = activityOut && mActivityEnabled;

        /// M: Add for plugin features. @ {
        state.mDataActivityIn = activityIn;
        state.mDataActivityOut = activityOut;
        /// @ }

        //Redmine117183 tangchangqiang modify the network icon 2018-01-06 bein
        setDataActivityMTK(activityIn, activityOut, subId);
        //Redmine117183 tangchangqiang modify the network icon 2018-01-06 end

        apply();
    }

statusIcon.icon怎么获取的呢?

	    int iconId = getCurrentIconId();
        iconId = mStatusBarExt.getCustomizeSignalStrengthIcon(
                    mSubscriptionInfo.getSubscriptionId(),
                    iconId,
                    mSignalStrength,
                    mDataNetType,
                    mServiceState);
        /// @ }

        // Show icon in QS when we are connected or data is disabled.
        boolean showDataIcon = mCurrentState.dataConnected || dataDisabled;
        IconState statusIcon = new IconState(mCurrentState.enabled 			 		                    
                && !mCurrentState.airplaneMode,iconId, contentDescription);

其中getCurrentIconId()方法:

  public int getCurrentIconId() {
      if (mCurrentState.connected) {
          return getIcons().mSbIcons[mCurrentState.inetCondition][mCurrentState.level];
        } else if (mCurrentState.enabled) {
            return getIcons().mSbDiscState;
        } else {
            return getIcons().mSbNullState;
        }
    }

而8.0之前和之后的图标区别就在这儿,在8.0之后代码:

    @Override
    public int getCurrentIconId() {
        if (mCurrentState.iconGroup == TelephonyIcons.CARRIER_NETWORK_CHANGE) {
            return SignalDrawable.getCarrierChangeState(getNumLevels());
        } else if (mCurrentState.connected) {
            int level = mCurrentState.level;
            if (mConfig.inflateSignalStrengths) {
                level++;
            }
            return SignalDrawable.getState(level, getNumLevels(),
                    mCurrentState.inetCondition == 0);
        } else if (mCurrentState.enabled) {
            return SignalDrawable.getEmptyState(getNumLevels());
        } else {
            return 0;
        }
    }

MobileSignalController.java继承了SignalController.java,一旦连接了getCurrentIconId()返回的就是:

	   if (mCurrentState.connected) {
          return getIcons().mSbIcons[mCurrentState.inetCondition][mCurrentState.level];
        } 
getIcons方法:
    protected I getIcons() {
        return (I) mCurrentState.iconGroup;
    }

在子类MobileSignalController.java中:

        mLastState.iconGroup = mCurrentState.iconGroup = mDefaultIcons;

而mDefaultIcons的值在mapIconSets()中:
        if (!mConfig.showAtLeast3G) {
            mNetworkToIconLookup.put(TelephonyManager.NETWORK_TYPE_UNKNOWN,
                    TelephonyIcons.UNKNOWN);
            mNetworkToIconLookup.put(TelephonyManager.NETWORK_TYPE_EDGE, 							  TelephonyIcons.E);
            mNetworkToIconLookup.put(TelephonyManager.NETWORK_TYPE_CDMA, 							  TelephonyIcons.ONE_X);
            mNetworkToIconLookup.put(TelephonyManager.NETWORK_TYPE_1xRTT, 							  TelephonyIcons.ONE_X);

            mDefaultIcons = TelephonyIcons.G;
        } else {
            mNetworkToIconLookup.put(TelephonyManager.NETWORK_TYPE_UNKNOWN,
                    TelephonyIcons.THREE_G);
            mNetworkToIconLookup.put(TelephonyManager.NETWORK_TYPE_EDGE,
                    TelephonyIcons.THREE_G);
            mNetworkToIconLookup.put(TelephonyManager.NETWORK_TYPE_CDMA,
                    TelephonyIcons.THREE_G);
            mNetworkToIconLookup.put(TelephonyManager.NETWORK_TYPE_1xRTT,
                    TelephonyIcons.THREE_G);
            mDefaultIcons = TelephonyIcons.THREE_G;
        }

这边就是给不同通信协议下赋予图标的位置,如果有需求比如H+和3G+做替换只要修改TelephonyIcons.java下对应的图标数组就行了。

你可能感兴趣的:(framework)