android 获取 meid 代码,Android 各个版本获取IMEI、MEID
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 "";
}
}
android 获取 meid 代码,Android 各个版本获取IMEI、MEID相关推荐
- android计算汇率代码,android studio 开发实例 连接网络获取汇率
配置文件 AndroidManifest.xml 如下 Version:1.0StartHTML:000000243 EndHTML:000019067 StartFragment:000007811 ...
- android获取海拔代码,android获取经度、维度、海拔简单代码
android获取经度.维度.海拔 import java.text.DecimalFormat; import java.text.SimpleDateFormat; import java.uti ...
- android增删功能代码,Android SQLite增删查改实例代码部分
在 Android与SQLite数据库 这个专题里我们谈到了 SQLite 的基本应用,但在实际开发中,为了能够更好的管理和维护数据库,我们会封装一个继承自 SQLiteOpenHelper 类的数据 ...
- android小球移动代码,Android自定义圆形View实现小球跟随手指移动效果
本文实例为大家分享了Android实现小球跟随手指移动效果的具体代码,供大家参考,具体内容如下 一. 需求功能 手指在屏幕上滑动,红色的小球始终跟随手指移动. 实现的思路: 1)自定义View,在on ...
- android登录操作代码,Android Studio实现第三方QQ登录操作代码
来看看效果图吧 实现QQ登录了, 新建一个项目工程 ,然后把我们刚才下载的SDK解压将jar文件夹中的jar包拷贝到我们的项目libs中 导入一个下面架包就可以 项目结构如下 打开我们的清单文件And ...
- android摄像头拍照代码,Android调用摄像头拍照开发教程
现在很多应用中都会要求用户上传一张图片来作为头像,首先我在这接收使用相机拍照和在相册中选择图片.接下来先上效果图: 接下来看代码: 1.布局文件: xmlns:tools="http://s ...
- android 小白点代码,Android实现小圆点显示未读功能
####前言 以前我们实现这个功能都是用 BadgeView.java,大体就是将这个java类复制到自己的项目中,然后在项目中使用,今天讲的也是一款BadgeView,我将其封装称工具类Badget ...
- Android钢琴滑动代码,Android实现简易版弹钢琴效果
本文实例为大家分享了Android实现弹钢琴效果展示的具体代码,供大家参考,具体内容如下 目标效果: 1.drawable下新建button_selector.xml页面: 2.drawable下新建 ...
- android清除缓存 代码,Android应用开发之Android应用清除缓存一般清理目录和代码的教程...
本文将带你了解Android应用开发Android应用清除缓存一般清理目录和代码的教程,希望本文对大家学Android有所帮助. 一个应用安装完成,会有缓存,缓存一般分为内部存储的和外置的,内存中路径 ...
最新文章
- Java OkHttp3的简单使用
- C++实现tree树(附完整源码)
- C++中对String的各种操作
- pvz安卓服务器维修礼包码,植物大战僵尸2礼包兑换码大全2020最新版
- 【C++】C++读取文本中的特定一列
- matlab dicom图像异常,用Matlab处理Dicom图像
- Httpclient远程调用WebService示例
- 数据库存储I/O类型分析与配置
- vue中a标签跳转问题(跳转网址自动加上http://local:8080/)
- django pdf转html5,pytho pdfkit 将网页django2.0教程内容打印成pdf文档
- 保研计算机专硕还是学硕,考研怎么选报专硕还是学硕
- uva 10158 - War(并查集)
- python字符串前面u、r、b含义以及str、bytes互转
- Teamcenter Folder
- 机器学习几种距离比较:欧拉距离(Euclidean Distance)、曼哈顿距离(Manhattan Distance)和明可夫斯基距离(Minkowski Distance)
- 未分配利润与利润表不一致_资产负债里的未分配利润与利润表不相等怎么回事...
- 是谁在为加速网络智能化落地打造开放、融合、端到端平台?
- Android Unicode与文本字符串互相转换
- 屏幕录制:SCR Screen Recorder Pro v0.14.3汉化破解版
- Origin如何画小提琴图