这篇关于android源码是如何操作sim卡上的信息说明,sim\usim卡的信息说起来这算是比较特别的一部分,由于android源码的信息是没有开机自动导卡信息和联系人的,所以有时会忘掉它的存在应该说关于卡信息操作源码只是实现大部分功能:可以读和删除卡上信息,把信息复制到手机上,但是不能把信息写入卡,这个功能是要我们自己实现的,当然仅仅是实现就好了,毕竟基本的框架google已经写好了。先看看已有功能的代码,原理是一样的。
private static final Uri ICC_URI = Uri.parse("content://sms/icc"); private void startQuery() { try { mQueryHandler.startQuery(0, null, ICC_URI, null, null, null, null); } catch (SQLiteException e) { SqliteWrapper.checkSQLiteException(this, e); } }根据上面的uri ICC_URI可以跟踪到SmsProvider.java的query()方法switch分支中的getAllMessagesFromIcc()方法,代码如下
private Cursor getAllMessagesFromIcc() { SmsManager smsManager = SmsManager.getDefault(); ArrayList<SmsMessage> messages = smsManager.getAllMessagesFromIcc(); ......省略部分代码...... }看到一个SmsManager的对象,操作卡信息就看它了,这个类里有删、改、查相应的方法,查询调用的方法如下:
public static ArrayList<SmsMessage> getAllMessagesFromIcc() { List<SmsRawData> records = null; try { ISms iccISms = ISms.Stub.asInterface(ServiceManager.getService("isms"));//AIDL if (iccISms != null) { records = iccISms.getAllMessagesFromIccEf();//我们关心这个,下面的代码 } } catch (RemoteException ex) { // ignore it } return createMessageListFromRawRecords(records); }
public List<SmsRawData> getAllMessagesFromIccEf() { if (DBG) log("getAllMessagesFromEF"); Context context = mPhone.getContext(); context.enforceCallingPermission( "android.permission.RECEIVE_SMS", "Reading messages from SIM"); synchronized(mLock) { //同步锁 Message response = mHandler.obtainMessage(EVENT_LOAD_DONE); mPhone.getIccFileHandler().loadEFLinearFixedAll(IccConstants.EF_SMS, response);//这里是实际干活的语句 try { mLock.wait(); } catch (InterruptedException e) { log("interrupted while trying to load from the SIM"); } } return mSms; }上面那个IccConstants.EF_SMS的值十六进制6F3C,转成十进制是28476,这里告诉我们卡上的信息在卡上6F3C这个位置上,要操作卡的信息 要找到这个,为什么要找这个位置,相信3gpp 11.14这个文档有明确的解释的,还是先看看loadEFLinearFixedAll()做了什么吧。
public void loadEFLinearFixedAll(int fileid, Message onLoaded) { Message response = obtainMessage(EVENT_GET_RECORD_SIZE_DONE, new LoadLinearFixedContext(fileid,onLoaded));//消息队列 phone.mCM.iccIO(COMMAND_GET_RESPONSE, fileid, getEFPath(fileid), 0, 0, GET_RESPONSE_EF_SIZE_BYTES, null, null, response);//看到iccIO就快到ril了 } RIl层的iccIO代码 public void iccIO (int command, int fileid, String path, int p1, int p2, int p3, String data, String pin2, Message result) { //Note: This RIL request has not been renamed to ICC, //but this request is also valid for SIM and RUIM RILRequest rr = RILRequest.obtain(RIL_REQUEST_SIM_IO, result);//这个标志RIL_REQUEST_SIM_IO .....省略部分代码,不影响我们跟踪代码...... send(rr); }这个标志RIL_REQUEST_SIM_IO在reference-ril.c的代码里可以找到,当然还有可能在别的文件中,毕竟是开源的代码,我们是可以修改或添加的。 最后关于操作卡信息at命令通常是at + crsm这样的形式, 命令格式 :+CRSM=<command>[,<fileid>[,<P1>,<P2>,<P3>[,<data>]]] command就下面这几种