Android frameworks - SystemUI信号槽修改定制简析

不啰嗦直接分析:

推荐一篇SystemUI的分析文章,帮这位不认识的老铁打个广告 ^_^

https://blog.csdn.net/azhengye/article/details/50419409

1:Android 4.1 MTK平台

2:Android 5.1 (6.1)  QCOM平台

(主要不同点,第一个数组是在代码里,第二个数读取资源文件里面的数组  . apply 里设置信号图片的代码略为不同,5.1以后是在updateMobile() 这个方法去设置 , 二4.1  直接在 apply() 这个函数里设置)

(源码下载链接在最后^_^)

定位源码:/XXX/frameworks/base/packages/SystemUI/

com.android.systemui.statusbar  包下的   SignalClusterView.java

这个类主要用来管理SystemUI的网络信号有关的UI, 记住只是UI。系统的架构很好,处理的地方在另外一个类,这个就是

 com.android.systemui.statusbar.policy  包下的 NetworkController

 这里主要做一些逻辑操作,比如说信号刷新,以及信号的UI如何获取 并传递到 SignalClusterView  这个类本身就是集成一个广播,这里不做深入分析。

    public void setMobileDataIndicators(boolean visible, IconIdWrapper strengthIcon, IconIdWrapper activityIcon,
            int typeIcon, String contentDescription, String typeContentDescription) {
        mMobileVisible = visible;
        mMobileStrengthId = strengthIcon.clone();
        mMobileActivityId = activityIcon.clone();
        mMobileTypeId = typeIcon;
        mMobileDescription = contentDescription;
        mMobileTypeDescription = typeContentDescription;

        Xlog.d(TAG, "setMobileDataIndicators"
                + " mMobileVisible=" + mMobileVisible
                + " mMobileStrengthId=" + mMobileStrengthId.getIconId()
                + " mMobileActivityId=" + mMobileActivityId.getIconId()
                + " mMobileTypeId=" + mMobileTypeId
                + " mWifiGroup" + ((mWifiGroup == null) ? "=null" : "!=null"));

        apply();
    }

 public void setMobileDataIndicators   这个函数就是 回调 NetworkController  的接口, 表示数据更新。

  我们后面回过头来看这个函数,

 最后面执行了apply();

4.1代码:

  

 // Run after each indicator change.
    private void apply() {
     
 // *******省略部分代码******
        if (mMobileVisible && !mIsAirplaneMode) {
            
            /// M: Support Roam Data Icon both show. @{
            if (mRoaming) {
                mMobileRoam.setImageResource(mRoamingId);
                mMobileRoam.setVisibility(View.VISIBLE);
            } else {
                mMobileRoam.setImageResource(0);
                mMobileRoam.setVisibility(View.GONE);
            }
            /// M: Support Roam Data Icon both show. }@
            
            mMobileGroup.setVisibility(View.VISIBLE);
            if (mMobileStrengthId.getResources() != null) {
                mMobile.setImageDrawable(mMobileStrengthId.getDrawable());
            } else {
                if (mMobileStrengthId.getIconId() == 0) {
                    mMobile.setImageDrawable(null);
                } else {
                    mMobile.setImageResource(mMobileStrengthId.getIconId());
                }
            }
            if (mMobileActivityId.getResources() != null) {
                mMobileActivity.setImageDrawable(mMobileActivityId.getDrawable());
            } else {
                if (mMobileActivityId.getIconId() == 0) {
                    mMobileActivity.setImageDrawable(null);
                } else {
                    mMobileActivity.setImageResource(mMobileActivityId.getIconId());
                }
            }
            mMobileType.setImageResource(mMobileTypeId);
            Xlog.d(TAG, "apply() setImageResource(mMobileTypeId) mShowSimIndicator = " + mShowSimIndicator);
            mMobileGroup.setContentDescription(mMobileTypeDescription + " " + mMobileDescription);
            
            /// M: Airplane mode: Shouldn't show data type icon (L1)
            ///    OP01 project: Not in airplane mode, the data type icon should be always displayed (L2)
            ///    WifiVisible: Not in airplane mode, not OP01 project, the data type icon should follow the wifi visible status (L3)
            if (PluginFactory.getStatusBarPlugin(mContext).supportDataTypeAlwaysDisplayWhileOn()) {
                mMobileType.setVisibility(View.VISIBLE);
            } else {
                mMobileType.setVisibility(!mWifiVisible ? View.VISIBLE : View.GONE);
            }
            
            /// M: When the signal strength icon id is null should hide the data type icon, this including several status
            if (mMobileStrengthId.getIconId() == R.drawable.stat_sys_signal_null) {
                mMobileType.setVisibility(View.GONE);
            }
            
            /// M: Support SIM Indicator. @{
            if (mShowSimIndicator) {
                mSignalClusterCombo.setBackgroundResource(mSimIndicatorResource);
            } else {
                mSignalClusterCombo.setPadding(0, 0, 0, 0);
                mSignalClusterCombo.setBackgroundDrawable(null);
            }
            /// M: Support SIM Indicator. }@
        } else {
            mMobileGroup.setVisibility(View.GONE);
        }

      // *******省略部分代码******

    }

