博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
IccFileHandler和IccRecords
阅读量:5969 次
发布时间:2019-06-19

本文共 6921 字,大约阅读时间需要 23 分钟。

hot3.png

1.IccFileHandler

IccFileHandler主要用于从SIM卡中读取相应文件的数据。

以下是IccFileHandler的一些主要方法,我们可以看出,这些方法基本上都是用于对SIM卡中EF文件进行读写的。

public void loadEFLinearFixed(int fileid,String path,int recordNum,Message onLoaded){

public void loadEFImgLinearFixed(int recordNum,Message onLoaded){

public void getEFLinearRecordSize(int fileid,String path,Message onLoaded){

public void loadEFLinearFixedAll(int fileid,String path,Message onLoaded){

public void loadEFTransparent(int fileid,Message onLoaded){

public void loadEFImgTransparent(int fileid,int highOffset,int lowOffset,

public void updateEFLinearFixed(int fileid,String path,int recordNum,byte[] data,

public void updateEFTransparent(int fileid,byte[] data,Message onComplete){

 

IccFileHandler在初始化时会根据SIM卡中Application的类型创建不同的对象。

包括SIMFileHandler、RuimFileHandler、UsimFileHandler、CsimFileHandler以及IsimFileHandler。

这些子类都只是对getEFPath()方法进行了重写,以SIMFileHandler和UsimFileHandler为例,

SIMFileHandler.java

protected String getEFPath(int efid){

switch(efid){

case EF_SMS:

return MF_SIM + DF_TELECOM;

case EF_EXT6:

……

case EF_CSP_CPHS:

return MF_SIM + DF_GSM;

}

String path = getCommonIccEFPath(efid);

if(path == null){

Rlog.e(LOG_TAG,“Error: EF Path being returned in null”);

}

return path;

}

UsimFileHandler.java

protected String getEFPath(int efid){

switch(efid){

case EF_SMS:

……

case EF_HPPLMN:

return MF_SIM + DF_ADF;

case EF_DIR:

return MF_SIM;

}

String path = getCommonIccEFPath(efid);

if(path == null){

return MF_SIM + DF_TELECOM + DF_PHONEBOOK;

}

return path;

}

可以看出,之所以重写getEFPath()方法,就是因为不同Application的文件结构有所差异,

从而导致我们在读写EF文件时传入的地址也不同,因此,针对不同的Application,就需要

重新计算EF文件的地址,这样才能保证读写EF文件时不会出错。

当我们读取EF文件的内容时,并不会一上来就去读,而是会先读取其长度,然后再去读取相应长度的值。

 

先读取记录的长度。

public void loadEFLinearFixed(int fileid,String path,int recordNum,Message onLoaded){

String efPath =(path == null)?getEFPath(fileid):path;

Message response

= obtainMessage(EVENT_GET_RECORD_SIZE_DONE,

new LoadLinearFixedContext(fileid,recordNum,efPath,onLoaded));

mCi.iccIOForApp(COMMAND_GET_RESPONSE,fileid,efPath,

0,0,GET_RESPONSE_EF_SIZE_BYTES,null,null,mAid,response);

}

根据记录的长度再去读取具体的内容。

public void handleMessage(Message msg){

……

case EVENT_GET_RECORD_SIZE_DONE:

……

lc.mRecordSize = data[RESPONSE_DATA_RECORD_LENGTH] & 0xFF;

size =((data[RESPONSE_DATA_FILE_SIZE_1] & 0xff)<< 8)

+(data[RESPONSE_DATA_FILE_SIZE_2] & 0xff);

lc.mCountRecords = size / lc.mRecordSize;

if(lc.mLoadAll){

lc.results = new ArrayList<byte[]>(lc.mCountRecords);

}

if(path == null){

path = getEFPath(lc.mEfid);

}

……

mCi.iccIOForApp(COMMAND_READ_RECORD,lc.mEfid,path,

lc.mRecordNum,

READ_RECORD_MODE_ABSOLUTE,

lc.mRecordSize,null,null,mAid,

obtainMessage(EVENT_READ_RECORD_DONE,lc));

……

}

 

2.IccRecords

先来看看那IccRecords中定义的一些属性及方法。

protected String mIccId;// Includes only decimals(no hex)

protected String mFullIccId;// Includes hex characters in ICCID

protected String mMsisdn = null;// My mobile number

protected String mMsisdnTag = null;

protected String mNewMsisdn = null;

protected String mNewMsisdnTag = null;

protected String mVoiceMailNum = null;

protected String mVoiceMailTag = null;

protected String mNewVoiceMailNum = null;

protected String mNewVoiceMailTag = null;

protected boolean mIsVoiceMailFixed = false;

protected String mImsi;

 

public String getIMSI(){

public void setImsi(String imsi){

public String getMsisdnNumber(){

public String getMsisdnAlphaTag(){

public String getVoiceMailNumber(){

public String getVoiceMailAlphaTag(){

 

public void registerForRecordsLoaded(Handler h,int what,Object obj){

public void registerForImsiReady(Handler h,int what,Object obj){

public void registerForRecordsEvents(Handler h,int what,Object obj){

public void registerForNewSms(Handler h,int what,Object obj){

public void registerForNetworkSelectionModeAutomatic(

从这些属性及方法可以看出,IccRecords主要就是维护了SIM卡的相关信息,并提供相应接口供其它对象操作,

然后还注册了一些监听器,包或卡Loaded、IMSI ready、NewSms等。

与IccFileHandler类似,IccRecords在初始化时也会根据SIM卡中Application的类型创建不同的对象。

包括SIMRecords、RuimRecords以及IsimUiccRecords。

接下来我们还是以SIMRecords为例来进行分析。

先来看看其构造方法,会创建一个AdnRecordCache对象,用于缓存SIM卡联系人,

还会注册一些监听器。

public SIMRecords(UiccCardApplication app,Context c,CommandsInterface ci){

super(app,c,ci);

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();

mParentApp.registerForReady(this,EVENT_APP_READY,null);

mParentApp.registerForLocked(this,EVENT_APP_LOCKED,null);

if(DBG)log(“SIMRecords X ctor this=”+ this);

IntentFilter intentfilter = new IntentFilter();

intentfilter.addAction(CarrierConfigManager.ACTION_CARRIER_CONFIG_CHANGED);

c.registerReceiver(mReceiver,intentfilter);

}

当监听到SIM卡为READY状态后,就会去读取SIM卡的相关记录,而读取记录基本上都是通过IccFileHandler来进行的。

读取完成后,结果都是保存在IccRecords或其子类的相关属性中的。

protected void fetchSimRecords(){

mRecordsRequested = true;

mCi.getIMSIForApp(mParentApp.getAid(),obtainMessage(EVENT_GET_IMSI_DONE));

mRecordsToLoad++;

mFh.loadEFTransparent(EF_ICCID,obtainMessage(EVENT_GET_ICCID_DONE));

mRecordsToLoad++;

new AdnRecordLoader(mFh).loadFromEF(EF_MSISDN,getExtFromEf(EF_MSISDN),1,

obtainMessage(EVENT_GET_MSISDN_DONE));

mRecordsToLoad++;

mFh.loadEFLinearFixed(EF_MBI,1,obtainMessage(EVENT_GET_MBI_DONE));

mRecordsToLoad++;

mFh.loadEFTransparent(EF_AD,obtainMessage(EVENT_GET_AD_DONE));

mRecordsToLoad++;

mFh.loadEFLinearFixed(EF_MWIS,1,obtainMessage(EVENT_GET_MWIS_DONE));

mRecordsToLoad++;

mFh.loadEFTransparent(

EF_VOICE_MAIL_INDICATOR_CPHS,

obtainMessage(EVENT_GET_VOICE_MAIL_INDICATOR_CPHS_DONE));

mRecordsToLoad++;

loadCallForwardingRecords();

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++;

mFh.loadEFTransparent(EF_GID2,obtainMessage(EVENT_GET_GID2_DONE));

mRecordsToLoad++;

mFh.loadEFTransparent(EF_PLMN_W_ACT,obtainMessage(EVENT_GET_PLMN_W_ACT_DONE));

mRecordsToLoad++;

mFh.loadEFTransparent(EF_OPLMN_W_ACT,obtainMessage(EVENT_GET_OPLMN_W_ACT_DONE));

mRecordsToLoad++;

mFh.loadEFTransparent(EF_HPLMN_W_ACT,obtainMessage(EVENT_GET_HPLMN_W_ACT_DONE));

mRecordsToLoad++;

mFh.loadEFTransparent(EF_EHPLMN,obtainMessage(EVENT_GET_EHPLMN_DONE));

mRecordsToLoad++;

mFh.loadEFTransparent(EF_FPLMN,obtainMessage(

EVENT_GET_FPLMN_DONE,HANDLER_ACTION_NONE,-1));

mRecordsToLoad++;

loadEfLiAndEfPl();

}

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

你可能感兴趣的文章
二十四种设计模式:策略模式(Strategy Pattern)
查看>>
统计某个字符串中指定字符串出现的次数
查看>>
asp.net三层结构中,SQL助手类DbHelperSQL
查看>>
scala map和flatMap
查看>>
.Net Core下使用 RSA
查看>>
python 数据库中文乱码 Excel
查看>>
利用console控制台调试php代码
查看>>
递归算法,如何把list中父子类对象递归成树
查看>>
jsf初学解决GlassFish Server 无法启动
查看>>
【Gson】2.2.4 StackOverflowError 异常
查看>>
hdu 1050 (preinitilization or postcleansing, std::fill) ...
查看>>
Form各键盘触发子所对应的“按键”
查看>>
【java IO】使用Java输入输出流 读取txt文件内数据,进行拼接后写入到另一个文件中...
查看>>
Linux系统下安装rz/sz命令及使用说明
查看>>
点击按钮抓不到页面的参数
查看>>
CentOS 6.5 下安装 Redis 2.8.7
查看>>
第一次模拟面试
查看>>
window.showModalDialog
查看>>
Pycharm选择pyenv安装的Python版本
查看>>
?Sized 和 Sized
查看>>