手记

安卓网络类型设置的实现

工作背景:公司出口国外某国的设备,因为该国对4G认证要求较高,流程非常麻烦,客户不想取得4G方面认证,因此订单机器设备需禁用4G,且不能手动恢复4G,默认3G/2G(auto)模式。

实现思路:在安卓系统的设置功能里面有设置网络类型的功能,根据设置时走的流程,默认设置开机时网络为3G/2G,并删除切换网络类型的选项。

工作步骤:首先,了解设置中网络类型设置的实现。

安卓系统对网络设置操作过程:设置(settings)->更多(more)->移动网络(Mobile networks)->首选网络类型(preferred network type)

1、设置(settings)模块的布局文件为:packages\apps\Settings\res\xml\dashboard_categories.xml,其中下面部分的代码对应的是settings中的more选项:

     <!-- Operator hook -->
        <dashboard-tile
                android:id="@+id/operator_settings"
                android:fragment="com.android.settings.WirelessSettings" >
            <intent android:action="com.android.settings.OPERATOR_APPLICATION_SETTING" />
        </dashboard-tile>

     <!-- Other wireless and network controls -->
        <dashboard-tile
                android:id="@+id/wireless_settings"
                android:title="@string/radio_controls_title"
                android:fragment="com.android.settings.WirelessSettings"
                android:icon="@drawable/ic_settings_more"
                />
    </dashboard-category>

2、点击more以后进入Mobile networks, packages\apps\Settings\src\com\android\settings\WirelessSettings.java文件,
发现加载:addPreferencesFromResource(R.xml.wireless_settings); 

3、通过更多(more)的布局文件packages\apps\Settings\res\xml\wireless_settings.xml文件发现,启动了Phone模块的,MobileNetworkSettings.java文件,其中下面部分的代码对应的是more中的Mobile networks选项:
    <PreferenceScreen
        android:key="mobile_network_settings"
        android:title="@string/network_settings_title"
        settings:keywords="@string/keywords_more_mobile_networks"
        android:dependency="toggle_airplane">
        <intent
            android:action="android.intent.action.MAIN"
            android:targetPackage="com.android.phone"
            android:targetClass="com.android.phone.MobileNetworkSettings" />
    </PreferenceScreen>
 
目录:packages\services\Telephony\src\com\android\phone\MobileNetworkSettings.java
 
4、点击移动网络(Mobile networks)时,通过 MobileNetworkSettings.java发现是里面的控件NetWork Mode控件: addPreferencesFromResource(R.xml.network_setting);  
文件加载的packages\services\Telephony\res\xml\network_setting.xml,它是移动网络的布局文件。其中下面部分的代码对应的是移动网络中的首选网络类型(preferred network type)选项,根据插入的SIM卡的情况,分别选择显示下面两个按钮中的哪一个:
    <ListPreference
        android:key="preferred_network_mode_key"
        android:title="@string/preferred_network_mode_title"
        android:summary="@string/preferred_network_mode_summary"
        android:entries="@array/preferred_network_mode_choices"
        android:entryValues="@array/preferred_network_mode_values"
        android:dialogTitle="@string/preferred_network_mode_dialogtitle" />

    <ListPreference
        android:key="enabled_networks_key"
        android:title="@string/preferred_network_mode_title"
        android:summary="@string/preferred_network_mode_summary"
        android:entries="@array/enabled_networks_choices"
        android:entryValues="@array/enabled_networks_values"
        android:dialogTitle="@string/preferred_network_mode_dialogtitle" />
 

5、通过preferred_network_mode_key回到MobileNetworkSettings.java中找寻BUTTON_PREFERED_NETWORK_MODE.
private static final String BUTTON_PREFERED_NETWORK_MODE = "preferred_network_mode_key";
private static final String BUTTON_ENABLED_NETWORKS_KEY = "enabled_networks_key";

6、找到语句,确定是对象mButtonPreferredNetworkMode:
mButtonPreferredNetworkMode = (ListPreference) prefSet.findPreference(BUTTON_PREFERED_NETWORK_MODE);
mButtonEnabledNetworks = (ListPreference) prefSet.findPreference(BUTTON_ENABLED_NETWORKS_KEY);

7、找到这个listpreference的点击事件:

