工作背景:公司出口国外某国的设备,因为该国对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-tileandroid: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-tileandroid: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选项:

    <PreferenceScreenandroid:key="mobile_network_settings"android:title="@string/network_settings_title"settings:keywords="@string/keywords_more_mobile_networks"android:dependency="toggle_airplane"><intentandroid: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卡的情况,分别选择显示下面两个按钮中的哪一个:

    <ListPreferenceandroid: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" /><ListPreferenceandroid: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.SettingmButtonPreferredNetworkMode.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文件中可以找到设置网络类型的地方(我也不知道是怎么对应的):

   @Overridepublic void setPhoneType(int phoneType) { // Called by CDMAPhone and GSMPhone constructorif (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.5Gpublic 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 快些

 

转载于:https://www.cnblogs.com/cengjingnianshao/p/9325962.html

安卓网络类型设置的实现相关推荐

  1. VMware中将虚拟机的网络类型设置为桥接模式

    本人的虚拟机是在VMware虚拟机软件下安装的Centos7版本. 1.克隆一台虚拟机(名称:cloneVM1) 2.查看物理主机(宿主机)的网络信息 (虚拟机的ip地址需要和物理主机在同一个网络,虚 ...

  2. VMware中将虚拟机的网络类型设置为NAT模式

    本人的虚拟机是在VMware虚拟机软件下安装的Centos7版本. 1.克隆一台虚拟机(名称:cloneVM3) 2.在物理机上查看VMnet8的IP地址为10.0.0.1 3.从VMware虚拟机的 ...

  3. Android系统首选网络类型设置

    Android 首选网络类型式默认值的修改方法 源码部分 //设置 frameworks/base/packages/SettingsProvider/src/com/android/provider ...

  4. Android 7.1 双卡双待机器,首选网络类型设置 详细分析

    首次由preferred_network_mode转换成preferred_network_mode1和preferred_network_mode2是在SubscriptionInfoUpdater ...

  5. ospf的四种网络类型

    原文链接:https://blog.csdn.net/weixin_37945631/article/details/79498334 https://blog.csdn.net/qq_3921960 ...

  6. 如何进行无线网络中继设置

    有一点大家需要注意,中继功能并不是所有产品都具有的.那么,如何进行有效的软硬结合,实现中继功能呢?下面就为大家介绍一下无线网络中继设置的内容. 当然并不是所有的无线设备都能够实现目的无线网络中继设置与 ...

  7. docker容器4:docker网络类型+跨主机访问

    文章目录 一.网络类型介绍 1.查看支持网络类型 2.测试使用种类网络类型 3.网络类型设置 3.1 bridge 3.2 host 3.3 none 3.4创建自定义网络 4.Docker跨主机网络 ...

  8. HCNP——OSPF网络类型

    一.网络类型 OSPF的许多功能或特性是基于接口实现的,当一个接口激活OSPF后,该接口会维护许多OSPF变量,例如其所接入的区域ID.接口Cost值.DR优先级.邻居列表.认证类型等,接口的网络类型 ...

  9. OSPF网络中两端设备网络类型不一致所带来的故障现象

    [前言] 众所周知,两台运行OSPF的路由器如果将一端的网络类型保持广播类型不变,另一端的网络类型设置为P2P,那么两台路由器的邻居关系仍旧会建立(进入Full状态).然而这样的结果在一定程度上会使得 ...

最新文章

  1. 【美国斯坦福大学人工智能研究院:人工智能当以人为本】
  2. Linux内核TCP/IP参数分析与调优
  3. Android10.0 Binder通信原理(八)-Framework层分析
  4. 符号链接和硬链接有什么区别?
  5. python中2个字典比较
  6. 【MySQL】查看MySQL配置文件路径及相关配置
  7. spring mvc综合easyui点击上面菜单栏中的菜单项问题
  8. linux 字幕制作工具,字幕制作工具
  9. Java调用阿里云短信接口发送手机验证码
  10. thinkpad重装系统不引导_联想品牌机重装系统无法引导原因分析以及解决方法(全面分析)...
  11. Timer already cancelled 或者 Task already scheduled or cancelled
  12. TP-link WR703N, OpenWrt, Mentohust
  13. java计算a+aa+aaa+aaaa的和
  14. treegrid 与java交互_EXTJS实现的TREEGRID(后台java,框架SpringMVC)
  15. word文档打不开的常见原因?好的处理方法
  16. 会计科目 分类 说明
  17. OpenGL 透视投影 齐次裁剪空间 深度缓存
  18. 自抗扰控制入门之ESO篇(纯小白入门向和ESO数学表达式的推导)
  19. P110 课时111.多线程更新UI数据
  20. 如何用python实现电商订单接口API

热门文章

  1. 四周第四次课(1月5日) 6.1 压缩打包介绍 6.2 gzip压缩工具 6.3 bzip2压缩工具 6.4 xz压缩工具...
  2. FreeBSD 安装过程
  3. C# 的EF框架怎么连接Oracle数据库
  4. 【 转 】Keepalived工作原理
  5. .NET基础 (05)内存管理和垃圾回收
  6. 系统学习Spring之Spring in action(二)
  7. 苍天啊,请你不要再哭泣
  8. 几何视角看线性方程组解的情况
  9. python常用库之base64
  10. ab url 带参数 测试