VoLTE 注册流程
1、开关按钮位置:
设置--> 更多--> 移动网络--> 增强型4G LTE模式
2、该设置开关使用了SwitchPreference控件,addEnhanced4GLteSwitchPreference()添加控件:
packages/services/telephony/src/com/android/phone/MobileNetworkSettings.java
private void addEnhanced4GLteSwitchPreference(PreferenceScreen preferenceScreen) {
log("[addEnhanced4GLteSwitchPreference] ImsEnabled :"
+ ImsManager.isVolteEnabledByPlatform(this));
if (mButton4glte != null) { //去掉Google原生开关按钮
log("[addEnhanced4GLteSwitchPreference] Remove mButton4glte!");
preferenceScreen.removePreference(mButton4glte);
}
if (ImsManager.isVolteEnabledByPlatform(this)) { //判断是否支持VoLTE
int order = mButtonEnabledNetworks.getOrder() + 1;
//VoLTE开关初始化
mEnhancedButton4glte = new Enhanced4GLteSwitchPreference(this, mPhone.getSubId());
/// Still use Google's key, title, and summary.
mEnhancedButton4glte.setKey(BUTTON_4G_LTE_KEY); //Key用于SharePreference存储信息
if (ImsManager.isWfcEnabledByPlatform(this)) { //判断是否支持WIFI Call
mEnhancedButton4glte.setTitle(R.string.wfc_volte_switch_title);
} else {
mEnhancedButton4glte.setTitle(R.string.enhanced_4g_lte_mode_title);
}
mEnhancedButton4glte.setSummary(R.string.enhanced_4g_lte_mode_summary);
mEnhancedButton4glte.setOnPreferenceChangeListener(this); //设置监听接口,状态发生变化onPreferenceChange()方法将被调用
mEnhancedButton4glte.setOrder(order);
//preferenceScreen.addPreference(mEnhancedButton4glte);
}
3、该接听方法是onPreferenceChangeMTK(),重新原生onPreferenceChange():
private boolean onPreferenceChangeMTK(Preference preference, Object objValue) {
log("[onPreferenceChangeMTK] preference = " + preference.getTitle());
if (mEnhancedButton4glte == preference) {
log("[onPreferenceChangeMTK] IsChecked = " + mEnhancedButton4glte.isChecked());
Enhanced4GLteSwitchPreference ltePref = (Enhanced4GLteSwitchPreference) preference;
ltePref.setChecked(!ltePref.isChecked()); //设置控件状态,默认关闭是false,打开即是true
ImsManager.setEnhanced4gLteModeSetting(this, ltePref.isChecked()); //设置VoLTE参数
return true;
}
return false;
}
有如下打印信息:

4、设置VoLTE状态setEnhanced4gLteModeSetting
frameworks/opt/net/ims/src/java/com/android/ims/ImsManager.java
public static void setEnhanced4gLteModeSetting(Context context, boolean enabled) {
int value = enabled ? 1 : 0;
//设置Settings.Global.ENHANCED_4G_MODE_ENABLED变量
android.provider.Settings.Global.putInt(
context.getContentResolver(),
android.provider.Settings.Global.ENHANCED_4G_MODE_ENABLED, value);
if (isNonTtyOrTtyOnVolteEnabled(context)) { //不支持TTY或者VoLTE支持TTY
ImsManager imsManager = ImsManager.getInstance(context,
SubscriptionManager.getDefaultVoicePhoneId()); //获取ImsManager对象
if (imsManager != null) {
try {
imsManager.setAdvanced4GMode(enabled); //设置VoLTE
} catch (ImsException ie) {
// do nothing
}
}
}
}
//设置VoLTE
private void setAdvanced4GMode(boolean turnOn) throws ImsException {
checkAndThrowExceptionIfServiceUnavailable();
try {
ImsConfig config = getConfigInterface(); //IMS 配置参数
if (config != null) {
//设置FeatureConstants.FEATURE_TYPE_VOICE_OVER_LTE网络参数
config.setFeatureValue(ImsConfig.FeatureConstants.FEATURE_TYPE_VOICE_OVER_LTE,
TelephonyManager.NETWORK_TYPE_LTE, turnOn ? 1 : 0, null);
}
} catch (ImsException e) {
log("setAdvanced4GMode() : " + e);
}
log("setAdvanced4GMode():" + turnOn);
if (turnOn) {
turnOnIms(); //打开IMS 服务
} else if (isImsTurnOffAllowed()) {
log("setAdvanced4GMode() : imsServiceAllowTurnOff -> turnOffIms");
turnOffIms(); //关闭IMS 服务
}
有如下打印信息:

5、打开IMS 服务
private void turnOnIms() throws ImsException {
checkAndThrowExceptionIfServiceUnavailable();
try {
mImsService.turnOnIms(mPhoneId);
} catch (RemoteException e) {
throw new ImsException("turnOnIms() ", e, ImsReasonInfo.CODE_LOCAL_IMS_SERVICE_DOWN);
}
}
mImsService 是IImsService 的实例对象,该对象在createImsService()中创建:
//绑定IMS Service
private void createImsService(boolean checkService) {
if (checkService) { //判断IMS Service 服务是否已经存在
IBinder binder = ServiceManager.checkService(getImsServiceName(mPhoneId));
if (binder == null) {
/// M: add for debug @{
if (DBG) log("ImsManager: createImsService binder is null");
/// @}
return;
}
}
//获取指向Service的IBinder对象
IBinder b = ServiceManager.getService(getImsServiceName(mPhoneId));
if (b != null) {
try {
b.linkToDeath(mDeathRecipient, 0);
} catch (RemoteException e) {
}
}
mImsService = IImsService.Stub.asInterface(b);
/// M: add for debug @{
if (DBG) log("ImsManager: mImsService = " + mImsService);
/// @}
}
getImsServiceName()获取IMS Service 名:
private static String getImsServiceName(int phoneId) {
// TODO: MSIM implementation needs to decide on service name as a function of phoneId
return IMS_SERVICE; //服务名即"ims"
}
而getImsServiceName()方法在ImsManager类的构造方法中即被调用,所以mImsService对象开机即获取到。
6、调用mImsService的turnOnIms()方法在IImsService.Stub继承类中实现:

vendor/mediatek/proprietary/packages/services/ims/src/com/mediatek/ims/ImsService.java
/**
* Used for turning on IMS when its in OFF state.
*/
@Override
public void turnOnIms(int phoneId) {
Rlog.d(LOG_TAG, "turnOnIms, mActivePhoneId = " + mActivePhoneId +
" phoneId = " + phoneId);
phoneId = getMainCapabilityPhoneId();
Rlog.d(LOG_TAG, "turnOnIms, MainCapabilityPhoneId = " + phoneId);
if (mActivePhoneId != phoneId) {
mActivePhoneId = phoneId;
}
}
/**
* to get main capability phone id.
*
* @return The phone id with highest capability.
*/
private int getMainCapabilityPhoneId() { //此接口可能获取主卡phoneID
//获取服务"phoneEx"
ITelephonyEx telephony = ITelephonyEx.Stub.asInterface(
ServiceManager.getService(mContext.TELEPHONY_SERVICE_EX));
if (telephony != null) {
try {
int mainPhoneId = telephony.getMainCapabilityPhoneId(); //调用getMainCapabilityPhoneId()方法
Rlog.d(LOG_TAG, "getMainCapabilityPhoneId: mainPhoneId = " + mainPhoneId);
return mainPhoneId;
}
..........
}
}
有如下打印信息:

7、获取主PhoneID
PhoneInterfaceManagerEx extends ITelephonyEx.Stub;
packages/services/telephony/src/com/mediatek/phone/PhoneInterfaceManagerEx.java
/**
* Get main capability phone id.
* @return The phone id with highest capability.
*/
public int getMainCapabilityPhoneId() {
return RadioCapabilitySwitchUtil.getMainCapabilityPhoneId();
}
frameworks/opt/telephony/src/java/com/mediatek/internal/telephony/RadioCapabilitySwitchUtil.java
/**
* Get main capability phone ID.
*
* @return Phone ID with main capability
*/
public static int getMainCapabilityPhoneId() {
int phoneId = 0;
if (SystemProperties.getBoolean("ro.mtk_dt_support", false) == true) {
int swapMode = SystemProperties.getInt("persist.ril.simswitch.swapmode", 3);
if (swapMode == SIM_SWITCH_MODE_DUAL_TALK) {
phoneId = 0;
} else if (swapMode == SIM_SWITCH_MODE_DUAL_TALK_SWAP) {
phoneId = 1;
}
} else {
phoneId = SystemProperties.getInt(PhoneConstants.PROPERTY_CAPABILITY_SWITCH, 1) - 1;
}
if (CdmaFeatureOptionUtils.isCdmaLteDcSupport()) {
if (phoneId == PhoneConstants.SIM_ID_1) {
if (SvlteUtils.getSvltePhoneProxy(phoneId).getActivePhone().
getPhoneName()== "CDMA") {
// for svlte project, we need re-mapping slot 0 to DC phone
phoneId = SubscriptionManager.LTE_DC_PHONE_ID_1;
}
}
if (phoneId == PhoneConstants.SIM_ID_2) {
if (SvlteUtils.getSvltePhoneProxy(phoneId).getActivePhone().
getPhoneName()== "CDMA") {
// for svlte project, we need re-mapping slot 1 to DC phone
phoneId = SubscriptionManager.LTE_DC_PHONE_ID_2;
}
}
}
Log.d(LOG_TAG, "[RadioCapSwitchUtil] getMainCapabilityPhoneId " + phoneId);
return phoneId;
VoLTE 注册流程的更多相关文章
- wifi万能钥匙自媒体平台开放注册(付注册流程)
12月13日,有网友爆料,wifi万能钥匙自媒体开放注册,看来自媒体还没有达到饱和阶段,也印证了自媒体时代才刚刚到来.现在这个自媒体的时代,几乎大多互联网企业都开通了自己的自媒体,比较知名的像今日头条 ...
- 源程序版本管理软件和项目管理软件,Github注册流程
目前流行的源程序版本管理软件和项目管理软件:Microsoft TFS,Github,SVN,Coding 各自的优缺点: Microsoft TFS: 优点: tfs核心的,是对敏捷,msf,cmm ...
- GitHub注册流程(中英对比)
GitHub注册流程(中英对比) 注明:为方便完成注册,将以中英文网页截图对应展示. 1. 注册邮箱: 点击GitHub官网进行邮箱注册. 2. 制定个人计划: 页面跳转至 ...
- 迅为4412开发板Linux驱动教程——总线_设备_驱动注册流程详解
本文转自:http://www.topeetboard.com 视频下载地址: 驱动注册:http://pan.baidu.com/s/1i34HcDB 设备注册:http://pan.baidu.c ...
- 从注册流程 分析如何安全退出多个Activity 多种方式(附DEMO)
退出Activity注册Android遍历 目录(?)[+] 前言 知识结构 具体方案 方案1 方法采用FLAG_ACTIVITY_CLEAR_TOP退出整个程序多activity 方案2 方 ...
- python selenium自动化(二)自动化注册流程
需求:使用python selenium来自动测试一个网站注册的流程. 假设这个网站的注册流程分为三步,需要提供比较多的信息: 在这个流程里面,需要用户填入信息.在下拉菜单中选择.选择单选的radio ...
- Android安全问题 抢先接收广播 - 内因篇之广播接收器注册流程
导读:本文说明系统是如何注册动态广播以及静态广播,这里主要注意其注册的顺序 这篇文章主要是针对我前两篇文章 android安全问题 抢先开机启动 - 结果篇 android安全问题 抢先拦截短信 ...
- 基于GBT28181:SIP协议组件开发-----------第三篇SIP注册流程分析实现
原创文章,引用请保证原文完整性,尊重作者劳动,原文地址http://www.cnblogs.com/qq1269122125/p/3941172.html,qq:1269122125. 上两章节简要的 ...
- 基于GBT28181:SIP协议组件开发-----------第四篇SIP注册流程eXosip2实现(一)
原创文章,引用请保证原文完整性,尊重作者劳动,原文地址http://www.cnblogs.com/qq1269122125/p/3945294.html. 上章节讲解了利用自主开发的组件SIP组件l ...
随机推荐
- 在网页中怎样给已发布的Flash添加链接的方法(zhuan)
因为网页中的 Flash 是以控件形式出现的,优先级别较高,所以直接对它加链接是无效的,不过可以用按钮控件 BUTTON 来实现. 具体步骤 1.直接在按钮上加上onClick事件打开指定页面: &l ...
- AES加密算法实现
AES算法是一种对称加密算法,是美国国家标准技术研究所NIST旨在取代DES的21世纪的加密标准. 下文实例中,密钥采用了直接写死的方式,实际使用中可以配合RSA加密算法加密密钥,从而达到更好的安全效 ...
- 洛谷P3392 涂国旗
P3392 涂国旗 107通过 507提交 题目提供者kkksc03 标签 难度普及- 提交 讨论 题解 最新讨论 直接读字符会wa WA?-- 为什么不对... 跪求找错 快点给钱 这不就是荷兰 ...
- 1 《JavaScript高级程序设计》学习笔记(1)
欢迎关注本人的微信公众号"前端小填填",专注前端技术的基础和项目开发的学习. 首先,我将从<JavaScript高级程序设计>这本JavaScript学习者必看的经典教 ...
- Cacti修改采集精度为1分钟
前言: 基础知识:建议先了解一下 rrdtool 及 rrd 数据库的工作原理,参考阅读<rrdtool学习笔记> cacti主要使用了rrdtool这个工具来绘图,所以看上去比zabbi ...
- spring3 项目更新
列志华 (组长) http://www.cnblogs.com/liezhihua/ 团队guihub https://github.com/LWHTF/OrderingFood 黄柏堂 http:/ ...
- C#学习网站记录
C# 编程指南--Microfsoft官方C#编程指南 https://msdn.microsoft.com/zh-cn/library/67ef8sbd(v=vs.100).aspx
- java 平台 权限管理
最近在做公司内部的物流业务平台的权限管理,感触颇多.记录一下 权限管理分两部分:数据权限和操作权限. 数据权限: 这个是和用户相关的. 因为平台是多机构的,所以再考虑数据权限的时候,是按照机构来管理的 ...
- SQL日期格式化应用大全
Sql Server 中一个非常强大的日期格式化函数Select CONVERT(varchar(100), GETDATE(), 0): 05 16 2006 10:57AMSelect CONVE ...
- 第六百一十六天 how can I 坚持
有时间还是多学点东西吧,webservice.. 晚上看了个电影<我们的十年>,乔任梁死了..买了个大柚子,上火好难受.有些困惑啊. 有没有梦想,只是不想让人来到这这个世界,什么都没留下就 ...