Android 各个版本获取IMEI、MEID 您所在的位置:网站首页 imei1和imei2相同 Android 各个版本获取IMEI、MEID

Android 各个版本获取IMEI、MEID

2023-11-04 01:58| 来源: 网络整理| 查看: 265

MEID/IMEI1/IMEI2 (可通过在手机拨号键盘中输入 *#06# 即可查询)

IMEI:(International Mobile Equipment Identity)国际移动设备身份码的缩写,由15~17(中国基本都15)位数字组成的电子串号与每台手机一一对应,且该码全世界唯一。

MEID:(Mobile Equipment Identifier)移动设备识别码,是CDMA手机的身份识别码,也是每台CDMA手机或通讯平板唯一的识别码,由14位数字组成。

在中国 移动卡和联通卡使用的是GSM制式 即使用IMEI , 电信卡使用CDMA制式 即使用MEID

Android个版本获取MEID/IMEI情况 版本 版本 = 5.x 的系统如果想获取MEID/IMEI1/IMEI2 ----framework层提供了两个属性值“ril.cdma.meid"和“ril.gsm.imei"获取meid、imei1、imei2(必须使用反射方法) 也可以用getDeviceId()获取 6.0 >= 版本 8.0 版本 >= 10 系统API限制,无法获取到imei/meid 以上方法均无效

注意: getDeviceId(): 能获取到imei 或 meid ,会根据插得卡返回对应值,不插卡或插移动联通卡默认返回imei 插电信卡则返回meid getMeid():8.0及以后调用 返回meid getImei():8.0及以后调用 返回imei

工具类 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303 public class IMEIUtil {     /**      * 获取默认的imei  一般都是IMEI 1      *      * @param context      * @return      */     public static String getIMEI1(Context context) {         //优先获取IMEI(即使是电信卡)  不行的话就获取MEID         return getImeiOrMeid(context, 0);     }     /**      * 获取imei2      *      * @param context      * @return      */     public static String getIMEI2(Context context) {         //imei2必须与 imei1不一样         String imeiDefault = getIMEI1(context);         if (TextUtils.isEmpty(imeiDefault)) {             //默认的 imei 竟然为空,说明权限还没拿到,或者是平板             //这种情况下,返回 imei2也应该是空串             return "";         }         //注意,拿第一个 IMEI 是传0,第2个 IMEI 是传1,别搞错了         String imei1 = getImeiOrMeid(context, 0);         String imei2 = getImeiOrMeid(context, 1);         //sim 卡换卡位时,imei1与 imei2有可能互换,而 imeidefault 有可能不变         if (!TextUtils.equals(imei2, imeiDefault)) {             //返回与 imeiDefault 不一样的             return imei2;         }         if (!TextUtils.equals(imei1, imeiDefault)) {             return imei1;         }         return "";     }     /**      * 获取 Imei/Meid    优先获取IMEI(即使是电信卡)  不行的话就获取MEID      *

     * 如果装有CDMA制式的SIM卡(电信卡) ,在Android 8 以下 只能获取MEID ,无法获取到该卡槽的IMEI      * 8及以上可以通过 #imei 方法获取IMEI  通过 #deviceId 方法获取的是MEID      *      * @param context      * @param slotId  slotId为卡槽Id,它的值为 0、1;      * @return      */     public static String getImeiOrMeid(Context context, int slotId) {         String imei = "";         //Android 6.0 以后需要获取动态权限  检查权限         if (ContextCompat.checkSelfPermission(context, Manifest.permission.READ_PHONE_STATE) != PackageManager.PERMISSION_GRANTED) {             return imei;         }         try {             TelephonyManager manager = (TelephonyManager) context.getApplicationContext().getSystemService(Context.TELEPHONY_SERVICE);             if (manager != null) {                 if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {// android 8 即以后建议用getImei 方法获取 不会获取到MEID                     Method method = manager.getClass().getMethod("getImei", int.class);                     imei = (String) method.invoke(manager, slotId);                 } else if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {                     //5.0的系统如果想获取MEID/IMEI1/IMEI2  ----framework层提供了两个属性值“ril.cdma.meid"和“ril.gsm.imei"获取                     imei = getSystemPropertyByReflect("ril.gsm.imei");                     //如果获取不到 就调用 getDeviceId 方法获取                 } else {//5.0以下获取imei/meid只能通过 getDeviceId  方法去取                 }             }         } catch (Exception e) {         }         if (TextUtils.isEmpty(imei)) {             imei = getDeviceId(context, slotId);         }         return imei;     }     /**      * 仅获取 Imei  如果获取到的是meid 或空  均返回空字符串      *      * @param slotId slotId为卡槽Id,它的值为 0、1;      * @return      */     public static String getImeiOnly(Context context, int slotId) {         String imei = "";         //Android 6.0 以后需要获取动态权限  检查权限         if (ContextCompat.checkSelfPermission(context, Manifest.permission.READ_PHONE_STATE) != PackageManager.PERMISSION_GRANTED) {             return imei;         }         try {             TelephonyManager manager = (TelephonyManager) context.getApplicationContext().getSystemService(Context.TELEPHONY_SERVICE);             if (manager != null) {                 if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {// android 8 即以后建议用getImei 方法获取 不会获取到MEID                     Method method = manager.getClass().getMethod("getImei", int.class);                     imei = (String) method.invoke(manager, slotId);                 } else if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {                     //5.0的系统如果想获取MEID/IMEI1/IMEI2  ----framework层提供了两个属性值“ril.cdma.meid"和“ril.gsm.imei"获取                     imei = getSystemPropertyByReflect("ril.gsm.imei");                     //如果获取不到 就调用 getDeviceId 方法获取                 } else {//5.0以下获取imei/meid只能通过 getDeviceId  方法去取                 }             }         } catch (Exception e) {         }         if (TextUtils.isEmpty(imei)) {             String imeiOrMeid = getDeviceId(context, slotId);             //长度15 的是imei  14的是meid             if (!TextUtils.isEmpty(imeiOrMeid) && imeiOrMeid.length() >= 15) {                 imei = imeiOrMeid;             }         }         return imei;     }     /**      * 仅获取 Meid  如果获取到的是imei 或空  均返回空字符串      * 一般只有一个 meid  即获取到的二个是相同的      *      * @param context      * @param slotId  slotId为卡槽Id,它的值为 0、1;      * @return      */     public static String getMeidOnly(Context context, int slotId) {         String meid = "";         //Android 6.0 以后需要获取动态权限  检查权限         if (ContextCompat.checkSelfPermission(context, Manifest.permission.READ_PHONE_STATE) != PackageManager.PERMISSION_GRANTED) {             return meid;         }         try {             TelephonyManager manager = (TelephonyManager) context.getApplicationContext().getSystemService(Context.TELEPHONY_SERVICE);             if (manager != null) {                 if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {// android 8 即以后建议用getMeid 方法获取 不会获取到Imei                     Method method = manager.getClass().getMethod("getMeid", int.class);                     meid = (String) method.invoke(manager, slotId);                 } else if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {                     //5.0的系统如果想获取MEID/IMEI1/IMEI2  ----framework层提供了两个属性值“ril.cdma.meid"和“ril.gsm.imei"获取                     meid = getSystemPropertyByReflect("ril.cdma.meid");                     //如果获取不到 就调用 getDeviceId 方法获取                 } else {//5.0以下获取imei/meid只能通过 getDeviceId  方法去取                 }             }         } catch (Exception e) {         }         if (TextUtils.isEmpty(meid)) {             String imeiOrMeid = getDeviceId(context, slotId);             //长度15 的是imei  14的是meid             if (imeiOrMeid.length() == 14) {                 meid = imeiOrMeid;             }         }         return meid;     }     private static String getSystemPropertyByReflect(String key) {         try {             @SuppressLint("PrivateApi")             Class clz = Class.forName("android.os.SystemProperties");             Method getMethod = clz.getMethod("get", String.class, String.class);             return (String) getMethod.invoke(clz, key, "");         } catch (Exception e) {/**/}         return "";     }     /**      * 获取 IMEI/MEID      *      * @param context 上下文      * @return 获取到的值 或者 空串""      */     public static String getDeviceId(Context context) {         String imei = "";         //Android 6.0 以后需要获取动态权限  检查权限         if (ContextCompat.checkSelfPermission(context, Manifest.permission.READ_PHONE_STATE) != PackageManager.PERMISSION_GRANTED) {             return imei;         }         // 1. 尝试通过系统api获取imei         imei = getDeviceIdFromSystemApi(context);         if (TextUtils.isEmpty(imei)) {             imei = getDeviceIdByReflect(context);         }         return imei;     }     /**      * 获取 IMEI/MEID      *      * @param context 上下文      * @param slotId  slotId为卡槽Id,它的值为 0、1;      * @return 获取到的值 或者 空串""      */     public static String getDeviceId(Context context, int slotId) {         String imei = "";         // 1. 尝试通过系统api获取imei         imei = getDeviceIdFromSystemApi(context, slotId);         if (TextUtils.isEmpty(imei)) {             imei = getDeviceIdByReflect(context, slotId);         }         return imei;     }     /**      * 调用系统接口获取 IMEI/MEID      *

     * Android 6.0之后如果用户不允许通过 {@link Manifest.permission#READ_PHONE_STATE} 权限的话,      * 那么是没办法通过系统api进行获取 IMEI/MEID 的,但是可以通过{@linkplain #getDeviceIdByReflect(Context)} 反射}绕过权限进行获取      *      * @param context 上下文      * @return 获取到的值 或者 空串""      */     public static String getDeviceIdFromSystemApi(Context context, int slotId) {         String imei = "";         try {             TelephonyManager telephonyManager =                     (TelephonyManager) context.getApplicationContext().getSystemService(Context.TELEPHONY_SERVICE);             if (telephonyManager != null) {                 imei = telephonyManager.getDeviceId(slotId);             }         } catch (Throwable e) {         }         return imei;     }     public static String getDeviceIdFromSystemApi(Context context) {         String imei = "";         try {             TelephonyManager telephonyManager =                     (TelephonyManager) context.getApplicationContext().getSystemService(Context.TELEPHONY_SERVICE);             if (telephonyManager != null) {                 imei = telephonyManager.getDeviceId();             }         } catch (Throwable e) {         }         return imei;     }     /**      * 反射获取 IMEI/MEID      *

     * Android 6.0之后如果用户不允许通过 {@link Manifest.permission#READ_PHONE_STATE} 权限的话,      * 那么是没办法通过系统api进行获取 IMEI/MEID 的,但是可以通过这个反射来尝试绕过权限进行获取      *      * @param context 上下文      * @return 获取到的值 或者 空串""      */     public static String getDeviceIdByReflect(Context context) {         try {             TelephonyManager tm = (TelephonyManager) context.getApplicationContext().getSystemService(Context.TELEPHONY_SERVICE);             if (Build.VERSION.SDK_INT >= 21) {                 Method simMethod = TelephonyManager.class.getDeclaredMethod("getDefaultSim");                 Object sim = simMethod.invoke(tm);                 Method method = TelephonyManager.class.getDeclaredMethod("getDeviceId", int.class);                 return method.invoke(tm, sim).toString();             } else {                 Class clazz = Class.forName("com.android.internal.telephony.IPhoneSubInfo");                 Method subInfoMethod = TelephonyManager.class.getDeclaredMethod("getSubscriberInfo");                 subInfoMethod.setAccessible(true);                 Object subInfo = subInfoMethod.invoke(tm);                 Method method = clazz.getDeclaredMethod("getDeviceId");                 return method.invoke(subInfo).toString();             }         } catch (Throwable e) {         }         return "";     }     /**      * 反射获取 deviceId      *      * @param context      * @param slotId  slotId为卡槽Id,它的值为 0、1;      * @return      */     public static String getDeviceIdByReflect(Context context, int slotId) {         try {             TelephonyManager tm = (TelephonyManager) context.getApplicationContext().getSystemService(Context.TELEPHONY_SERVICE);             Method method = tm.getClass().getMethod("getDeviceId", int.class);             return method.invoke(tm, slotId).toString();         } catch (Throwable e) {         }         return "";     } }



【本文地址】

公司简介

联系我们

今日新闻

    推荐新闻

    专题文章
      CopyRight 2018-2019 实验室设备网 版权所有