为什么方法SimCardInfo.getImsi在真机下会报错

2025-04-09 04:07:31
推荐回答(1个)
回答1:

  手机使用IMEI和IMSI登录到GSM中国络的,由GSM中国络侧负责将IMSI和映射成手机号(MSISDN),以及执行相反方向的映射。   (一)、SIM card 号的修改:   SIM card号就是印制在SIM上的一串数字。   读SIM card号的AT命令为:AT+CRSM=176,12258,0,0,10   因此在andorid模拟其源码中找到该AT命令——在sim_card.c中:   const char*   asimcard_io( ASimCard sim, const char* cmd )   {   int nn;   #if ENABLE_DYNAMIC_RECORDS   int 中国mand, id, p1, p2, p3;   #endif   static const struct { const char* cmd; const char* answer; } answers[] =   {   { "+CRSM=192,28436,0,0,15", "+CRSM: 144,0,000000146f1404001aa0aa01020000" },   { "+CRSM=176,28436,0,0,20", "+CRSM: 144,0,416e64726f6964ffffffffffffffffffffffffff" },   { "+CRSM=192,28433,0,0,15", "+CRSM: 144,0,000000016f11040011a0aa01020000" },   { "+CRSM=176,28433,0,0,1", "+CRSM: 144,0,55" },   { "+CRSM=192,12258,0,0,15", "+CRSM: 144,0,0000000a2fe204000fa0aa01020000" },   { "+CRSM=176,12258,0,0,10", "+CRSM: 144,0,98101430121181157002" },   ...   ...   因此用UE二进制方式打开emulator-arm.exe 或 emulator-x86.exe,并搜索字符串“98101430121181157002”,然后将其修改成需要的SIM card号。   比如:   00209a00h: 31 30 00 00 2B 43 52 53 4D 3A 20 31 34 34 2C 30 ; 10..+CRSM: 144,0   00209a10h: 2C 39 38 31 30 31 34 33 30 31 32 31 31 38 31 31 ; ,981014301211811   00209a20h: 35 37 30 30 32 00 2B 43 52 53 4D 3D 31 39 32 2C ; 57002.+CRSM=192,   (二)、IMEI、IMSI号的修改:   Java代码中获取手机的IMEI号与ISMI号途径为:   TelephonyManager manager = (TelephonyManager)getSystemService(TELEPHONY_SERVICE);   String imei = manager.getDeviceId();   String imsi = manager.getSubscriberId();   在android的源码树中找到类TelephonyManager的实现:   成员函数getDeviceId:   /**   * Returns the unique device ID, for example, the IMEI for GSM and the MEID   * or ESN for CDMA phones. Return null if device ID is not available.   *   * Requires Permission:   * {@link android.Manifest.permission#READ_PHONE_STATE READ_PHONE_STATE}   */   public String getDeviceId() {   try {   return getSubscriberInfo().getDeviceId();   } catch (RemoteException ex) {   return null;   } catch (NullPointerException ex) {   return null;   }   }   成员函数getSubscriberId:   /**   * Returns the unique subscriber ID, for example, the IMSI for a GSM phone.   * Return null if it is unavailable.   *   * Requires Permission:   * {@link android.Manifest.permission#READ_PHONE_STATE READ_PHONE_STATE}   */   public String getSubscriberId() {   try {   return getSubscriberInfo().getSubscriberId();   } catch (RemoteException ex) {   return null;   } catch (NullPointerException ex) {   // This could happen before phone restarts due to crashing   return null;   }   }   上面两个成员函数最终调用共同的一个私有成员函数getSubscriberInfo():   private IPhoneSubInfo getSubscriberInfo() {   // get it each time because that process crashes a lot   return IPhoneSubInfo.Stub.asInterface(ServiceManager.getService("iphonesubinfo"));   }   而上面私有函数getSubscriberInfo获取的手机IMSI和IMEI号被硬编码在文件android_modem.c中:   /* the Android GSM stack checks that the operator's name has changed   * when roaming is on. If not, it will not update the Roaming status icon   *   * this means that we need to emulate two distinct operators:   * - the first one for the 'home' registration state, must also correspond   * to the emulated user's IMEI   *   * - the second one for the 'roaming' registration state, must have a   * different name and MCC/MNC   */   #define OPERATOR_HOME_INDEX 0   #define OPERATOR_HOME_MCC 310   #define OPERATOR_HOME_MNC 260   #define OPERATOR_HOME_NAME "Android"   #define OPERATOR_HOME_MCCMNC STRINGIFY(OPERATOR_HOME_MCC) \   STRINGIFY(OPERATOR_HOME_MNC)   #define OPERATOR_ROAMING_INDEX 1   #define OPERATOR_ROAMING_MCC 310   #define OPERATOR_ROAMING_MNC 295   #define OPERATOR_ROAMING_NAME "TelKila"   #define OPERATOR_ROAMING_MCCMNC STRINGIFY(OPERATOR_ROAMING_MCC) \   STRINGIFY(OPERATOR_ROAMING_MNC)   /* a function used to deal with a non-trivial request */   typedef const char* (*ResponseHandler)(const char* cmd, AModem modem);   static const struct {   const char* cmd; /* 中国mand 中国ing from libreference-ril.so, if first   character is '!', then the rest is a prefix only */   const char* answer; /* default answer, NULL if needs specific handling or   if OK is good enough */   ResponseHandler handler; /* specific handler, ignored if 'answer' is not NULL,   NULL if OK is good enough */   } sDefaultResponses[] =   {   /* see onRadioPowerOn() */   { "%CPHS=1", NULL, NULL },   { "%CTZV=1", NULL, NULL },   ...      { "!+VTS=", NULL, handleSetDialTone },   { "+CIMI", OPERATOR_HOME_MCCMNC "000000000", NULL }, /* request internation subscriber identification number */   { "+CGSN", "000000000000000", NULL }, /* request model version */   { "+CUSD=2",NULL, NULL }, /* Cancel USSD */   ...   /* end of list */   {NULL, NULL, NULL}   };   因此用UE二进制方式打开emulator-arm.exe 或 emulator-x86.exe,并搜索字符串"+CGSN"修改为需要的IMEI号;搜索"+CIMI"修改为需要的IMSI号。需要注意的是 IMSI 号的头六个数字"310260"不能修改,否则模拟器无法与中国络连接。   例如:   001fc700h: 33 00 41 00 48 00 21 2B 56 54 53 3D 00 2B 43 49 ; 3.A.H.!+VTS=.+CI   001fc710h: 4D 49 00 33 31 30 32 36 30 30 30 30 30 30 30 30 ; MI.3102600000000   001fc720h: 30 30 00 2B 43 47 53 4E 00 30 30 30 30 30 30 30 ; 00.+CGSN.0000000   001fc730h: 30 30 30 30 30 30 30 30 00 2B 43 55 53 44 3D 32 ; 00000000.+CUSD=2