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 ...
随机推荐
- 外壳exe通过反射调用dll时
外壳exe通过反射调用dll时,dll是 4.0的框架,外壳exe也需要编译成4.0的框架,如果dll本身有调用32位的dll,那么外壳exe也需要编译成32位. 调试时报的那个错,直接继续运行,不影 ...
- Python体验(08)-图形界面之工具栏和状态栏
# coding=utf-8 import wx # 导入必须的Python包 class MenuForm(wx.Frame): def OnQuit(self,event): self.Close ...
- 使用wcf服务捕捉到“POST http://yourIP/WCFService.svc 405 (Method Not Allowed) ”错误!
在程序中使用了一个wcf服务,调试时无任何问题(win7 64位,iis6.1),发布到部门服务器上没有问题(server2008 64位),但是部署到实际服务器上时(server2008 iis6. ...
- Jmeter plugin jp@gc - PerfMon Metrics Collector
Jmeter由于是开源工具,所以目前有很多插件可以供使用,最简单的方法是先把Plugin Manager安装了 下载地址:https://jmeter-plugins.org/wiki/Plugins ...
- 关于oracle中创建新表时将我们要用的表的结构和数据都复制过去
今天在oracle中遇到了一个问题,就是给我查询出来了一张表的数据,只有部分的字段,让我将这张表的结构和数据放到新的临时表中,并进行数据的查询. 我是这样做的: 如:create table tabl ...
- neutron floatingip-delete
- iOS CoreAnimate
iOS CoreAnimate 东西比较多,这篇笔记是入门用的,主要讲述的是静态的图形绘画处理问题.(当然动画也只是一小部分)理解相关的概念问题: 参考资料 http://segmentfault ...
- WEB文件上传漏洞介绍解决办法
引用:http://blog.csdn.net/kobejayandy/article/details/35861499 问题: -1. 上传文件WEB脚本语言,服务器的WEB容器解释并执行了用户上传 ...
- ue4框架C++语法汇总文章
1.Run external .exe file TCHAR* url = TEXT("C:\\windows\\system32\\calc.exe"); FPlatformPr ...
- ES6 学习笔记(1)
恰逢换工作之际,新公司的是以 ES6 + webpack + vue 为技术栈, 正好ES6是我下个学习目标, 因此买了阮老师的 ES6标准入门,也当是支持阮老师了. 笔记将会照着这本书的阅读展开而做 ...