android删除sim卡短信,Android的SIM卡信息的初始化过程

Phone

对象初始化的过程中,会加载SIM卡的部分数据信息,这些信息会保存在IccRecords 和 AdnRecordCache

中。SIM卡的数据信息的初始化过程主要分为如下几个步骤

1.RIL 和 UiccController 建立监听关系

,SIM卡状态发生变化时,UiccController 第一个去处理。

Phone 应用初始化 Phone 对象时会建立一个 RIL

和UiccController 的监听关系:UiccController 监听 RIL,相关代码如下

sCommandsInterface = new RIL(context,

networkMode, cdmaSubscription);  UiccController.make(context,

sCommandsInterface);

UiccController 构造的过程

private UiccController(Context c, CommandsInterface ci)

{

if (DBG) log("Creating

UiccController");

mContext = c;

mCi = ci;

mCi.registerForIccStatusChanged(this,

EVENT_ICC_STATUS_CHANGED, null);

// TODO remove this once modem correctly notifies

the unsols

mCi.registerForOn(this, EVENT_ICC_STATUS_CHANGED,

null);

}

从代码中可以看出,UiccController 对象被注册为RIL对象的监听者,当 RIL 检测到 uicc card

状态发生变化或者 radio on UiccController 都会处理对应的数据变化。UiccController 是

SIM卡状态发生变化后的第一个处理者。

UiccController 处理 EVENT_ICC_STATUS_CHANGED

public void handleMessage (Message msg) {

synchronized (mLock) {

switch

(msg.what) {

case

EVENT_ICC_STATUS_CHANGED:

if (DBG) log("Received EVENT_ICC_STATUS_CHANGED,

calling getIccCardStatus");

mCi.getIccCardStatus(obtainMessage(EVENT_GET_ICC_STATUS_DONE));

break;

case

EVENT_GET_ICC_STATUS_DONE:

if (DBG) log("Received

EVENT_GET_ICC_STATUS_DONE");

AsyncResult ar =

(AsyncResult)msg.obj;

onGetIccCardStatusDone(ar);

break;

default:

Rlog.e(LOG_TAG, " Unknown Event " +

msg.what);

}

}

}

从代码中可以看出,RIL  上报

SIM卡状态发生变化后,做了两件事,一是获取SIM卡的具体状态,二是处理这个状态。

UiccController 处理具体的SIM卡状态

private synchronized void onGetIccCardStatusDone(AsyncResult

ar) {

if (ar.exception != null) {

Rlog.e(LOG_TAG,"Error getting ICC status.

"

+ "RIL_REQUEST_GET_ICC_STATUS should

"

+ "never return an error",

ar.exception);

return;

}

IccCardStatus status =

(IccCardStatus)ar.result;

if (mUiccCard == null) {

//Create

new card

mUiccCard =

new UiccCard(mContext, mCi, status);

} else {

//Update

already existing card

mUiccCard.update(mContext, mCi ,

status);

}

if (DBG) log("Notifying

IccChangedRegistrants");

mIccChangedRegistrants.notifyRegistrants();

}

从代码中可以看出,做了两件事,一是 创建或者 更新 UiccCard

二是 通知监听 UiccController 的监听者。

2.创建或者更新 UiccCard,UiccCard

创建或者更新与SIM卡类型对应的UiccCardApplication.

一个UiccCard 对象代表着一张SIM卡,UiccCard 根据获取的SIM卡信息创建

UiccCardApplication,UiccCardApplication去读取具体的SIM卡里的信息。

更新UiccCard

public void update(Context c, CommandsInterface ci,

IccCardStatus ics) {

synchronized (mLock) {

if

(mDestroyed) {

loge("Updated after destroyed!

Fix me!");

return;

}

CardState

oldState = mCardState;

mCardState

= ics.mCardState;

mUniversalPinState =

ics.mUniversalPinState;

mGsmUmtsSubscriptionAppIndex =

ics.mGsmUmtsSubscriptionAppIndex;

mCdmaSubscriptionAppIndex =

ics.mCdmaSubscriptionAppIndex;

mImsSubscriptionAppIndex=

ics.mImsSubscriptionAppIndex;

mContext =

c;

mCi =

ci;

//update

applications

if (DBG)

log(ics.mApplications.length + " applications");

for ( int i

= 0; i < mUiccApplications.length; i++) {

if (mUiccApplications[i] ==

null) {

//Create newly added

Applications

if (i < ics.mApplications.length)

{

mUiccApplications[i] = new

UiccCardApplication(this,

ics.mApplications[i], mContext,

mCi);

}

} else if (i >=

ics.mApplications.length) {

//Delete removed applications

mUiccApplications[i].dispose();

mUiccApplications[i] = null;

} else {

//Update the rest

mUiccApplications[i].update(ics.mApplications[i],

mContext, mCi);

}

}

if

(mUiccApplications.length > 0 && mUiccApplications[0] !=

null) {

// Initialize or Reinitialize

CatService

mCatService =

CatService.getInstance(mCi,

mContext,

this);

} else

{

if (mCatService != null)

{

mCatService.dispose();

}

mCatService =

null;

}

sanitizeApplicationIndexes();

RadioState

radioState = mCi.getRadioState();

if (DBG)

log("update: radioState=" + radioState + "

mLastRadioState="

+ mLastRadioState);

// No

notifications while radio is off or we just powering

up

if

(radioState == RadioState.RADIO_ON && mLastRadioState ==

RadioState.RADIO_ON) {

if (oldState !=

CardState.CARDSTATE_ABSENT &&

mCardState

== CardState.CARDSTATE_ABSENT) {

if (DBG) log("update: notify card

removed");

mAbsentRegistrants.notifyRegistrants();

mHandler.sendMessage(mHandler.obtainMessage(EVENT_CARD_REMOVED,

null));

} else if (oldState ==

CardState.CARDSTATE_ABSENT &&

mCardState

!= CardState.CARDSTATE_ABSENT) {

if (DBG) log("update: notify card

added");

mHandler.sendMessage(mHandler.obtainMessage(EVENT_CARD_ADDED,

null));

}

}

mLastRadioState = radioState;

}

}

IccCardStatus,记录了RIL 读取的SIM卡的信息,UiccCard 根据 IccCardStatus

中记录的应用程序信息,创建 UiccCardApplication.

UiccCard 还创建了 CatService,用于读取 STK 的信息。

创建或者更新 UiccCardApplication

UiccCardApplication,会记录对应的卡的状态,类型,以及卡的记录信息。

//创建 UiccCardApplication

UiccCardApplication(UiccCard uiccCard,

IccCardApplicationStatusas,

Context

c,

CommandsInterface ci) {

if (DBG) log("Creating UiccApp: " +

as);

mUiccCard = uiccCard;

mAppState = as.app_state;

mAppType = as.app_type;

mPersoSubState =

as.perso_substate;

mAid = as.aid;

mAppLabel = as.app_label;

mPin1Replaced = (as.pin1_replaced !=

0);

mPin1State = as.pin1;

mPin2State = as.pin2;

mContext = c;

mCi = ci;

mIccFh =

createIccFileHandler(as.app_type);

mIccRecords = createIccRecords(as.app_type,

mContext, mCi);

///读取 SIM卡上的 EF 文件信息

if (mAppState == AppState.APPSTATE_READY)

{

queryFdn();

// FDN 信息

queryPin1State(); // Pin State

}

}

//更新UiccCardApplication

void update (IccCardApplicationStatusas, Context c,

CommandsInterface ci) {

synchronized (mLock) {

if

(mDestroyed) {

loge("Application updated

after destroyed! Fix me!");

return;

}

if (DBG)

log(mAppType + " update. New " + as);

mContext =

c;

mCi =

ci;

AppType

oldAppType = mAppType;

AppState

oldAppState = mAppState;

PersoSubState oldPersoSubState =

mPersoSubState;

mAppType =

as.app_type;

mAppState =

as.app_state;

mPersoSubState =

as.perso_substate;

mAid =

as.aid;

mAppLabel =

as.app_label;

mPin1Replaced = (as.pin1_replaced !=

0);

mPin1State

= as.pin1;

mPin2State

= as.pin2;

if

(mAppType != oldAppType) {

if (mIccFh != null) {

mIccFh.dispose();}

if (mIccRecords != null) {

mIccRecords.dispose();}

mIccFh =

createIccFileHandler(as.app_type);

mIccRecords =

createIccRecords(as.app_type, c, ci);

}

if

(mPersoSubState != oldPersoSubState &&

mPersoSubState ==

PersoSubState.PERSOSUBSTATE_SIM_NETWORK) {

notifyNetworkLockedRegistrantsIfNeeded(null);

}

if

(mAppState != oldAppState) {

if (DBG) log(oldAppType + "

changed state: " + oldAppState + " -> " +

mAppState);

// If the app state turns to

APPSTATE_READY, then query FDN status,

//as it might have failed in

earlier attempt.

if (mAppState ==

AppState.APPSTATE_READY) {

queryFdn();// FDN 信息

queryPin1State();

}

notifyPinLockedRegistrantsIfNeeded(null);

notifyReadyRegistrantsIfNeeded(null);

}

}

}

在更新和创建UiccCardApplication的过程中,有如下几个重要的变量

IccRecords

记录 SIM卡上的EF

文件信息,实现类有SIMRecords,RuimRecords,IsimUiccRecords,对应于不同的类型的SIM卡。

IccFileHandler

根据SIM卡的类型,去读取SIM卡上的信息,实现类有SIMFileHandler,RuimFileHandler,UsimFileHandler,CsimFileHandler,IsimFileHandler,对应于不同的SIM卡。

创建 IccRecords 对象

正如前面所描述的,IccRecords 记录SIM卡的EF文件信息,具体的读取SIM卡EF文件信息的过程是由

IccFileHandler 来实现的,以 SIMRecords 为例。

public SIMRecords(UiccCardApplication app, Context c,

CommandsInterface ci) {

super(app, c, ci);

// 1.电话本的缓存

mAdnCache = new

AdnRecordCache(mFh);

mVmConfig = new

VoiceMailConstants();

mSpnOverride = new

SpnOverride();

mRecordsRequested = false;  //

No load request is made till SIM ready

// recordsToLoad is set to 0 because no requests

are made yet

mRecordsToLoad = 0;

mCi.setOnSmsOnSim(this, EVENT_SMS_ON_SIM,

null);

mCi.registerForIccRefresh(this,

EVENT_SIM_REFRESH, null);

// Start off by setting empty

state

resetRecords();

//2. 读取 SIM卡的所有重要的记录信息

mParentApp.registerForReady(this,

EVENT_APP_READY, null);

if (DBG) log("SIMRecords X ctor this=" +

this);

}

这个过程包含两个重要的步骤

创建AdnRecordCache,用于保存电话本数据,根据EF的ID,可以分别读取SIM卡和USIM卡的电话本数据。AdnRecordCache

中持有一个UsimPhoneBookManager,它就是用来读取USIM卡电话本数据的。GSM的SIM卡和WCDMA的USIM卡都是对应的

SimRecords.

读取SIM卡的所有重要记录信息,在fetchSimRecords 方法中实现。

protected void fetchSimRecords() {

mRecordsRequested = true;

if (DBG) log("fetchSimRecords " +

mRecordsToLoad);

mCi.getIMSIForApp(mParentApp.getAid(),

obtainMessage(EVENT_GET_IMSI_DONE));

mRecordsToLoad++;

mFh.loadEFTransparent(EF_ICCID,

obtainMessage(EVENT_GET_ICCID_DONE));

mRecordsToLoad++;

// FIXME should examine EF[MSISDN]'s capability

configuration

// to determine which is the voice/data/fax

line

new AdnRecordLoader(mFh).loadFromEF(EF_MSISDN,

EF_EXT1, 1,

obtainMessage(EVENT_GET_MSISDN_DONE));

mRecordsToLoad++;

// Record number is subscriber

profile

mFh.loadEFLinearFixed(EF_MBI, 1,

obtainMessage(EVENT_GET_MBI_DONE));

mRecordsToLoad++;

mFh.loadEFTransparent(EF_AD,

obtainMessage(EVENT_GET_AD_DONE));

mRecordsToLoad++;

// Record number is subscriber

profile

mFh.loadEFLinearFixed(EF_MWIS, 1,

obtainMessage(EVENT_GET_MWIS_DONE));

mRecordsToLoad++;

// Also load CPHS-style voice mail indicator,

which stores

// the same info as EF[MWIS]. If both exist, both

are updated

// but the EF[MWIS] data is

preferred

// Please note this must be loaded after

EF[MWIS]

mFh.loadEFTransparent(

EF_VOICE_MAIL_INDICATOR_CPHS,

obtainMessage(EVENT_GET_VOICE_MAIL_INDICATOR_CPHS_DONE));

mRecordsToLoad++;

// Same goes for Call Forward Status indicator:

fetch both

// EF[CFIS] and CPHS-EF, with EF[CFIS]

preferred.

mFh.loadEFLinearFixed(EF_CFIS, 1,

obtainMessage(EVENT_GET_CFIS_DONE));

mRecordsToLoad++;

mFh.loadEFTransparent(EF_CFF_CPHS,

obtainMessage(EVENT_GET_CFF_DONE));

mRecordsToLoad++;

getSpnFsm(true, null);

mFh.loadEFTransparent(EF_SPDI,

obtainMessage(EVENT_GET_SPDI_DONE));

mRecordsToLoad++;

mFh.loadEFLinearFixed(EF_PNN, 1,

obtainMessage(EVENT_GET_PNN_DONE));

mRecordsToLoad++;

mFh.loadEFTransparent(EF_SST,

obtainMessage(EVENT_GET_SST_DONE));

mRecordsToLoad++;

mFh.loadEFTransparent(EF_INFO_CPHS,

obtainMessage(EVENT_GET_INFO_CPHS_DONE));

mRecordsToLoad++;

mFh.loadEFTransparent(EF_CSP_CPHS,obtainMessage(EVENT_GET_CSP_CPHS_DONE));

mRecordsToLoad++;

mFh.loadEFTransparent(EF_GID1,

obtainMessage(EVENT_GET_GID1_DONE));

mRecordsToLoad++;

// XXX should seek instead of examining them

all

if (false) { // XXX

mFh.loadEFLinearFixedAll(EF_SMS,

obtainMessage(EVENT_GET_ALL_SMS_DONE));

mRecordsToLoad++;

}

if (CRASH_RIL) {

String sms

=

"0107912160130310f20404d0110041007030208054832b0120"

+

"fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff"

+

"fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff"

+

"fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff"

+

"fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff"

+

"ffffffffffffffffffffffffffffff";

byte[] ba =

IccUtils.hexStringToBytes(sms);

mFh.updateEFLinearFixed(EF_SMS, 1, ba,

null,

obtainMessage(EVENT_MARK_SMS_READ_DONE,

1));

}

if (DBG) log("fetchSimRecords " + mRecordsToLoad

+ " requested: " + mRecordsRequested);

}

总的来说,创建 SimRecords 的过程就是读取并且保存SIM卡重要信息的过程。其中,电话本的信息保存在 mAdnCache

中,其他信息保存在 SimRecords 中,但是在Phone对象完成初始化后,mAdnCache

里是空的,也就是说,在IccRecords 初始化的过程中,AdnRecordCache

并没有主动去请求SIM卡联系人的数据。

所有的IccRecords 是通过 IccFileHandler 向Modem 发命令读取数据的。他们之间的交互图如下

a4c26d1e5885305701be709a3d33442f.png

3.通知UiccController

的监听者,与UiccCardApplication的相关信息可以更新了。根据分析源代码,我们可以看到,PhoneBase

,ServiceStateTracker,IccCardProxy,DcTrackerBase,这些类是 UiccController

的监听者。他们都会处理UiccController

的变化。我们可以这么理解,这些类是SIM卡状态发生变化后,第二批处理SIM卡状态变化的实体。第一个处理SIM卡状态变化的是

UiccController.

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值