5.1  以上:

  

 // Run after each indicator change.
    private void apply(int phoneId) {

        if (mWifiGroup == null) return;

        if (mWifiVisible) {
            mWifiGroup.setVisibility(View.VISIBLE);
            mWifi.setImageResource(mWifiStrengthId);
            mWifiActivity.setImageResource(mWifiActivityId);
            mWifiGroup.setContentDescription(mWifiDescription);
        } else {
            mWifiGroup.setVisibility(View.GONE);
        }

        if (DEBUG) Slog.d(TAG,
                String.format("wifi: %s sig=%d act=%d",
                (mWifiVisible ? "VISIBLE" : "GONE"), mWifiStrengthId, mWifiActivityId));

        if (mMobileVisible && !mIsAirplaneMode) {
            updateMobile(phoneId);
            updateCdma();
            updateData(phoneId);
            updateDataVoice(phoneId);
            mMobileGroup[phoneId].setVisibility(View.VISIBLE);
        } else {
            mMobileGroup[phoneId].setVisibility(View.GONE);
            mMobileCdmaGroup.setVisibility(View.GONE);
            mMobileCdma1xOnly.setVisibility(View.GONE);
            mDataGroup[phoneId].setVisibility(View.GONE);
        }

     // *******省略部分代码******

    }

   到这里只是设置完了UI。我们再回过头来看  图片源到底是怎么设置的?

  这边就要回到

NetworkControllerImpl.java 这边了

 这边只是做个简单分析,这个类会接受一些广播信息,然后通过接口刷新数据给上面那个类。

看下代码:

 

  public void refreshSignalCluster(SignalCluster cluster) {
        cluster.setWifiIndicators(
                // only show wifi in the cluster if connected or if wifi-only
                mWifiEnabled && (mWifiConnected || !mHasMobileDataFeature),
                mWifiIconId,
                mWifiActivityIconId,
                mContentDescriptionWifi);

        if (mIsWimaxEnabled && mWimaxConnected) {
            // wimax is special
            cluster.setMobileDataIndicators(
                    true,
                    mAlwaysShowCdmaRssi ? mPhoneSignalIconId : new IconIdWrapper(mWimaxIconId),
                    mMobileActivityIconId,
                    mDataTypeIconId,
                    mContentDescriptionWimax,
                    mContentDescriptionDataType);
        } else {
            // normal mobile data
            cluster.setMobileDataIndicators(
                    mHasMobileDataFeature,
                    mShowPhoneRSSIForData ? mPhoneSignalIconId : mDataSignalIconId,
                    mMobileActivityIconId,
                    mDataTypeIconId,
                    mContentDescriptionPhoneSignal,
                    mContentDescriptionDataType);
        }
        cluster.setIsAirplaneMode(mAirplaneMode, mAirplaneIconId);
    }

  其中  cluster.setMobileDataIndicators(**)  就是将SIM的信息回调给 SignalClusterView

 第二个参数标识的是信号强度。其余的参数想了解 可以找百度。

 然后通过这个mPhoneSignalIconId  继续查找 会发现到底是谁给他赋值,接下来我们在MTK4.0 已经iQCOM 5.1 6.1 代码分别来看(MTK5.1和这个一样)。

  有一点,对这个  图标 赋值的函数是同一个 那就是 

 private final void updateTelephonySignalStrength()   信号强度  
 private final void updateDataNetType()               信号类型  

 

        

 switch (mDataNetType) {
                case TelephonyManager.NETWORK_TYPE_UNKNOWN:
                    if (!mShowAtLeastThreeGees) {
                        if (!mIsRoaming) {  /// M: Support Roam Data Icon both show.
                            mDataIconList = TelephonyIcons.DATA_G[simColor];
                        } else {
                            mDataIconList = TelephonyIcons.DATA_G_ROAM[simColor];
                        }
                        mDataTypeIconId = 0;
                        mContentDescriptionDataType = mContext.getString(
                                R.string.accessibility_data_connection_gprs);
                        break;
                    } else {
                        // fall through
                    }
                case TelephonyManager.NETWORK_TYPE_EDGE:
                    if (!mShowAtLeastThreeGees) {
                        if (!mIsRoaming) {  /// M: Support Roam Data Icon both show.
                            mDataIconList = TelephonyIcons.DATA_E[simColor];
                        } else {
                            mDataIconList = TelephonyIcons.DATA_E_ROAM[simColor];
                        }
                        mDataTypeIconId = mDataIconList[0];
                        mContentDescriptionDataType = mContext.getString(
                                R.string.accessibility_data_connection_edge);
                        break;
                    } else {
                        // fall through
                    }
                case TelephonyManager.NETWORK_TYPE_UMTS:
                    if (!mIsRoaming) {  /// M: Support Roam Data Icon both show.
                        mDataIconList = TelephonyIcons.DATA_3G[simColor];
                    } else {
                        mDataIconList = TelephonyIcons.DATA_3G_ROAM[simColor];
                    }
                    mDataTypeIconId = mDataIconList[0];
                    mContentDescriptionDataType = mContext.getString(
                            R.string.accessibility_data_connection_3g);
                    break;

   从代码中可以看出,所有图标数组 都是定义在  TelephonyIcons.java  这个类中,  不管是类型还是强度。具体的部分源码我会给个下载地址。

   那么信号强度:

   

  private final void updateTelephonySignalStrength(int phoneId) {
          
           /****省略部分代码***/
            mMSimPhoneSignalIconId[phoneId] =
                    TelephonyIcons.getSignalNullIcon(phoneId);
            mMSimDataSignalIconId[phoneId] =
                    mMSimPhoneSignalIconId[phoneId];
            if (phoneId == dataSub) {
                mQSPhoneSignalIconId = R.drawable.ic_qs_signal_no_signal;
            }
        } else {
            if (mMSimSignalStrength[phoneId] == null || (mMSimServiceState == null)) {
                if (DEBUG) {
                    Slog.d(TAG, " Null object, mMSimSignalStrength= "
                            + mMSimSignalStrength[phoneId]
                            + " mMSimServiceState " + mMSimServiceState[phoneId]);
                }
                mMSimPhoneSignalIconId[phoneId] =
                        TelephonyIcons.getSignalNullIcon(phoneId);
                mMSimDataSignalIconId[phoneId] =mMSimPhoneSignalIconId[phoneId];
                mMSimContentDescriptionPhoneSignal[phoneId] =
                        TelephonyIcons.getSignalStrengthDes(phoneId, 0);

  		/****省略部分代码***/
               
            }
        }
    }

   

