上一篇总结icc card和app的更新过程,更新结束以后,会发出ready通知,如下图,第三主线的主要内容是,iccCardProxy.java通过UiccController监听状态变化信息,并更新上层的一些属性值:
1.iccCardProxy.java
当UICC card和APP更新结束以后,iccCardProxy.java通过UiccController注册了卡状态监听,当接收到UiccController发送的EVENT_ICC_CHANGED事件之后,更新icc上层的属性值,主要是调用updateExternalState()方法;
public IccCardProxy(Context context, CommandsInterface ci, PhoneBase phone)
{ mUiccController = UiccController.getInstance(); mUiccController.registerForIccChanged(this, EVENT_ICC_CHANGED, null); ci.registerForOn(this,EVENT_RADIO_ON, null); }
case EVENT_ICC_CHANGED:
updateIccAvailability();
break;
private void updateIccAvailability() {
synchronized (mLock) {
if (mIccRecords != newRecords||mUiccApplication != newApp||mUiccCard != newCard)
{ if (DBG) log("Icc changed. Reregestering.");
unregisterUiccCardEvents();
mUiccCard = newCard;
mUiccApplication = newApp;
mIccRecords = newRecords;
registerUiccCardEvents(); //注册成为 UiccCard、UiccCardApplication、
//IccRecords 的监听器,可以从他们获取SIM卡的相关信息
}
updateExternalState();
}
在updateExternalState()中,若是接收到了之前更新icc状态上发的Ready信号,就会将gsm.sim.state属性值设置成Ready:
private void updateExternalState()
{ switch (mUiccApplication.getState())
{ case APPSTATE_READY:
if (mInvalidSimNotiDisplayed){removeInvalidSIMNotification();}
setExternalState(State.READY);
break;
} }
private void setExternalState(State newState, boolean override) {
mExternalState = newState;
mTelephonyManager.setSimStateForPhone(mPhoneId, getState().toString());
}
其中,State的状态在iccContants.java里面有设置,上层用户可以通过查询这个状态知道此时sim卡的状态如何:
State | State | ||
UNKNOWN | 未知 | PERM_DISABLED | puk解锁fail |
ABSENT | 无卡 | CARD_IO_ERROR | 卡io错误 |
PIN_REQUIRED | 需要pin解锁 | PERSO_LOCKED | |
PUK_REQUIRED | 需要puk解锁 | NETWORK_SUBSET_LOCKED | |
NETWORK_LOCKED | 需要NETWORK pin解锁 | SIM_SERVICE_PROVIDER_LOCKED | |
READY | 卡准备好 | DETECTED | |
NOT_READY | 卡未准备好 |
通过修改这个属性,上层的app就可以读到当前的卡状态了;
关于PhoneProxy.java,主要涉及到了电话管理的phone应用层的实现机制,是一种安卓代理模式(Proxy),之后会详细总结,下一篇将会总结第四个主线,即当icc状态更新完成之后,开始对卡上的EF文件进行读写的流程。