Android 获取 IMSI、IMEI
目录
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