关注微信公众号:程序员小安,精彩文章按期推送。android
获取IMEI相信你们很是熟悉,可是项目中使用时,发现当手机卡为电信的时候,获取的并非IMEI,而是MEID,什么是MEID,为何会出现这种状况呢? IMEI国际移动设备识别码(IMEI:International Mobile Equipment Identification Number)是区别移动设备的标志,储存在移动设备中,可用于监控被窃或无效的移动设备。目前GSM和WCDMA手机终端须要使用IMEI号码 MEID移动设备识别码(Mobile Equipment Identifier)是CDMA手机的身份识别码,也是每台手机有惟一的识别码。经过这个识别码,网络端能够对该手机进行跟踪和监管。用于CDMA制式的手机。MEID的数字范围是十六进制的,和IMEI的格式相似。程序员
为何会出现获取的不是IMEI,而是MEID呢,继续往下看。 通常状况下,你们获取imei号,经过如下两个步骤实现。 1)添加读取权限:bash
<uses-permission android:name="android.permission.READ_PHONE_STATE" /> 复制代码
2)获取设备imei号微信
public static String getImei(Context context) { TelephonyManager telephonyMgr = (TelephonyManager) context.getSystemService(TELEPHONY_SERVICE); String imei = telephonyMgr.getDeviceId(); return imei ; } 复制代码
很明显,经过调用getDeviceId()但愿获取IMEI,可是获得的倒是MEID,定位到getDeviceId()的源码,以下:markdown
/** * 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. * * <p>Requires Permission: * {@link android.Manifest.permission#READ_PHONE_STATE READ_PHONE_STATE} */ public String getDeviceId() { try { ITelephony telephony = getITelephony(); if (telephony == null) return null; return telephony.getDeviceId(mContext.getOpPackageName()); } catch (RemoteException ex) { return null; } catch (NullPointerException ex) { return null; } } 复制代码
注释很明显了,CDMA手机返回的是MEID或者ESN,也就是电信卡返回的是MEID,到这里咱们发现了问题所在,那么如何解决呢,浏览源码,咱们发现,有个隐藏的(hide)方法,以下:网络
/** * Returns the IMEI. Return null if IMEI is not available. * * <p>Requires Permission: * {@link android.Manifest.permission#READ_PHONE_STATE READ_PHONE_STATE} */ /** {@hide} */ public String getImei() { return getImei(getDefaultSim()); } 复制代码
这个方法能够获取IMEI,可是因为是hide方法,不能直接调用,因此咱们只能经过反射调用该方法。ide
代码很简单,以下所示:学习
public static String getMachineImei(Context context) { TelephonyManager manager = (TelephonyManager) context.getSystemService(TELEPHONY_SERVICE); Class clazz = manager.getClass(); String imei = ""; try { Method getImei=clazz.getDeclaredMethod("getImei",int.class);//(int slotId) getImei.setAccessible(true); imei = (String) getImei.invoke(manager); } catch (Exception e) { } return imei; } 复制代码
经过上述反射调用getImei(),则能够在电信卡手机成功获取IMEI号,当前前提是存在IMEI号。ui
若有错误欢迎指出来,一块儿学习。 spa