平台
RK3288 + Android 7.1 + EC20
流程
获取手机号代码:
TelephonyManager telMgr = (TelephonyManager) getSystemService(TELEPHONY_SERVICE); if (telMgr != null) { String num = telMgr.getLine1Number();//手机号码 }
接口跟踪
//–frameworks/base/telephony/java/android/telephony/TelephonyManager.java public String getLine1Number() { return getLine1Number(getSubId()); } public String getLine1Number(int subId) { String number = null; try { ITelephony telephony = getITelephony(); if (telephony != null) number = telephony.getLine1NumberForDisplay(subId, mContext.getOpPackageName()); } catch (RemoteException ex) { } catch (NullPointerException ex) { } if (number != null) { return number; } try { //手上测试卡执行的是这部分代码: IPhoneSubInfo info = getSubscriberInfo(); if (info == null) return null; return info.getLine1NumberForSubscriber(subId, mContext.getOpPackageName()); } catch (RemoteException ex) { return null; } catch (NullPointerException ex) { // This could happen before phone restarts due to crashing return null; } }
//–frameworks/opt/telephony/src/java/com/android/internal/telephony/PhoneSubInfoController.java public String getLine1Number(String callingPackage) { return getLine1NumberForSubscriber(getDefaultSubscription(), callingPackage); } public String getLine1NumberForSubscriber(int subId, String callingPackage) { Phone phone = getPhone(subId); if (phone != null) { // This is open to apps with WRITE_SMS. if (!checkReadPhoneNumber(callingPackage, "getLine1Number")) { return null; } return phone.getLine1Number(); } else { loge("getLine1Number phone is null for Subscription:" + subId); return null; } }
//–frameworks/opt/telephony/src/java/com/android/internal/telephony/GsmCdmaPhone.java @Override public String getLine1Number() { d("getLine1Number " + isPhoneTypeGsm()); if (isPhoneTypeGsm()) { IccRecords r = mIccRecords.get(); return (r != null) ? r.getMsisdnNumber() : null; } else { return mSST.getMdnNumber(); } }
//–frameworks/opt/telephony/src/java/com/android/internal/telephony/uicc/SIMRecords.java //直接返回mMsisdn @Override public String getMsisdnNumber() { return mMsisdn; } //mMsisdn的赋值: @Override public void handleMessage(Message msg) { //... case EVENT_GET_MSISDN_DONE: isRecordLoadResponse = true; ar = (AsyncResult)msg.obj; if (ar.exception != null) { log("Invalid or missing EF[MSISDN]"); break; } adn = (AdnRecord)ar.result; mMsisdn = adn.getNumber(); mMsisdnTag = adn.getAlphaTag(); log("MSISDN: " + /*mMsisdn*/ Rlog.pii(LOG_TAG, mMsisdn)); break; //... }
请求
//–frameworks/opt/telephony/src/java/com/android/internal/telephony/uicc/SIMRecords.java
//发起获取SIM卡卡号请求: protected void fetchSimRecords() { d("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, getExtFromEf(EF_MSISDN), 1, obtainMessage(EVENT_GET_MSISDN_DONE)); }
//–frameworks/opt/telephony/src/java/com/android/internal/telephony/uicc/AdnRecordLoader.java
class AdnRecordLoader extends Handler /** * Resulting AdnRecord is placed in response.obj.result * or response.obj.exception is set */ public void loadFromEF(int ef, int extensionEF, int recordNumber, Message response) { mEf = ef; mExtensionEF = extensionEF; mRecordNumber = recordNumber; mUserResponse = response; mFh.loadEFLinearFixed( ef, getEFPath(ef), recordNumber, obtainMessage(EVENT_ADN_LOAD_DONE)); }
//–frameworks/opt/telephony/src/java/com/android/internal/telephony/uicc/IccFileHandler.java
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)); d("loadEFLinearFixed fileid(" + fileid + "), path(" + path + ")"); mCi.iccIOForApp(COMMAND_GET_RESPONSE, fileid, efPath, 0, 0, GET_RESPONSE_EF_SIZE_BYTES, null, null, mAid, response); }
//–frameworks/opt/telephony/src/java/com/android/internal/telephony/RIL.java
@Override public void iccIOForApp (int command, int fileid, String path, int p1, int p2, int p3, String data, String pin2, String aid, 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); rr.mParcel.writeInt(command); rr.mParcel.writeInt(fileid); rr.mParcel.writeString(path); rr.mParcel.writeInt(p1); rr.mParcel.writeInt(p2); rr.mParcel.writeInt(p3); rr.mParcel.writeString(data); rr.mParcel.writeString(pin2); rr.mParcel.writeString(aid); if (RILJ_LOGD) riljLog(rr.serialString() + "> iccIO: " + requestToString(rr.mRequest) + " 0x" + Integer.toHexString(command) + " 0x" + Integer.toHexString(fileid) + " " + " path: " + path + "," + p1 + "," + p2 + "," + p3 + " aid: " + aid); send(rr); }
发送的过程消息顺序: SIMRecords -> AdnRecordLoader -> IccFileHandler -> RIL
响应:
//–frameworks/opt/telephony/src/java/com/android/internal/telephony/RIL.java
private void processResponse (Parcel p) { int type; type = p.readInt(); if (type == RESPONSE_UNSOLICITED || type == RESPONSE_UNSOLICITED_ACK_EXP) { processUnsolicited (p, type); } else if (type == RESPONSE_SOLICITED || type == RESPONSE_SOLICITED_ACK_EXP) { RILRequest rr = processSolicited (p, type); if (rr != null) { if (type == RESPONSE_SOLICITED) { decrementWakeLock(rr); } rr.release(); return; } } else if (type == RESPONSE_SOLICITED_ACK) { int serial; serial = p.readInt(); RILRequest rr; synchronized (mRequestList) { rr = mRequestList.get(serial); } if (rr == null) { Rlog.w(RILJ_LOG_TAG, "Unexpected solicited ack response! sn: " + serial); } else { decrementWakeLock(rr); if (RILJ_LOGD) { riljLog(rr.serialString() + " Ack < " + requestToString(rr.mRequest)); } } } } private RILRequest processSolicited (Parcel p, int type) { // ... if (error == 0 || p.dataAvail() > 0) { // either command succeeds or command fails but with data payload try {switch (rr.mRequest) { // ... case RIL_REQUEST_SIM_IO: ret = responseICC_IO(p); break; } //... if (error == 0) { //IccIoResult ret. if (RILJ_LOGD) riljLog(rr.serialString() + "< " + requestToString(rr.mRequest) + " " + retToString(rr.mRequest, ret)); if (rr.mResult != null) { if(rr.mRequest == RIL_REQUEST_SIM_IO){ Rlog.d("RIL", "SIM_IO response send " + rr.mResult.what + "{" + ret.toString() + "}"); } AsyncResult.forMessage(rr.mResult, ret, null); rr.mResult.sendToTarget(); } } } private Object responseICC_IO(Parcel p) { int sw1, sw2; Message ret; sw1 = p.readInt(); sw2 = p.readInt(); String s = p.readString(); Rlog.d("RIL", "responseICC_IO 0x" + Integer.toHexString(sw1) + " 0x" + Integer.toHexString(sw2) + " " + s); if (true || RILJ_LOGV) riljLog("< iccIO: " + " 0x" + Integer.toHexString(sw1) + " 0x" + Integer.toHexString(sw2) + " " + s); return new IccIoResult(sw1, sw2, s); }
//–frameworks/opt/telephony/src/java/com/android/internal/telephony/uicc/IccFileHandler.java
@Override public void handleMessage(Message msg) { AsyncResult ar; IccIoResult result; Message response = null; String str; LoadLinearFixedContext lc; byte data[]; int size; int fileid; int recordSize[]; String path = null; try { switch (msg.what) case EVENT_GET_RECORD_SIZE_IMG_DONE: case EVENT_GET_RECORD_SIZE_DONE: ar = (AsyncResult)msg.obj; lc = (LoadLinearFixedContext) ar.userObj; result = (IccIoResult) ar.result; response = lc.mOnLoaded; if (processException(response, (AsyncResult) msg.obj)) { break; } data = result.payload; path = lc.mPath; if (TYPE_EF != data[RESPONSE_DATA_FILE_TYPE]) { throw new IccFileTypeMismatch(); } if (EF_TYPE_LINEAR_FIXED != data[RESPONSE_DATA_STRUCTURE]) { throw new IccFileTypeMismatch(); } 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)); break; }
//–frameworks/opt/telephony/src/java/com/android/internal/telephony/uicc/AdnRecordLoader.java
void handleMessage(){ case EVENT_ADN_LOAD_DONE: ar = (AsyncResult)(msg.obj); data = (byte[])(ar.result); if (ar.exception != null) { throw new RuntimeException("load failed", ar.exception); } if (VDBG) { Rlog.d(LOG_TAG,"ADN EF: 0x" + Integer.toHexString(mEf) + ":" + mRecordNumber + "\n" + IccUtils.bytesToHexString(data)); } adn = new AdnRecord(mEf, mRecordNumber, data); mResult = adn; if (adn.hasExtendedRecord()) { // If we have a valid value in the ext record field, // we're not done yet: we need to read the corresponding // ext record and append it mPendingExtLoads = 1; mFh.loadEFLinearFixed( mExtensionEF, adn.mExtRecord, obtainMessage(EVENT_EXT_RECORD_LOAD_DONE, adn)); } break; }
处理响应的顺序: RIL -> IccFileHandler -> AdnRecordLoader -> SIMRecords
测试过程LOG整理
// RIL.java reference-ril.so iccIOForApp 0xc0, 0x2fe2 requestSIM_IO 0x2fe2, 0, 0, 15 iccIOForApp 0xc0, 0x6f40 requestSIM_IO 0x6f40, 0, 0, 15 iccIOForApp 0xc0, 0x6fc9 requestSIM_IO 0x6fc9, 0, 0, 15 iccIOForApp 0xc0, 0x6fad requestSIM_IO 0x6fad, 0, 0, 15 iccIOForApp 0xc0, 0x6fca requestSIM_IO 0x6fca, 0, 0, 15 iccIOForApp 0xc0, 0x6f11 requestSIM_IO 0x6f11, 0, 0, 15 iccIOForApp 0xc0, 0x6fcb requestSIM_IO 0x6fcb, 0, 0, 15 iccIOForApp 0xc0, 0x6f13 requestSIM_IO 0x6f13, 0, 0, 15 iccIOForApp 0xc0, 0x6f46 requestSIM_IO 0x6f46, 0, 0, 15 iccIOForApp 0xc0, 0x6fcd requestSIM_IO 0x6fcd, 0, 0, 15 iccIOForApp 0xc0, 0x6fc5 requestSIM_IO 0x6fc5, 0, 0, 15 iccIOForApp 0xc0, 0x6f38 requestSIM_IO 0x6f38, 0, 0, 15 iccIOForApp 0xc0, 0x6f16 requestSIM_IO 0x6f16, 0, 0, 15 iccIOForApp 0xc0, 0x6f15 requestSIM_IO 0x6f15, 0, 0, 15 iccIOForApp 0xc0, 0x6f3e requestSIM_IO 0x6f3e, 0, 0, 15 iccIOForApp 0xc0, 0x6f3f requestSIM_IO 0x6f3f, 0, 0, 15 iccIOForApp 0xc0, 0x6f60 requestSIM_IO 0x6f60, 0, 0, 15 iccIOForApp 0xc0, 0x6f61 requestSIM_IO 0x6f61, 0, 0, 15 iccIOForApp 0xc0, 0x6f62 requestSIM_IO 0x6f62, 0, 0, 15 iccIOForApp 0xc0, 0x6fd9 requestSIM_IO 0x6fd9, 0, 0, 15 iccIOForApp 0xc0, 0x6f7b requestSIM_IO 0x6f7b, 0, 0, 15 iccIOForApp 0xb0, 0x2fe2 requestSIM_IO 0x2fe2, 0, 0, 10 iccIOForApp 0xb2, 0x6f40 requestSIM_IO 0x6f40, 1, 4, 28 iccIOForApp 0xb0, 0x6fad requestSIM_IO 0x6fad, 0, 0, 4 iccIOForApp 0xc0, 0x6f17 requestSIM_IO 0x6f17, 0, 0, 15 iccIOForApp 0xb2, 0x6fcb requestSIM_IO 0x6fcb, 1, 4, 16 iccIOForApp 0xb0, 0x6f46 requestSIM_IO 0x6f46, 0, 0, 17 iccIOForApp 0xb0, 0x6f38 requestSIM_IO 0x6f38, 0, 0, 11 iccIOForApp 0xb0, 0x6f60 requestSIM_IO 0x6f60, 0, 0, 40 iccIOForApp 0xb0, 0x6f61 requestSIM_IO 0x6f61, 0, 0, 3500 iccIOForApp 0xb0, 0x6f62 requestSIM_IO 0x6f62, 0, 0, 10 iccIOForApp 0xb0, 0x6fd9 requestSIM_IO 0x6fd9, 0, 0, 12 iccIOForApp 0xb0, 0x6f7b requestSIM_IO 0x6f7b, 0, 0, 60 RIL : responseICC_IO 0x90 0x0 0000000a2fe2040000000000000000 RIL : responseICC_IO 0x90 0x0 000000386f4004000000000000011c RIL : responseICC_IO 0x90 0x0 000000046fad040000000000000000 RIL : responseICC_IO 0x6a 0x82 null RIL : responseICC_IO 0x90 0x0 000000106fcb040000000000000110 RIL : responseICC_IO 0x6a 0x82 null RIL : responseICC_IO 0x90 0x0 000000116f46040000000000000000 RIL : responseICC_IO 0x90 0x0 0000000b6f38040000000000000000 RIL : responseICC_IO 0x6a 0x82 null RIL : responseICC_IO 0x6a 0x82 null RIL : responseICC_IO 0x90 0x0 000000286f60040000000000000000 RIL : responseICC_IO 0x90 0x0 00000dac6f61040000000000000000 RIL : responseICC_IO 0x90 0x0 0000000a6f62040000000000000000 RIL : responseICC_IO 0x90 0x0 0000000c6fd9040000000000000000 RIL : responseICC_IO 0x90 0x0 0000003c6f7b040000000000000000 RIL : responseICC_IO 0x90 0x0 98683061691572783521 RIL : responseICC_IO 0x90 0x0 ffffffffffffffffffffffffffff0891688116325476f8ffffffffff RIL : responseICC_IO 0x90 0x0 00000002 RIL : responseICC_IO 0x6a 0x82 null RIL : responseICC_IO 0x90 0x0 00000000000000000000000000000000 RIL : responseICC_IO 0x90 0x0 01804E2D56FD75354FE1FFFFFFFFFFFFFF RIL : responseICC_IO 0x90 0x0 802F1C2C230E0100C00050 RIL : responseICC_IO 0x90 0x0 FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF RIL : responseICC_IO 0x90 0x0 54F430C08054F440008054F491C08054F460C08025F040C08025F099808025F000808025F030800025F0100080130014C080130062C080130073C0801300744080130041808044F001C00044F002800064F629C08064F679808064F639008064F699008005F530C08005F501008005F510C08054F080C00054F050C00062F220C08062F210C08025F550408025F510408002F801C08002F802C08015F001C08015F0108080030216C0000302 RIL : responseICC_IO 0x90 0x0 FFFFFFFFFFFFFFFFFFFF RIL : responseICC_IO 0x90 0x0 64F01164F030FFFFFFFFFFFF RIL : responseICC_IO 0x90 0x0 64F00064F01064F02064F06064F07064F002FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF IccFileHandler: handleMessage what=4 IccFileHandler: handleMessage what=6 IccFileHandler: handleMessage what=6 IccFileHandler: handleMessage what=4 IccFileHandler: handleMessage what=6 IccFileHandler: handleMessage what=4 IccFileHandler: handleMessage what=6 IccFileHandler: handleMessage what=4 IccFileHandler: handleMessage what=4 IccFileHandler: handleMessage what=4 IccFileHandler: handleMessage what=6 IccFileHandler: handleMessage what=4 IccFileHandler: handleMessage what=4 IccFileHandler: handleMessage what=4 IccFileHandler: handleMessage what=4 IccFileHandler: handleMessage what=4 IccFileHandler: handleMessage what=4 IccFileHandler: handleMessage what=4 IccFileHandler: handleMessage what=4 IccFileHandler: handleMessage what=4 IccFileHandler: handleMessage what=4 IccFileHandler: handleMessage what=5 IccFileHandler: handleMessage what=7 IccFileHandler: handleMessage what=5 IccFileHandler: handleMessage what=6 IccFileHandler: handleMessage what=7 IccFileHandler: handleMessage what=5 IccFileHandler: handleMessage what=5 IccFileHandler: handleMessage what=5 IccFileHandler: handleMessage what=5 IccFileHandler: handleMessage what=5 IccFileHandler: handleMessage what=5 IccFileHandler: handleMessage what=5 IccFileHandler: loadEFLinearFixed fileid(28439), path(null) RIL : SIM_IO response send 4{IccIoResult sw1:0x90 sw2:0x0,0000000a2fe2040000000000000000} RIL : SIM_IO response send 6{IccIoResult sw1:0x90 sw2:0x0,000000386f4004000000000000011c} RIL : SIM_IO response send 4{IccIoResult sw1:0x90 sw2:0x0,000000046fad040000000000000000} RIL : SIM_IO response send 4{IccIoResult sw1:0x6a sw2:0x82 Error: File not found} RIL : SIM_IO response send 6{IccIoResult sw1:0x90 sw2:0x0,000000106fcb040000000000000110} RIL : SIM_IO response send 4{IccIoResult sw1:0x6a sw2:0x82 Error: File not found} RIL : SIM_IO response send 4{IccIoResult sw1:0x90 sw2:0x0,000000116f46040000000000000000} RIL : SIM_IO response send 4{IccIoResult sw1:0x90 sw2:0x0,0000000b6f38040000000000000000} RIL : SIM_IO response send 4{IccIoResult sw1:0x6a sw2:0x82 Error: File not found} RIL : SIM_IO response send 4{IccIoResult sw1:0x6a sw2:0x82 Error: File not found} RIL : SIM_IO response send 4{IccIoResult sw1:0x90 sw2:0x0,000000286f60040000000000000000} RIL : SIM_IO response send 4{IccIoResult sw1:0x90 sw2:0x0,00000dac6f61040000000000000000} RIL : SIM_IO response send 4{IccIoResult sw1:0x90 sw2:0x0,0000000a6f62040000000000000000} RIL : SIM_IO response send 4{IccIoResult sw1:0x90 sw2:0x0,0000000c6fd9040000000000000000} RIL : SIM_IO response send 4{IccIoResult sw1:0x90 sw2:0x0,0000003c6f7b040000000000000000} RIL : SIM_IO response send 5{IccIoResult sw1:0x90 sw2:0x0,98683061691572783521} RIL : SIM_IO response send 7{IccIoResult sw1:0x90 sw2:0x0ffffffffffffffffffffffffffff0891688116325476f8ffffffffff} RIL : SIM_IO response send 5{IccIoResult sw1:0x90 sw2:0x0,00000002} RIL : SIM_IO response send 6{IccIoResult sw1:0x6a sw2:0x82 Error: File not found} RIL : SIM_IO response send 7{IccIoResult sw1:0x90 sw2:0x0,00000000000000000000000000000000} RIL : SIM_IO response send 5{IccIoResult sw1:0x90 sw2:0x0,01804e2d56fd75354fe1ffffffffffffff} RIL : SIM_IO response send 5{IccIoResult sw1:0x90 sw2:0x0,802f1c2c230e0100c00050} RIL : SIM_IO response send 5{IccIoResult sw1:0x90 sw2:0x0,ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff} RIL : SIM_IO response send 5{IccIoResult sw1:0x90 sw2:0x0,54f430c08054f440008054f491c08054f460c08025f040c08025f099808025f000808025f030800025f0100080130014c080130062c080130073c0801300744080130041808044f001c00044f002800064f629c08064f679808064f639008064f699008005f530c08005f501008005f510c08054f080c00054f050c00062f220c08062f210c08025f550408025f510408002f801c08002f802c08015f001c08015f0108080030216c0000302} RIL : SIM_IO response send 5{IccIoResult sw1:0x90 sw2:0x0,ffffffffffffffffffff} RIL : SIM_IO response send 5{IccIoResult sw1:0x90 sw2:0x0,64f01164f030ffffffffffff} RIL : SIM_IO response send 5{IccIoResult sw1:0x90 sw2:0x0,64f00064f01064f02064f06064f07064f002ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff} RILC : respose SIM_IO number[18612345678], 11 RILC : respose SIM_IO [18612345678]:[ffffffffffffffffffffffffffff0891688116325476f8ffffffffff] AdnRecordLoader: handleMessage what=1 AdnRecordLoader: handleMessage what=10x6f40:1[ffffffffffffffffffffffffffff0891688116325476f8ffffffffff] AdnRecord: parseRecord len(28), footerOffset(14), numberLength(8) AdnRecordLoader: handleMessage what=1 SIMRecords: SIMRecords EVENT_GET_MSISDN_DONE
结语
以上代码及相关逻辑并非通用, RIL本身存在一定的复杂性, 具体情况需具体分析.
仅供参考