Android运营商名称显示

下列情况都会触发更新运营商名称。
1 卡loaded
2 IMS_CAPABILITY_CHANGED
3 LOCALE_CHANGED
4 SubscriptionsChanged
5 ServiceStateChanged

更新运营商名称的入口为ServiceStateTracker.updateSpnDisplay()。
这里面会根据多种条件来判断显示SPN还是PLMN,或者是两者都显示,

PLMN是查询状态时通过RIL.getOperator()去获取的,保存在ServiceState的mVoiceOperatorAlphaLong/mVoiceOperatorAlphaShort中。

SPN可以保存在EF_SPN (0x6F46)、EF_SPN_CPHS(0x6F14)或者EF_SPN_SHORT_CPHS(0x6F18)中,
卡READY后在fetchSimRecords()中读取,之后保存在IccRecords.mSpn中

最后发送广播SPN_STRINGS_UPDATED_ACTION进行通知。

 

如果WFC打开了,会先读取WFC运营商的显示格式

运营商的显示可以为PLMN和(或)SPN,SPN从SIM卡中读取,PLMN为当前注册的网络。
GSM基本规则如下:
1 当设置了OperatorBrandOverride时,只显示PLMN
2 没有SPN或SPN未加载时,显示PLMN,
3 当注册到HPLMN或EF_SPDI列表中的PLMN时,则
a.显示SPN
b.若EF_SPN的第一字节的bit0为1,则显示PLMN,否则不显示PLMN
4 其它情况
a.显示PLMN
b.若EF_SPN的第一字节的bit1为0,则显示SPN,否则不显示SPN

相应代码为:
// See TS 22.101 Annex A and TS 51.011 10.3.11 for details.
SIMRecords.getDisplayRule()

有了显示规则,接下来就是获取需要显示的SPN/PLMN了。

1 PLMN
STATE_EMERGENCY_ONLY:R.string.emergency_calls_only
STATE_OUT_OF_SERVICE:R.string.lockscreen_carrier_default
STATE_IN_SERVICE:mSS.getOperatorAlpha()
其它状态:R.string.lockscreen_carrier_default

2 SPN
如果注上了WFC,则需要将SPN转换为WFC的格式
 

 


接下来再看PLMN及SPN的获取。

PLMN是查询状态时通过RIL.getOperator()去获取的,

