呼叫转移设置
Android5.0之后的版本,手机的CallSetting设置一般在package/APPs/service/Telephony中
1.CallFeartureSettingActivity.java为通话设置入口
//在谷歌的源码中没有这个类,可以直接看2、CallFeatureSetting
在onResume方法中判断手机是单卡还是双卡
单卡直接通过CallFeatureSetting进入补充业务的设置界面,双卡先进入PhoneAccountSettingActivity的双卡选择界面,再通过PhoneAccountSettingFragmentNew选择某个sim卡,以intent进入CallFeatureSetting的activity
2.CallFeatureSetting设置补充业务
CallFeatureSetting中的onResume中调用init,
if (carrierConfig.getBoolean(CarrierConfigManager.KEY_WORLD_PHONE_BOOL)) {
cdmaOptions.setIntent(mSubscriptionInfoHelper.getIntent(CdmaCallOptions.class));
gsmOptions.setIntent(mSubscriptionInfoHelper.getIntent(GsmUmtsCallOptions.class));
} else {
prefSet.removePreference(cdmaOptions);
prefSet.removePreference(gsmOptions);
int phoneType = mPhone.getPhoneType();
if (carrierConfig.getBoolean(CarrierConfigManager.KEY_HIDE_CARRIER_NETWORK_settings_BOOL)) {
prefSet.removePreference(fdnButton);
} else {
if (phoneType == Phoneconstants.PHONE_TYPE_CDMA) {
prefSet.removePreference(fdnButton);//固定拨号
if (!carrierConfig.getBoolean(
CarrierConfigManager.KEY_VOICE_PRIVACY_disable_UI_BOOL)) {
addPreferencesFromResource(R.xml.cdma_call_privacy);
}
} else if (phoneType == PhoneConstants.PHONE_TYPE_GSM) {
if (carrierConfig.getBoolean(
CarrierConfigManager.KEY_ADDITIONAL_CALL_SETTING_BOOL)) {
addPreferencesFromResource(R.xml.gsm_umts_call_options);
GsmUmtsCallOptions.init(prefSet, mSubscriptionInfoHelper);
}
} else {
throw new IllegalStateException("unexpected phone type: " + phoneType);
}
}
GsmUmtsCallOption.init(preferencescreen,SubscriptionIfoHelper)为补充业务的preference建立对应的intent
63 public static void init(PreferenceScreen prefScreen, SubscriptionInfoHelper subInfoHelper) {
64 Preference callForwardingPref = prefScreen.findPreference(CALL_FORWARDING_KEY);
65 callForwardingPref.setIntent(subInfoHelper.getIntent(GsmUmtsCallForwardOptions.class));
66
67 Preference additionalGsmSettingsPref =
68 prefScreen.findPreference(ADDITIONAL_GSM_SETTINGS_KEY);
69 additionalGsmSettingsPref.setIntent(
70 subInfoHelper.getIntent(GsmUmtsAdditionalCallOptions.class));
不同的补充业务会转入不同的activity,呼叫转移业务对应的activity为GsmUmtsCallForwardOption。
3. GsmUmtsCallForwardOption呼叫转移的activity
在onResume中进行界面初始化,调用init函数,
@Override
public void onResume() {
super.onResume();
if (mFirstResume) {
if (mIcicle == null) {
if (DBG) Log.d(LOG_TAG, "start to init ");
mPreferences.get(MinitIndex).init(this, false, mPhone);
} else {
mInitIndex = mPreferences.size();
for (CallForwardEditPreference pref : mPreferences) {
Bundle bundle = mIcicle.getParcelable(pref.getKey());
pref.setToggled(bundle.getBoolean(KEY_TOGGLE));
CallForwardInfo cf = new CallForwardInfo();
cf.number = bundle.getString(KEY_NUMBER);
cf.status = bundle.getInt(KEY_STATUS);
pref.handleCallForwardResult(cf);
pref.init(this, true, mPhone);
}
}
mFirstResume = false;
mIcicle = null;
}
}
在初次进入时会进行四种呼叫转移的初始化,因为四个呼叫转移都是CallForwardEditPreference类,所以具体每个Preference的点击动作应该看CallForwardEditPreference类;CallForwardEditPreference通过Myhandle的消息处理handlemessage,分别为handleGetCFresponse(设置新CF)与handleSetCFResponse (读取CF状态)。
CallForwardEditPreference分为始终转接,占线时转接,无人接听时转接和无法接听时转接四种情况,也就是四个CallForwardEditPreference,其中init函数是获取当前呼叫转移设置的代码。
void init(TimeConsumingPreferenceListener listener, boolean skipReading, Phone phone) {
mPhone = phone;
mTcpListener = listener;
if (!skipReading) {
mPhone.getCallForwardingOption(reason,
mhandler.obtainMessage(MyHandler.MESSAGE_GET_CF,
// unused in this case
commandsInterface.CF_ACTION_DISABLE,
MyHandler.MESSAGE_GET_CF, null));
if (mTcpListener != null) {
mTcpListener.onStarted(this, true);
}
}
}
4. GsmCdmaPhone
其中函数getCallForwardingOption这是个phone的接口方法,继承自接口PhoneInternalInterface
作为父类,真正的实现代码在GsmCdmaPhone.java上
@Override
public void getCallForwardingOption(int commandInterfaceCFReason, Message onComplete) {
if (isPhoneTypeGsm()) {
Phone imsPhone = mImsPhone;
//判断是否为imsPhone,是的话走ImsPhone(PS)流程,不是的话走CS流程
if ((imsPhone != null)
&& ((imsPhone.getServiceState().getState() == ServiceState.STATE_IN_SERVICE)
|| imsPhone.isUtEnabled())) {
imsPhone.getCallForwardingOption(commandInterfaceCFReason, onComplete);
return;
}
if (isvalidCommandInterfaceCFReason(commandInterfaceCFReason)) {
if (DBG) logd("requesting call forwarding query.");
Message resp;
if (commandInterfaceCFReason == CF_REASON_UNconditional) {
resp = obtainMessage(EVENT_GET_CALL_FORWARD_DONE, onComplete);
} else {
resp = onComplete;
}
mCi.queryCallforwardstatus(commandInterfaceCFReason, 0, null, resp);
}
} else {
loge("getCallForwardingOption: not possible in CDMA");
}
}
首先分析走CS流程,mCi为Phone类中的CommandsInterface接口,而CommandsInterface的接口方法都在RIL类中实现
5.RIL
调用函数RIL.queryCallForwardStatus(int cfReason, int serviceClass, String number, Message response)
@Override
public void queryCallForwardStatus(int cfReason, int serviceClass,
String number, Message result) {
IRadio radioProxy = getRadioProxy(result);
//将消息result包装为IRadio发送request到modem
if (radioProxy != null) {
RILRequest rr = obtainRequest(RIL_REQUEST_QUERY_CALL_FORWARD_STATUS, result,
mRILDefaultWorkSource);
if (RILJ_LOGD) {
riljLog(rr.serialString() + "> " + requestToString(rr.mRequest)
+ " cfreason = " + cfReason + " serviceClass = " + serviceClass);
}
android.hardware.radio.V1_0.CallForwardInfo cfInfo =
new android.hardware.radio.V1_0.CallForwardInfo();
cfInfo.reason = cfReason;
cfInfo.serviceClass = serviceClass;
cfInfo.toa = PhoneNumberUtils.toaFromString(number);
cfInfo.number = convertNullToemptyString(number);
cfInfo.timeSeconds = 0;
try {
radioProxy.getCallForwardStatus(rr.mSerial, cfInfo);
} catch (RemoteException | runtimeexception e) {
handleRadioProxyExceptionForRR(rr, "queryCallForwardStatus", e);
}
}
}
IRadio为c++程序,这是发送Requst的过程,下面就超出了本组的学习内容
相关阅读
用户界面设计 接口设计主要包括三个方面的内容:一是设计软件构件间的接口;二是设计模块和其他非人的信息生产者和消费者(如外部
一、爬取豆瓣影评 基本思路:先获取每个电影的评论区链接,然后依次进入其评论区爬取评论。选取10部电影,每部200条评论。 用到的包为
货拉拉APP产品分析:作为同城货运的APP,是如何在市场上占
在同城货运市场不断扩大趋势下,货拉拉作为一款同城货运的APP,如何在市场上占有一席之地的,又存在哪些交互细节的问题,我们一起进入产
2016年中国出生人口数量同比增长11.50%,家庭育儿市场迎来人口红利。同时,伴随着科学养育观念不断渗透,男性在家庭育儿过程中参与度越
唱吧需要怎么利用自己的目前积累的强大体量用户和明星资源,寻找差异化突破点来应对全民K歌?本文作者就此来分析,一起来瞧瞧~一、背景