mMSimContentDescriptionPhoneSignal[phoneId] =TelephonyIcons.getSignalStrengthDes(phoneId, iconLevel);

   所以在追踪到 TelephonyIcons  会发现有很多

  

static void initAll(Context context) {
        if (isInitiated) {
            log(TAG, "initAll, already initiated!");
            return;
        }

        mRes = context.getResources();
        try {
            mDataTypeArray = mRes.getStringArray(
                    R.array.multi_data_type);
            mDataTypeDescriptionArray = mRes.getStringArray(
                    R.array.telephony_data_type_description);
            mDataTypeGenerationArray = mRes.getStringArray(
                    R.array.telephony_data_type_generation);
            mDataTypeGenerationDescArray = mRes.getStringArray(
                    R.array.telephony_data_type_generation_description);
            mDataActivityArray = mRes.getStringArray(
                    R.array.multi_data_activity);
            mSignalStrengthArray = mRes.getStringArray(
                    R.array.multi_signal_strength);
            mSignalStrengthRoamingArray = mRes.getStringArray(
                    R.array.multi_signal_strength_roaming);
            mSignalNullArray = mRes.getStringArray(
                    R.array.multi_signal_null);
            mNoSimArray = mRes.getStringArray(
                    R.array.multi_no_sim);
            mSignalStrengthDesc = mRes.getStringArray(
                    R.array.signal_strength_description);
        } catch (android.content.res.Resources.NotFoundException e) {
            isInitiated = false;
            log(TAG, "initAll, exception happened: " + e);
            return;
        }

   可以发现 ,读取的是资源文件的array。  那么就可以对应的去查找这个array资源文件 可以在里面替换自己想要的一些信号强度图片。

 贴个部分代码吧:

      


    
        array/signal_strength_cdma_normal_roaming_sim1
        array/signal_strength_cdma_fully_roaming_sim1
    

    
        array/signal_strength_umts_normal_sim1
        array/signal_strength_umts_fully_sim1
    

    
        array/signal_strength_umts_normal_roaming_sim1
        array/signal_strength_umts_fully_roaming_sim1
    

    
        drawable/stat_sys_signal_0_fully
        drawable/stat_sys_signal_1_fully
        drawable/stat_sys_signal_2_fully
        drawable/stat_sys_signal_3_fully
        drawable/stat_sys_signal_4_fully
    

   这样就OK了!

 

  SystemUI源码:

       点击下载

你可能感兴趣的:(android)