public void pollState(boolean modemTriggered) {
......
switch (mCi.getRadioState()) {
case RADIO_UNAVAILABLE:
......
case RADIO_OFF:
......
default:
// Issue all poll-related commands at once then count down the responses, which
// are allowed to arrive out-of-order
mPollingContext[0]++;
mCi.getOperator(obtainMessage(EVENT_POLL_STATE_OPERATOR, mPollingContext));
......
}

请求返回后,保存到ServiceState的mVoiceOperatorAlphaLong/mVoiceOperatorAlphaShort中,
如果有OperatorBrandOverride的话,则会使用brandOverride的值。

void handlePollStateResultMessage(int what, AsyncResult ar) {
int ints[];
switch (what) {
......
case EVENT_POLL_STATE_OPERATOR: {
if (mPhone.isPhoneTypeGsm()) {
String opNames[] = (String[]) ar.result;

if (opNames != null && opNames.length >= 3) {
// FIXME: Giving brandOverride higher precedence, is this desired?
String brandOverride = mUiccController.getUiccCard(getPhoneId()) != null ?
mUiccController.getUiccCard(getPhoneId()).getOperatorBrandOverride() : null;
if (brandOverride != null) {
log("EVENT_POLL_STATE_OPERATOR: use brandOverride=" + brandOverride);
mNewSS.setOperatorName(brandOverride, brandOverride, opNames[2]);
} else {
mNewSS.setOperatorName(opNames[0], opNames[1], opNames[2]);
}
}
} else {
......
}
break;
}


SPN可以保存在EF_SPN(0x6F46)、EF_SPN_CPHS(0x6F14)或者EF_SPN_SHORT_CPHS(0x6F18)中,
卡READY后在fetchSimRecords()中读取,之后保存在IccRecords.mSpn中

protected void fetchSimRecords() {
......
getSpnFsm(true, null);
......
}

我们会最先从EF_SPN(0x6F46)中读取,如果没有,则会再从EF_SPN_CPHS(0x6F14)中读取,若还是没有,最后会从EF_SPN_SHORT_CPHS(0x6F18)中读取。
private void getSpnFsm(boolean start, AsyncResult ar) {
......
switch(mSpnState){
case INIT:
setServiceProviderName(null);

mFh.loadEFTransparent(EF_SPN,
obtainMessage(EVENT_GET_SPN_DONE));
mRecordsToLoad++;

mSpnState = GetSpnFsmState.READ_SPN_3GPP;
break;
case READ_SPN_3GPP:
if (ar != null && ar.exception == null) {
data = (byte[]) ar.result;
mSpnDisplayCondition = 0xff & data[0];

setServiceProviderName(IccUtils.adnStringFieldToString(
data, 1, data.length - 1));
// for card double-check and brand override
// we have to do this:
final String spn = getServiceProviderName();

if (spn == null || spn.length() == 0) {
mSpnState = GetSpnFsmState.READ_SPN_CPHS;
} else {
if (DBG) log("Load EF_SPN: " + spn
+ " spnDisplayCondition: " + mSpnDisplayCondition);
mTelephonyManager.setSimOperatorNameForPhone(
mParentApp.getPhoneId(), spn);

mSpnState = GetSpnFsmState.IDLE;
}
} else {
mSpnState = GetSpnFsmState.READ_SPN_CPHS;
}

if (mSpnState == GetSpnFsmState.READ_SPN_CPHS) {
mFh.loadEFTransparent( EF_SPN_CPHS,
obtainMessage(EVENT_GET_SPN_DONE));
mRecordsToLoad++;

// See TS 51.011 10.3.11. Basically, default to
// show PLMN always, and SPN also if roaming.
mSpnDisplayCondition = -1;
}
break;
case READ_SPN_CPHS:
if (ar != null && ar.exception == null) {
data = (byte[]) ar.result;

setServiceProviderName(IccUtils.adnStringFieldToString(
data, 0, data.length));
// for card double-check and brand override
// we have to do this:
final String spn = getServiceProviderName();

if (spn == null || spn.length() == 0) {
mSpnState = GetSpnFsmState.READ_SPN_SHORT_CPHS;
} else {
// Display CPHS Operator Name only when not roaming
mSpnDisplayCondition = 2;

if (DBG) log("Load EF_SPN_CPHS: " + spn);
mTelephonyManager.setSimOperatorNameForPhone(
mParentApp.getPhoneId(), spn);

mSpnState = GetSpnFsmState.IDLE;
}
} else {
mSpnState = GetSpnFsmState.READ_SPN_SHORT_CPHS;
}

if (mSpnState == GetSpnFsmState.READ_SPN_SHORT_CPHS) {
mFh.loadEFTransparent(
EF_SPN_SHORT_CPHS, obtainMessage(EVENT_GET_SPN_DONE));
mRecordsToLoad++;
}
break;
case READ_SPN_SHORT_CPHS:
if (ar != null && ar.exception == null) {
data = (byte[]) ar.result;

setServiceProviderName(IccUtils.adnStringFieldToString(
data, 0, data.length));
// for card double-check and brand override
// we have to do this:
final String spn = getServiceProviderName();

if (spn == null || spn.length() == 0) {
if (DBG) log("No SPN loaded in either CHPS or 3GPP");
} else {
// Display CPHS Operator Name only when not roaming
mSpnDisplayCondition = 2;

if (DBG) log("Load EF_SPN_SHORT_CPHS: " + spn);
mTelephonyManager.setSimOperatorNameForPhone(
mParentApp.getPhoneId(), spn);
}
} else {
setServiceProviderName(null);
if (DBG) log("No SPN loaded in either CHPS or 3GPP");
}

mSpnState = GetSpnFsmState.IDLE;
break;
default:
mSpnState = GetSpnFsmState.IDLE;
}
}


 

转载于:https://my.oschina.net/igiantpanda/blog/1787609

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值