欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

Android 获取 IMSI、IMEI

程序员文章站 2024-02-10 23:48:58
...

目录


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 编号
移动 460 00、02、04、07、08
联通 460 01、06、09
电信 460 03、05、11
铁通 460 20
移动白卡 001 01
电信白卡 460 99



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

相关标签: android imei imsi