Android 获取 IMSI、IMEI

龙永逸
2023-12-01

目录


IMSI

IMSI (IMSI:International Mobile Subscriber Identification Number) 国际移动用户识别码。
IMSI 由 MCC + MNC + MSIN组成。
MCC(Mobile Country Code)是手机号码所属国家的代号,占3位,中国是460。
MNC (Mobile Network Code,移动网络号码):用于识别移动用户所归属的移动通信网,2~3位,用来区分运营商。
MSIN (Mobile Subscriber Identification Number,移动用户识别号码):用以识别某一移动通信网中的移动用户。


MCC 第一个代码指地理区域

编码区域
0测试网络
2欧洲
3北美和加勒比地区
4亚洲和中东
5大洋洲
6非洲
7南美和中美洲
9全球(卫星,空中飞机,海上船舶,南极洲)


国内的运营商使用如下:

运营商名称MCC编号MNC 编号
移动46000、02、04、07、08
联通46001、06、09
电信46003、05、11
铁通46020
移动白卡00101
电信白卡46099



IMEI

IMEI(International Mobile Equipment Identity)是国际移动设备识别码的缩写。俗称“手机串号”、“手机串码”、“手机序列号”,用于在GSM移动网络中识别每一部独立的手机,相当于手机的身份证号码。

双卡双待手机会有两个IMEI,IMEI和IMSI存在一一对应的关系。因为双卡双待手机两个卡槽都能插SIM卡,在GSM蜂窝通信网络中被看作是集成在一起的两个设备,所以会被分配有2个IMEI码。

IMEI由15位数字组成,其组成为:
1、前6位数(TAC,Type Approval Code)是”型号核准号码”,一般代表机型。
2、接着的2位数(FAC,Final Assembly Code)是”最后装配号”,一般代表产地。
3、之后的6位数(SNR)是”串号”,一般代表生产顺序号。
4、最后1位数(SP)通常是”0”,为检验码,目前暂备用。



Andoid 获取 IMSI/IMEI 代码

/**
 * 反射获取 getSubscriberId ,既imsi
 *
 * @param subId
 * @return
 */
 public static String getSubscriberId(int subId) {
     TelephonyManager telephonyManager = (TelephonyManager) App.getInstance().getSystemService(TELEPHONY_SERVICE);// 取得相关系统服务
     Class<?> telephonyManagerClass = null;
     String imsi = null;
     try {
         telephonyManagerClass = Class.forName("android.telephony.TelephonyManager");

         if (android.os.Build.VERSION.SDK_INT > android.os.Build.VERSION_CODES.LOLLIPOP) {
             Method method = telephonyManagerClass.getMethod("getSubscriberId", int.class);
             imsi = (String) method.invoke(telephonyManager, subId);
         } else if (android.os.Build.VERSION.SDK_INT == android.os.Build.VERSION_CODES.LOLLIPOP) {
             Method method = telephonyManagerClass.getMethod("getSubscriberId", long.class);
             imsi = (String) method.invoke(telephonyManager, (long) subId);
         }
     } catch (Exception e) {
         e.printStackTrace();
     }

     Log.i(App.TAG, "IMSI==" + imsi);
     return imsi;
 }

 /**
  * 反射获取 getSubscriptionId ,既 subid
  *
  * @param slotId 卡槽位置(0,1)
  * @return
  */
 public static int getSubscriptionId(int slotId) {
     try {
         Method datamethod;
         int setsubid = -1;//定义要设置为默认数据网络的subid
         //获取默认数据网络subid   getDefaultDataSubId
         Class<?> SubscriptionManager = Class.forName("android.telephony.SubscriptionManager");
         if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.N) { // >= 24  7.0
             datamethod = SubscriptionManager.getDeclaredMethod("getDefaultDataSubscriptionId"); 
         } else {
             datamethod = SubscriptionManager.getDeclaredMethod("getDefaultDataSubId");  
         }
         datamethod.setAccessible(true);
         int SubId = (int) datamethod.invoke(SubscriptionManager);


         Method subManagermethod = SubscriptionManager.getDeclaredMethod("from", Context.class);
         subManagermethod.setAccessible(true);
         Object subManager = subManagermethod.invoke(SubscriptionManager, App.getInstance());

         //getActiveSubscriptionInfoForSimSlotIndex  //获取卡槽0或者卡槽1  可用的subid
         Method getActivemethod = SubscriptionManager.getDeclaredMethod("getActiveSubscriptionInfoForSimSlotIndex", int.class);
         getActivemethod.setAccessible(true);
         Object msubInfo = getActivemethod.invoke(subManager, slotId);  //getSubscriptionId

         Class<?> SubInfo = Class.forName("android.telephony.SubscriptionInfo");

         //slot0   获取卡槽0的subid
         int subid = -1;
         if (msubInfo != null) {
             Method getSubId0 = SubInfo.getMethod("getSubscriptionId");
             getSubId0.setAccessible(true);
             subid = (int) getSubId0.invoke(msubInfo);
         }
         Log.i(App.TAG, "slotId=" + slotId + ", subid=" + subid);
         return subid;
     } catch (Exception e) {
         Log.e(App.TAG, e.getLocalizedMessage());
     }
     return -1;
 }

 /**
  * 获取运营商 IMSI
  * 默认为 IMEI1对应的 IMSI
  *
  * @return
  */
 public static String getSimOperator() {
     TelephonyManager telephonyManager = (TelephonyManager) App.getInstance().getSystemService(TELEPHONY_SERVICE);// 取得相关系统服务
     return telephonyManager.getSimOperator();
 }

 /**
  * 根据卡槽位置 获取运营商 IMSI
  *
  * @param slotId 卡槽位置(0,1)
  * @return
  */
 public static String getSimOperator(int slotId) {
     int subid = getSubscriptionId(slotId);
     if (subid == -1) {
         return null;
     }

     String imsi = getSubscriberId(subid);
     if (!TextUtils.isEmpty(imsi)) {
         return imsi;
     }

     return null;
 }

/**
 * 通过卡槽位置拿 IMEI
 *
 * @param slotId (0, 1卡槽位置)
 * @return
 */
public static String getImei(int slotId) {
    if (slotId != 0 && slotId != 1) {
        return null;
    }

    TelephonyManager tm = (TelephonyManager) App.getInstance().getSystemService(TELEPHONY_SERVICE);
    if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.M) {
        return tm.getDeviceId(slotId);

    } else if (slotId == 0){
        return tm.getDeviceId();

    } else {
        TelephonyManager telephonyManager = (TelephonyManager) App.getInstance().getSystemService(TELEPHONY_SERVICE);// 取得相关系统服务
        Class<?> telephonyManagerClass = null;
        String imei = null;

        try {
            telephonyManagerClass = Class.forName("android.telephony.TelephonyManager");
            Method method = telephonyManagerClass.getMethod("getImei", int.class);
            imei = (String) method.invoke(telephonyManager, slotId);
        } catch (Exception e) {
            e.printStackTrace();
        }

        Log.i(App.TAG, "imei==" + imei);

        return imei;
    }
}

参看链接:
https://baike.so.com/doc/5456486-5694874.html
https://www.jianshu.com/p/da5942fe78d6


END

 类似资料: