Android 4.4 原始的状态栏信号和数据业务图标比较丑,当打开数据业务时,数据业务图标,重叠显示在信号图标一起,为一个灰黑色的上下箭头,并且只有在3G和4G信号时,才会显示为3G4G的图标,2G时不会显示2G两个字。最近应客户需求,将状态栏信号和数据业务图标改成下如下样式:
这图片上的4G,3G,2G和下面的信号条,不是同一张图片,是两张图片组合起来的,上部份为3G图片,下部份为信号条。至于在哪里设置这个4G、3G、2G的图片呢,它是在frameworks\base\packages\SystemUI\src\com\android\systemui\statusbar\policy\TelephonyIcons.java这个文件中, 通过下面的函数来判断当前要设置哪个图片:
static void updateDataType(int sub, int type, boolean showAtLeast3G,
boolean show4GforLte, boolean hspaDistinguishable,
int inetCondition)
这函数中的type,即当前卡找到的网络信号,通过这些信号值,来取对应的图片ID,这些图片的ID,是通过
String resName = mDataTypeArray[sub];
int resId = mRes.getIdentifier(resName, null, NS);
String[] dataTypeArray = mRes.getStringArray(resId);
这几条语句,来从资源文件里取出来后保存在dataTypeArray这个数组中,这些资源是在frameworks\base\packages\SystemUI\res\values\Arrays.xml里,定义在下面的数组中:
然后telephony_data_type_sim1这个数组,又被包含定义在multi_data_type这个数组中:
String resName = mDataTypeArray[sub];
int resId = mRes.getIdentifier(resName, null, NS);
String[] dataTypeArray = mRes.getStringArray(resId);
这三条语句,将我们前面定义的telephony_data_type_sim1这个数组的值都取出来了,再接着,就可以通过type这个网络类型值,来在telephony_data_type_sim1这个数组中取对应的图片了,比如:
case TelephonyManager.NETWORK_TYPE_EDGE:
if (!showAtLeast3G) {
mSelectedDataTypeIcon[sub] = mRes.getIdentifier(
dataTypeArray[type], null, NS);
TelephonyManager.NETWORK_TYPE_EDGE的值为2,对应的在telephony_data_type_sim1中的位置的图片为:stat_sys_data_fully_connected_2g。 这样,我们便知道,可以通过telephony_data_type_sim1这个数组,来改变信号图标上面的2g3g4g所对应的图标了。这些图2g3g4g图标,在android4.4默认的情况里,如果当前卡的数据业务没开,或者上网选的数据业务通道卡不是当前卡,那么都不会显示2g3g4g图标(比如上网时选择的数据业务卡为卡1,那么卡2的2g3g4g图标将不会显示),为了让2g3g4g图标始终都在显示,需要在MSimNetworkController.java里的private final void updateDataNetType(int subscription)里,屏掉下面的代码:
if (subscription != dataSub) {
mMSimDataTypeIconId[subscription] = 0;
}
还有要将protected void refreshViews(int subscription)必备数里,下面这段代码屏掉:
if (!mMSimDataConnected[subscription]) {
mMSimDataTypeIconId[subscription] = 0;
if (isCdma(subscription)) {
if (isCdmaEri(subscription)) {
mMSimDataTypeIconId[subscription] =
R.drawable.stat_sys_data_fully_connected_roam;
}
} else if (mPhone.isNetworkRoaming(subscription)) {
mMSimDataTypeIconId[subscription] = R.drawable.stat_sys_data_fully_connected_roam;
}
}
设完图片后,可能有同学会好奇,这卡对应的网络类型,又是怎么获取的呢?我们可以通过下面的方法,来获取当前卡所在的网络类型:
int sub = mApp.getVoiceSubscriptionInService();
Phone phone = mApp.getPhone(sub);
ServiceState ss = phone.getServiceState();
int voiceNetworkType = ss.getVoiceNetworkType();
int dataNetworkType = ss.getDataNetworkType();
int chosenNetworkType = ((dataNetworkType == TelephonyManager.NETWORK_TYPE_UNKNOWN)
? voiceNetworkType : dataNetworkType);
这个mApp是一个PhoneGlobals类型的变量,chosenNetworkType这便是我们所获取的当前网络的类型
下面我们再讲一下,怎么让打开数据业务时,数据业务图标,不是那个默认的灰色的难看的上下箭头,而是对应的2g3g4g图片。
首先一个,如果想在打开数据业务时,不是那个默认的灰色的难看的上下箭头,而是类似我最上面那的那张图片上的上下箭头加2G/3G/4G字的图片,则需要先在frameworks\base\packages\SystemUI\res\values\Config.xml里修改status_bar_style的值为3,3表示数据业务的图标,会显示在信号图标的左侧,如我上图所未,如果是选0的话,则只有信号图标和默认的灰色的难看的上下箭头。
然后,在MSimSignalClusterView.java里的private void applySubscription(int subscription)这个函数中,有下面一段代码:
if (mStyle == STATUS_BAR_STYLE_ANDROID_DEFAULT) {
mMobileType[subscription].setVisibility(
!mWifiVisible ? View.VISIBLE : View.GONE);
} else {
mMobileType[subscription].setVisibility(View.GONE);
}
在这里,我们需要将mMobileType[subscription].setVisibility(View.GONE);改为mMobileType[subscription].setVisibility(View.VISIBLE); 否则将不会显示数据业务图标。 这些数据业务的图标,同样定义在frameworks\base\packages\SystemUI\res\values\Arrays.xml里,比如我们2G网络的图标,定义在telephony_data_activity_g_sim1 、telephony_data_activity_e_sim1、telephony_data_activity_2g_sim1这三个数组中,要换数据业务图标的,可以直接在这里换。 3G的图标定义在telephony_data_activity_3g_sim1、stat_sys_data_idle_3g、telephony_data_activity_lte_sim1这几个数组中,4G的定义在telephony_data_activity_4g_sim1数组中