快捷开关之移动数据
概览
移动数据开关作为快捷开关的三大金刚之一,重要性不言而喻。作为日常高频使用的开关之一,承载了及其重要的功能。在Flyme6之前,4G还未普及,流量金贵,所以切换菜单中加入了2G,3G,4G的功能,而在Flyme7的过渡中,双卡用户增加,所以将切换菜单中网络模式切换更换为主副卡切换功能。后续跟随用户反馈,可能会将这两个功能同时加入
背景知识
一些需要知道的基础知识
mSubscriptionManager.getActiveSubscriptionInfoCount()
指所有插入的卡,包含当前禁用的SIM卡,当前禁用的卡使用isRadioOn()
来判断mTelephonyManager.getSimCount()
判断是判断当前手机是单卡还是双卡手机,而不是判断当前插入SIM卡的数量mTelephonyManager.getSimState() == SIM_STATE_READY
这个状态获取的是先识别到的那张卡,一般是卡1,所以需要改用mTelephonyManager.getSimState(int slotId)
这个接口分别获取两张卡的状态phoneId,slotId,这两个类似,对应卡槽1,卡槽2,值为0和1
subId,对应SIM卡,从0开始递增,每次插入一张新的SiM卡subid都会+1
卡的名称需要获取卡的subid之后自己去取名称
1
2
3
4
5
6/**
* @return the name displayed to the user that identifies this subscription
*/
public CharSequence getDisplayName() {
return this.mDisplayName;
}软卡就是软件模拟的一个卡,跟真正插卡一样的软卡也会占用一个实体卡槽,启用软卡的卡槽在插卡就没有用了
正文
开关移动数据
点击设置
android自身提供了接口操作移动数据
1 | /** |
响应
也有对应的获取移动数据状态接口,但是比较耗时,所以Flyme使用监听数据库字段的方式来响应移动数据的变化,监听路径区分单双卡手机
- 单卡:Uri mobileDataUri = Settings.Global.getUriFor(Settings.Global.MOBILE_DATA);
- 双卡:Uri mobileDataUri = Settings.Global.getUriFor(Settings.Global.MOBILE_DATA + mDefaultDataSubscriptionId)
双卡手机的监听会涉及到defaultDataSubscriptionId
的合法性,在开机或插拔SIM卡时,如果SIM卡状态没有及时准备好,获取的defaultDataSubscriptionId
可能是非法的,所以需要监听ACTION_SIM_STATE_CHANGED
来多次获取确保注册的数据库路径是正确的
切换卡
切换设置
设置主卡:
SubscriptionManager.setDefaultDataSubId()获取主卡状态:
SubscriptionManager.getDefaultDataSubscriptionId() 可以获取数据卡的subid
切换卡的业务比较复杂,需要管理的细节也比较多,我们来通过UI状态来划分这些细节
UI状态,有两种:一种是整个VIew置灰,不响应用户操作,还有一种隐藏dual图标,不响应用户切换卡,我们接下来从这两个状态细说
View置灰
由当前是否可以开关移动数据和底层的CallBackInfo状态决定
1 | final boolean enabled = mDataController.isMobileDataSupported() |
隐藏Dual图标
是否隐藏由3个情况判断
1 |
|
- 移动数据开启
mDataController.isMobileDataEnabled()
:只有移动数据开启才支持双卡切换 - 硬件(或编译)是否支持双卡
mDataController.canConfigSubId()
:支持双卡手机、非移动入库定制版 - 根据当前状态动态判断是否支持双卡
mDataController.isDualEnabled()
:- 当前插入卡数量(可能为空)
- 当前是否双卡都启用(可在设置中禁用启用)
- 是否正在通话(通话过程禁止切换卡)
- 是否启用软卡(阮卡默认为主卡,且不支持切换)
- 是否正在切换卡
状态获取
以上两个节讲完了切换卡可能的UI状态以及决定状态的判断条件,下面来分析一下这些状态该从哪里获取
所有的这些状态我们主要通过广播来决定刷新的时机
双卡状态刷新时机
- ACTION_SIM_STATE_CHANGED,用于监听SIM的状态变化,相当于硬件设备在开机过程中从准备到完成的状态,无法跟踪主卡的状态
- ACTION_DEFAULT_DATA_SUBSCRIPTION_CHANGED,监听这个广播, 在数据卡(也即主卡)变化时可以获取通知,这个时候就可以更新主卡ID
注:数据库中有个Uri与这个广播是一样的功能:Settings.Global.MULTI_SIM_DATA_CALL_SUBSCRIPTION - ACTION_SERVICE_STATE_CHANGED,监听当前服务状态,是否驻网脱网
- ACTION_SUBINFO_RECORD_UPDATED,可以用于监听双卡启用停用
切换卡状态刷新时机
- ACTION_MAIN_SLOT_CHANGED(高通,samsung) | ACTION_SET_RADIO_CAPABILITY_DONE(mtk),用于监听双卡切换完毕
注:ACTION_SET_RADIO_CAPABILITY_DONE是google字段,所以三个平台都有,MAIN_SLOT可能会有平台缺少的问题
- ACTION_MAIN_SLOT_CHANGED(高通,samsung) | ACTION_SET_RADIO_CAPABILITY_DONE(mtk),用于监听双卡切换完毕
电话状态刷新时机
- ACTION_PHONE_STATE_CHANGED,用于电话状态变化的广播,只有在第一次来电话之后才会触发,注意初始化值
网络制式发生变化时机(目前暂未用到)
- ACTION_RADIO_TECHNOLOGY_CHANGED 与 ACTION_RAT_CHANGED:用于radio的类型变化 When the radio changes (ex: CDMA->GSM), refresh all options.
切换网络模式
当前已经去除,后续可能增加
注意事项
- 解完BUG之后,记得判断处理默认状态,一定要重启去check状态是否异常
1 | //FLYME:wanglong@CommSrv.Telephony.Bugfix#481606 {@ |
这段代码中,MSIM_MODE_SETTINGS中,MTK在Global数据库里,三星和高通在System数据库里,使用的时候注意区分在AndroidL中,MTK也位于System数据库