P.S.为了方便起见,以后:数据流量信号——小图标,SIM卡信号——大图标。下面简单介绍一下作假流程,以及经常修改的地方和方法。
1.默认值修改
a)路径:framworks/base/core/java/android/os/ProjectManager.java
b)文件不存在时,返回默认值;统一信息切换指令中有变动时,返回用户手动切换的值
c)返回值: 0-关闭(normal) , 3-3G, 4-double 4G,5-single 4G
private static final String GTYPE_FILE_NAME = "GTypeFlag";
public static int readGTypeFlag()
{
byte flag = 0;
File file = new File(INTERNAL_DIR,GTYPE_FILE_NAME);
if(!file.exists()){
if(isAndroid()){
return 0;//默认normal
}else{
return 5;//默认single 4G
}
}
try {
FileInputStream fis = new FileInputStream(file);
flag = (byte)fis.read();
fis.close();
} catch (Exception e) {
Log.e(TAG,"readGTypeFlag e " + e.toString());
return -1;
}
Log.e(TAG," readGTypeFlag flag="+flag);
return (int)flag;
}
/**
2.状态栏大图标显示
a)路径:frameworks/base/packages/SystemUI/src/com/android/systemui/statusbar/SignalClusterView.java
b)刷新状态栏中的大图标
c)当系统不处于飞行模式并且能接受到网络信号时,调用TelephonyIcons类中的getTypeIcon方法,获去所需图标
*/
public boolean apply(boolean isSecondaryIcon) {
Xlog.d(TAG, "apply(" + mSubId + ")," + " mMobileVisible= " + mMobileVisible +
", mIsAirplaneMode= " + mIsAirplaneMode);
...
if (!mIsAirplaneMode && mNetworkType != null) {
//start:add by zyl
Integer simNumber = getSimId(mSubId);
//方法作用:获取做假所需的大图标
int id = TelephonyIcons.getTypeIcon(ProjectManager.readGTypeFlag(),getContext(),simNumber,mNetworkType);
//end:add by zyl
Xlog.d(TAG, "apply(), mNetworkType= " + mNetworkType + " resId= " + id);
mSignalNetworkType.setImageResource(id);
mSignalNetworkType.setVisibility(View.VISIBLE);
} else {
mSignalNetworkType.setImageDrawable(null);
mSignalNetworkType.setVisibility(View.GONE);
}
...
mMobileType.setVisibility(mMobileTypeId != 0 ? View.VISIBLE : View.GONE);
return mMobileVisible;
}
/**
3.状态栏大图标获取及作假修改
a)路径:frameworks/base/packages/SystemUI/src/com/android/systemui/statusbar/policy/TelephonyIcons.java
b)参数说明:GTypeFlag——默认或用户手动切换的信号值;simNumber——SIM卡号(1 or 2);networkType——真实的网络信号值
c)返回值:所需图标
p.s.关于 single 4G 的说明:
针对3G支持双卡的项目,我们的系统是双卡双带单通,即只有可能一张卡开启数据流量,此种作假方案是根据客户机及真机的图标显示而定的一种方案.在设置中的SIM卡管理项可以选择开启哪张卡的数据流量,并且记录此张卡的号(1 or 2),那么状态栏作假时,那张卡开启流量,哪张卡对应的大图标就显示4G(有时客户要求是4G LTE),另外一张卡对应的大图标显示G.(注意不能和小图标混淆,在single 4G下,静态作假的小图标显示4G)
*/
static public int getTypeIcon(int GTypeFlag,Context context,int simNumber,NetworkType networkType){
if( GTypeFlag == 0 ){//normal
return getNetworkTypeIcon(networkType);//注意此处调用了系统的方法,即根据真实信号去获取相应的图标
}else if ( GTypeFlag == 3 ){//double 3G
return R.drawable.status_bar_network_type_3g;
}else if ( GTypeFlag == 4 ){//double 4G
return R.drawable.status_bar_network_type_4g_lte;
}else if ( GTypeFlag == 5 ){ //Signal 4G:一个G一个LTE
if(SIMHelper.getSIMInfoList(context).size() == 2){
int typeofsim_value=Settings.System.getInt(context.getContentResolver(), Settings.System.SETTINGS_SYSTEM_NETWORKTYPEOFSIM,1);
if(typeofsim_value == simNumber){
return R.drawable.status_bar_network_type_4g_lte;
}else{
return R.drawable.status_bar_network_type_g;
}
}
return R.drawable.status_bar_network_type_4g_lte;
}
return R.drawable.status_bar_network_type_g;
}
/**
4.状态栏小图标显示
a)路径:frameworks/base/packages/SystemUI/src/com/android/systemui/statusbar/policy/NetworkControllerImpl.java
b)小图标根据系统获取的真实网络信号实时刷新
c)同理,还是根据默认or用户手动切换的信号值,调用ChooseTypeOfDataBySwitch3Gicon方法,获取需要做假的图标,替换系统原本的真实值
*/
@Override
public void notifyListeners() {
MobileIconGroup icons = getIcons();
...
boolean showDataIcon = mCurrentState.dataConnected
&& (mCurrentState.inetForNetwork != 0 || mShowNormalIcon)
|| mCurrentState.iconGroup == TelephonyIcons.ROAMING;
...
int typeIcon = showDataIcon ? icons.mDataType : 0;
//start:add by zyl
int typeofdata = ProjectManager.readGTypeFlag();
//方法作用:获取做假所需的小图标
typeIcon = ChooseTypeOfDataBySwitch3Gicon(typeofdata,icons,showDataIcon);
//end:add by zyl
...
int signalClustersLength = mSignalClusters.size();
for (int i = 0; i < signalClustersLength; i++) {
mSignalClusters.get(i).setNetworkType(mNetworkType,
mSubscriptionInfo.getSubscriptionId());
mSignalClusters.get(i).setMobileDataIndicators(
mCurrentState.enabled && !mCurrentState.airplaneMode,
getCurrentIconId(),
typeIcon,//赋值
contentDescription,
dataContentDescription,
// Only wide if actually showing something.
icons.mIsWide && typeIcon != 0,
mSubscriptionInfo.getSubscriptionId());
}
}
/**
5.状态栏小图标获取及作假修改
a)路径:frameworks/base/packages/SystemUI/src/com/android/systemui/statusbar/policy/NetworkControllerImpl.java
b)参数说明:typeofdata——默认或用户手动切换的信号值;icons——系统值,保存网络数据类型、状态等的对象;showDataIcon——是否显示
c)返回值:所需小图标
*/
private int ChooseTypeOfDataBySwitch3Gicon(int typeofdata,MobileIconGroup icons,boolean showDataIcon){
int mtypeIcon = showDataIcon ? icons.mDataType : 0;
if((typeofdata == 4) || (typeofdata == 5)){//double 4G or single 4G
mtypeIcon = showDataIcon ? R.drawable.status_bar_data_connected_4g : 0;
}else if(typeofdata == 3){//3g
mtypeIcon = showDataIcon ? R.drawable.status_bar_data_connected_3g : 0;
}else{}//normal(真实)
return mtypeIcon;
}
/**
6.设置中控制打开对应卡的数据流量
a)路径:packages/apps/Settings/src/com/android/settings/DataUsageSummary.java
b)开启SIM卡数据流量时,通过此方法,记录用户开启哪张卡的数据流量(1 or 2)
*/
private void setMobileDataEnabled(int subId, boolean enabled) {
//start:add by zyl
//launch which SIM (1 or 2),记录哪张卡开启了数据流量
Integer simNumber1 = getSimId(subId);
if(enabled == true){
Integer simNumber = getSimId(subId);
Settings.System.putInt(getActivity().getContentResolver(),Settings.System.SETTINGS_SYSTEM_NETWORKTYPEOFSIM, simNumber);
}
//end:add by zyl
if (LOGD) Log.d(TAG, "setMobileDataEnabled()");
mTelephonyManager.setDataEnabled(subId, enabled);
mMobileDataEnabled.put(String.valueOf(subId), enabled);
updatePolicy(false);
}
/**
7.关于设置/更多/网络偏好的几点说明:
a)U1653Q修改记录,搜索张帆的标签,可以看到具体修改的文件,由于文件中的方法太长,我们这里只做简单说明,做此需求的同事可以具体研究一下
b)路径:packages/services/Telephony/src/com/android/phone/MobileNetworkSettings.java
c)当时对于此处的理解不到位,导致165项目开发时,将此处修改成了统一切换指令中的Fake 4G,即两处功能相同,互相关联,一处改变,另一处也同时改变.网络偏好设置的应该是用户的首选项,举例来说,一张3G的SIM卡,流量的数据类型可以是G(包括E) or 3G(包括H),当用户选择了G,那么状态栏的小图标在开启流量时,不管是否同时可以接收到G和3G的网络信号,只能显示G;当用户选择了3G,那么当系统可以接收到3G网络信号时,显示3G,没有的时候,显示G.
d)U165系列的此处修改(Bug)效果,用户表示接受,所以暂时保持这样;后面的Z6U090项目根据客户的需求,重新做了此处功能,后面我们会做简要说明.
*/
/**
*
*二.动态作假(Z6U090Q系列最初的需求,现在也改为了静态):
A)简单说明:小图标随真实信号以及统一切换指令中切换的SIM卡信号类型的改变而改变,例如,down机默认normal(真实),那么插卡后大图标根据真实SIM信号显示G(E) or 3G(H),小图标将根据真实网络数据类型显示E or H;当用户在统一切换指令中手动选择了3G(一说双3G),那么状态栏中SIM卡信号大图标将变为3G,小图标仍将根据真实网络数据类型显示E or H;当用户在统一切换指令中手动选择了4G(single 4G或者 double 4G),那么状态栏中SIM卡信号大图标将变为4G(有的客户要求4G LTE),小图标将根据真实网络数据类型作假显示3G or 4G,即针对我们的3G项目,将2G作假成了3G,3G作假成了4G
B)修改文件:导入时,具体的修改文件,可以在Z6U090Q的修改记录中查找我的标签(张亚伦)查看详细记录
p.s.由于此种作假的大图标和之前完全相同我们就不做介绍了;小图标也是在MobileNetworkSettings.java类中根据用户手动切换的3G/4G信号的值,来动态的将2G作假为3G,3G作假为4G,这里我们只看一下何止前部痛得状态栏针对小图标的作假
*/
/**
1.状态栏小图标获取及作假修改
a)路径:frameworks/base/packages/SystemUI/src/com/android/systemui/statusbar/policy/NetworkControllerImpl.java
b)参数说明:typeofdata——默认或用户手动切换的信号值;icons——系统值,保存网络数据类型、状态等的对象;showDataIcon——是否显示
c)返回值:所需小图标
*/
private int ChooseTypeOfDataBySwitch3Gicon(int typeofdata,MobileIconGroup icons,boolean showDataIcon){
int mtypeIcon = showDataIcon ? icons.mDataType : 0;
//这里根据手动切换的SIM信号以及真实信号,来作假小图标
if(android.os.FeatureOption.CUSTOM_PROJECT_A || android.os.FeatureOption.CUSTOM_PROJECT_D){
if(typeofdata == 3){
if(mtypeIcon == TelephonyIcons.ICON_H || mtypeIcon == TelephonyIcons.ICON_3G){
mtypeIcon = showDataIcon ? TelephonyIcons.ICON_H_PLUS : 0;
}
}else if(typeofdata == 4 || typeofdata == 5){
//这里动态的将真实的3G信号作假为了4G;2G信号作假为了3G
if(mtypeIcon == TelephonyIcons.ICON_H || mtypeIcon == TelephonyIcons.ICON_3G){
mtypeIcon = showDataIcon ? TelephonyIcons.ICON_4G : 0;
}else if(mtypeIcon == TelephonyIcons.ICON_E || mtypeIcon == TelephonyIcons.ICON_G){
mtypeIcon = showDataIcon ? TelephonyIcons.ICON_3G : 0;
}
}else{
}
}
return mtypeIcon;
}