首页 > 编程知识 正文

手机卡iccid码怎么查,超雪卡贴最新iccid

时间:2023-05-05 06:52:57 阅读:248874 作者:4853

1、在Android中我们可以通过下面这段代码获取SIM的iccid,关于手机中常用术语简介可参考《Android中CS域和PS域以及手机中常用术语简介》

TelephonyManager telephonyManager = (TelephonyManager) getSystemService(TELEPHONY_SERVICE); String simSerialNumber = telephonyManager.getSimSerialNumber();

注:ICCID (Integrate circuit card identity ) 集成电路卡识别码(固化在手机SIM 卡中) ICCID 为IC 卡的唯一识别号码,共有20 位数字组成。

但调用这个方法有时候并不能获取到20位完整的SIM iccid,怀着好奇心看了下android源码,下面就来一层层揭开这面纱。

frameworks/base/telephony/java/android/telephony/TelephonyManager.java public String getSimSerialNumber(int subId) { android.util.SeempLog.record_str(388, ""+subId); try { IPhoneSubInfo info = getSubscriberInfo(); if (info == null) return null; return info.getIccSerialNumberForSubscriber(subId, mContext.getOpPackageName()); } catch (RemoteException ex) { return null; } catch (NullPointerException ex) { // This could happen before phone restarts due to crashing return null; } }

getIccSerialNumberForSubscriber是在PhoneSubInfoController.java中实现,具体方式如下:

frameworks/opt/telephony/src/java/com/android/internal/telephony/PhoneSubInfoController.java public String getIccSerialNumberForSubscriber(int subId, String callingPackage) { Phone phone = getPhone(subId); if (phone != null) { if (!checkReadPhoneState(callingPackage, "getIccSerialNumber")) { return null; } return phone.getIccSerialNumber(); } else { loge("getIccSerialNumber phone is null for Subscription:" + subId); return null; } }

getIccSerialNumber是在GsmCdmaPhone.java实现:

frameworks/opt/telephony/src/java/com/android/internal/telephony/GsmCdmaPhone.java @Override public String getIccSerialNumber() { IccRecords r = mIccRecords.get(); if (!isPhoneTypeGsm() && r == null) { // to get ICCID form SIMRecords because it is on MF. r = mUiccController.getIccRecords(mPhoneId, UiccController.APP_FAM_3GPP); } return (r != null) ? r.getIccId() : null; }

getIccId是IccRecords.java中定义的,但其赋值是在IccRecords的两个子类SIMRecords.java和RuimRecords.java中赋值的

frameworks/opt/telephony/src/java/com/android/internal/telephony/uicc/SIMRecords.java // ***** Overridden from Handler @Override public void handleMessage(Message msg) { AsyncResult ar; AdnRecord adn; byte data[]; boolean isRecordLoadResponse = false; if (mDestroyed.get()) { loge("Received message " + msg + "[" + msg.what + "] " + " while being destroyed. Ignoring."); return; } try { switch (msg.what) { case EVENT_GET_ICCID_DONE: isRecordLoadResponse = true; ar = (AsyncResult)msg.obj; data = (byte[])ar.result; if (ar.exception != null) { break; } mIccId = IccUtils.bcdToString(data, 0, data.length); mFullIccId = IccUtils.bchToString(data, 0, data.length); log("iccid: " + SubscriptionInfo.givePrintableIccid(mFullIccId)); break; ... default: super.handleMessage(msg); // IccRecords handles generic record load responses }}catch (RuntimeException exc) { // I don't want these exceptions to be fatal logw("Exception parsing SIM record", exc); } finally { // Count up record load responses even if they are fails if (isRecordLoadResponse) { onRecordLoaded(); } } }

EVENT_GET_ICCID_DONE是在IccFileHandler.java@loadEFTransparent里调用

public void loadEFTransparent(int fileid, Message onLoaded) { Message response = obtainMessage(EVENT_GET_BINARY_SIZE_DONE, fileid, 0, onLoaded); mCi.iccIOForApp(COMMAND_GET_RESPONSE, fileid, getEFPath(fileid), 0, 0, GET_RESPONSE_EF_SIZE_BYTES, null, null, mAid, response); }

这里会调用RIL.java里的iccIOForApp向modem发送查询请求,有结果返回后便会调用EVENT_GET_ICCID_DONE对mIccId进行赋值

frameworks/opt/telephony/src/java/com/android/internal/telephony/uicc/IccUtils.java public static String bcdToString(byte[] data, int offset, int length) { StringBuilder ret = new StringBuilder(length*2); for (int i = offset ; i < offset + length ; i++) { int v; v = data[i] & 0xf; if (v > 9) break; ret.append((char)('0' + v)); v = (data[i] >> 4) & 0xf; // Some PLMNs have 'f' as high nibble, ignore it if (v == 0xf) continue; if (v > 9) break; ret.append((char)('0' + v)); } return ret.toString(); }

可以看到在bcdToString时,如果data里面包含非0-9的字符,就只取第一个非0-9的字段
eg:8986011785a113040534 ,按照这个方法获取的为8986011785

当然在GsmCdmaPhone@getFullIccSerialNumber,这个方法在调用的时候,只是调用了IccUtils.bchToString

/** * Some fields (like ICC ID) in GSM SIMs are stored as nibble-swizzled BCH */ public static String bchToString(byte[] data, int offset, int length) { StringBuilder ret = new StringBuilder(length*2); for (int i = offset ; i < offset + length ; i++) { int v; v = data[i] & 0xf; ret.append("0123456789abcdef".charAt(v)); v = (data[i] >> 4) & 0xf; ret.append("0123456789abcdef".charAt(v)); } return ret.toString(); }

此时获取到的iccid才是完整的,然而现在很多sim卡的iccid包含0-f之外的字符,还是不能取到完整的iccid,如果你有好的方案,欢迎留言指教,谢谢!
eg:8986011785N113040534,不能获取到正确完整的20位iccid

版权声明:该文观点仅代表作者本人。处理文章:请发送邮件至 三1五14八八95#扣扣.com 举报,一经查实,本站将立刻删除。