public boolean onPreferenceChange(Preference preference, Object objValue) {
     if (preference == mButtonPreferredNetworkMode) {
         //NOTE onPreferenceChange seems to be called even if there is no change
         //Check if the button value is changed from the System.Setting
          mButtonPreferredNetworkMode.setValue((String) objValue);

然后执行里面的语句,设置联网模式:
//Set the modem network mode
setPreferredNetworkType(modemNetworkMode);  该函数实现的方法为:
mPhone.setPreferredNetworkType(modemNetworkMode, mHandler.obtainMessage(MyHandler.MESSAGE_SET_PREFERRED_NETWORK_TYPE));

8、跟踪到framework层,找寻Phone.java文件,具体目录所在:frameworks\opt\telephony\src\java\com\android\internal\telephony\Phone.java

发现Phone.java仅仅是一个接口,而被PhoneBase.java文件所实现(PhoneBase extends Handler implements Phone),设置网络类型的函数。

public void setPreferredNetworkType(int networkType, Message response) {
     mCi.setPreferredNetworkType(networkType, response);
}

其实实际上是public CommandsInterface mCi; 接口实现的
protected PhoneBase(PhoneNotifier notifier, Context context, CommandsInterface ci, boolean unitTestMode) {
      this.mNotifier = notifier;
      this.mContext = context;
      mLooper = Looper.myLooper();
      mCi = ci;
}

9、最后网络上说在RIL.java文件中可以找到设置网络类型的地方(我也不知道是怎么对应的):

    @Override
    public void setPhoneType(int phoneType) { // Called by CDMAPhone and GSMPhone constructor
        if (RILJ_LOGD) riljLog("setPhoneType=" + phoneType + " old value=" + mPhoneType);
        mPhoneType = phoneType;
    }
 
    public void setPreferredNetworkType(int networkType , Message response) {
        RILRequest rr = RILRequest.obtain(RILConstants.RIL_REQUEST_SET_PREFERRED_NETWORK_TYPE, response);

        rr.mParcel.writeInt(1);
        rr.mParcel.writeInt(networkType);
        mPreferredNetworkType = networkType;
        if (RILJ_LOGD) riljLog(rr.serialString() + "> " + requestToString(rr.mRequest)
                + " : " + networkType);
        send(rr);
    }
 
扩展CommandsInterface接口主要为了在RIL.java 中实现向modem发送请求的方法 
领导说,此处后面的部分由安卓在modem中实现在modem中实现。该部分不在源码中实现,因此也无法往下分析。
 ***************************************************华丽分割线************************************************

过程搞懂了,如何实现呢?以我们公司的安卓源码为例:
1、 在device\qcom\XXXX\system.prop文件中定义了参数default_network,设置默认网络类型。
# Start in global mode
ro.telephony.default_network=22
 
2、在frameworks\base\packages\SettingsProvider\src\com\android\providers\settings\DatabaseHelper.java中获取默认网络类型

 type = SystemProperties.getInt("persist.radio.default_network", -1);
    if (type == TYPE_NONE) {
           type = SystemProperties.getInt("ro.telephony.default_network", RILConstants.PREFERRED_NETWORK_MODE);
       }
    String val = Integer.toString(type);
    for (int phoneId = 1; phoneId < phoneCount; phoneId++) {
          val = val + "," + type;
    }
 loadSetting(stmt, Settings.Global.PREFERRED_NETWORK_MODE, val);
 
3、Settings.Global.PREFERRED_NETWORK_MODE的定义在文件frameworks\base\packages\SettingsProvider\src\com\android\providers\settings\Settings.java中:
 public static final String PREFERRED_NETWORK_MODE = "preferred_network_mode";
   
 MOVED_TO_GLOBAL.add(Settings.Global.PREFERRED_NETWORK_MODE);
 
4、在frameworks\base\telephony\java\com\android\internal\telephony\RILConstants.java中定义了各种网络类型的值,安卓中默认值为22

int NETWORK_MODE_TD_SCDMA_LTE_CDMA_EVDO_GSM_WCDMA = 22; /* TD-SCDMA/LTE/GSM/WCDMA, CDMA, and EvDo */
 
5、在frameworks\opt\telephony\src\java\com\android\internal\telephony\Phone.java中将上面的值赋值给一个全局变量,在安卓中其他地方调用时就可以直接使用全局变量--Phone.NT_MODE_TD_SCDMA_LTE_CDMA_EVDO_GSM_WCDMA
   int NT_MODE_TD_SCDMA_LTE_CDMA_EVDO_GSM_WCDMA = RILConstants.NETWORK_MODE_TD_SCDMA_LTE_CDMA_EVDO_GSM_WCDMA; 
   
6、安卓开机时会调用frameworks\base\packages\SystemUI\src\com\android\systemui\statusbar\phone\MobilePhone.java中的getDispNet(Context context)函数获取网络类型,该函数调用getNetworkTypeName(Context context)函数,进一步调用getTelNetType(Context context)函数,最终调用telephonyManager.getNetworkType()函数。
 
7、getNetworkType()函数实现方法所在目录frameworks\base\telephony\java\android\telephony\TelephonyManager.java,该方法最终调用的是telephony.getDataNetworkTypeForSubscriber(subId)。注:TelephonyManager中含有获取SIM卡等信息的方法,使用如下:

//获取系统的TelephonyManager 
TelephonyManager telephonyManager = (TelephonyManager)context.getSystemService(Context.TELEPHONY_SERVICE);
//获取设备编号 
mId = mTelephonyManager.getDeviceId(); 
//获取系统平台版本 
mVersion=mTelephonyManager.getDeviceSoftwareVersion(); 
//获取网络运营商代号 
mOperator=mTelephonyManager.getNetworkOperator(); 
//获取网络运营商名称 
mName=mTelephonyManager.getNetworkOperatorName(); 
//获取手机网络类型 
mType = mTelephonyManager.getPhoneType(); 
//获取设备所在位置 
mLocation=mTelephonyManager.getCellLocation(); 
//获取SIM卡的国别 
mIso=mTelephonyManager.getSimCountryIso(); 
//获取SIM卡的序列号 
mNumber=mTelephonyManager.getSimSerialNumber(); 
//获取SIM卡状态 
mState = mTelephonyManager.getSimState();  
 
Android的Api中已经定义了各种网络状态,也在TelephonyManager里面的定义
public static final int NETWORK_TYPE_UNKNOWN
Network is unknown  0  (不知道网络类型)

public static final int NETWORK_TYPE_GPRS
network is GPRS     1  (2.5G)移动和联通
 
public static final int NETWORK_TYPE_EDGE
network is EDGE     2  (2.75G)2.5G到3G的过渡    移动和联通
 
public static final int NETWORK_TYPE_UMTS
network is UMTS     3  (3G)联通

public static final int NETWORK_TYPE_CDMA
network is CDMA: Either IS95A or IS95B  4 (2G 电信)
 
public static final int NETWORK_TYPE_EVDO_0
network is EVDO revision0  5   (3G)电信
 
public static final int NETWORK_TYPE_EVDO_A
network is EVDO revisionA 6 (3.5G) 属于3G过渡
 
public static final int NETWORK_TYPE_1xRTT
network is 1xRTT    7  ( 2G )
 
public static final int NETWORK_TYPE_HSDPA
network is HSDPA    8 (3.5G)
 
public static final int NETWORK_TYPE_HSUPA
network is HSUPA   9 (3.5G)
 
public static final int NETWORK_TYPE_HSPA
network is HSPA    10 (3G)联通

public static final int NETWORK_TYPE_IDEN
network is iDen   11 (2G)
 
public static final int NETWORK_TYPE_EVDO_B
network is EVDO revisionB  12  3G-3.5G
 
public static final int NETWORK_TYPE_LTE
network is LTE     13  (4G)
 
public static final int NETWORK_TYPE_EHRPD
network is eHRPD   14  3G(3G到4G的升级产物)
 
public static final int NETWORK_TYPE_HSPAP
network is HSPA+   15 ( 3G )
 
GPRS      2G(2.5) General Packet Radia Service 114kbps
EDGE      2G(2.75G) Enhanced Data Rate for GSM Evolution 384kbps
UMTS      3G WCDMA 联通3G Universal Mobile Telecommunication System 完整的3G移动通信技术标准
CDMA      2G 电信 Code Division Multiple Access 码分多址
EVDO_0    3G (EVDO 全程 CDMA2000 1xEV-DO) Evolution - Data Only (Data Optimized) 153.6kps - 2.4mbps 属于3G
EVDO_A    3G 1.8mbps - 3.1mbps 属于3G过渡,3.5G
1xRTT     2G CDMA2000 1xRTT (RTT - 无线电传输技术) 144kbps 2G的过渡,
HSDPA     3.5G 高速下行分组接入 3.5G WCDMA High Speed Downlink Packet Access 14.4mbps 
HSUPA     3.5G High Speed Uplink Packet Access 高速上行链路分组接入 1.4 - 5.8 mbps
HSPA      3G (分HSDPA,HSUPA) High Speed Packet Access 
IDEN      2G Integrated Dispatch Enhanced Networks 集成数字增强型网络 (属于2G,来自维基百科)
EVDO_B    3G EV-DO Rev.B 14.7Mbps 下行 3.5G
LTE       4G Long Term Evolution FDD-LTE 和 TDD-LTE , 3G过渡,升级版 LTE Advanced 才是4G 
EHRPD     3G CDMA2000向LTE 4G的中间产物 Evolved High Rate Packet Data HRPD的升级
HSPAP     3G HSPAP 比 HSDPA 快些

原文出处:安卓网络类型设置的实现


0人推荐
随时随地看视频
慕课网APP