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 "";

}

}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/344293.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

JMetro版本5发布

Java的第5版JavaFX主题JMetro刚刚发布。 这是此版本中的新功能: 新的文本区域明暗风格; 现有控件样式的一些更改; 新CSS变量称为accent_color。 顾名思义,它允许您定义JMetro控件中使用的强调颜色。 已经进行了很大的重构&am…

[渝粤教育] 西南科技大学 会计学原理 在线考试复习资料(1)

会计学原理——在线考试复习资料 一、单选题 1.资产负债表是反映企业( )财务状况的会计报表。 A.某一特定日期 B.一定时期内 C.某一月份内 D.某一年份内 2.某企业本期盘亏的材料已查明原因,属于自然损耗,批准处理时应编制的会计分录( )。 A.借记“待处理财产损溢”,…

android 开发 矩形截屏插件,Android 上如何实现矩形区域截屏

对屏幕进行截屏并裁剪有两种方式:早截图和晚截图。早截图,就是先截取全屏,再让用户对截取到的图片进行修改;与之相对的,晚截图,就是先让用户在屏幕上划好区域,再进行截图和裁剪。其实两者并没有什么太大的区…

[渝粤教育] 西南科技大学 供应链管理 在线考试复习资料

供应链管理——在线考试复习资料 一、单选题 1.人们设置库存的目的,不包括以下哪种? A.增加固定资产 B.防止缺货 C.保持生产连续性 D.快速满足订货需求 2.费希尔(Fisher)按市场需求模式将产品分为两类,即功能性产品和创新性产品。下面属于功能性产品的是: A.时装 B.石油 C.手…

[渝粤教育] 西南科技大学 信息组织与检索 在线考试复习资料2021版

信息组织与检索——在线考试复习资料2021版 一、单选题 1.要求两个关键词至少有一个出现在检索结果中需使用的操作符是( )。 A. ND B. OR C. ND NOT D. NEAR 答案:看左边查询 2.要求两个关键词都必须出现在检索结果中需使用的操作符是( )。 A. ND B. OR C. ND NOT D. NE…

Android布局怎么画图形,Android开发者的图形化布局

图形化布局编辑器允许你通过拖放来创建UI。在早期版本的ADT中,图形化布局编辑器并不是很有帮助,幸运的是,最新版本非常强大,可以用来创建复杂的包含有复合组件以及动画的布局。(1)Configuration下拉菜单让你可以改变当前布局展示的…

java注释类型_Java 8类型注释

java注释类型Lambda表达式是迄今为止Java 8讨论最多和最受促进的功能。虽然我同意Lambda是一个很大的改进,但我认为其他一些Java 8功能由于Lambda的炒作而有所欠缺。 在这篇文章中,我想展示另一个来自Java 8的出色特性的示例:Type Annotation…

[渝粤教育] 西南科技大学 公共组织学 在线考试复习资料

公共组织学——在线考试复习资料 一、单选题 1.从沟通媒介自身的丰富性程度看,排在第一位的应该是( ) A.电话 B.电子邮件 C.面对面地交谈 D.文件 2.“韦伯认为,以古老的传统、神圣不可侵犯的信念,以及对其下属行使权力的人的地位的合法性为基础的权力属于( ) A.合理–合法型…

[渝粤教育] 西南科技大学 刑事诉讼法学 在线考试复习资料

刑事诉讼法学——在线考试复习资料 一、单选题 1.传唤、拘传持续的时间不得超过十二小时;案情特别重大、复杂,需要采取拘留、逮捕措施的,传唤、拘传持续的时间不得超过( )小时。 A.12 B.24 C.48 2.无期徒刑的执行机关是?( ) A.公安机关 B.监狱 C.检察机关 D.人民法院 3.讯问…

android studio简易记账本,Android记账本

十分感谢徐老师用心制作的这个视频,我学到了很多,再次感谢。这里贴一下我对着这个视频写的代码:https://github.com/supertian007/ImoocDaily,欢迎大家参考、或指出问题。记录一下学习过程中遇到的几个问题:1. 视频的b…

Java可选参数

在Java类中设计方法时,某些参数对于其执行而言可能是可选的。 无论是在DTO,胖模型域对象还是简单的无状态服务类中,可选方法参数都是常见的。 从本文中, 您将学习如何在Java中处理可选参数 。 我们将专注于常规方法,带…

[渝粤教育] 西南科技大学 单片机原理与应用 在线考试复习资料(2)

单片机原理与应用——在线考试复习资料 一、单选题 1.信息能够同时双向传送的是( )。 A.并行通信 B.单工串行通信 C.半双工串行通信 D.全双工串行通信 2.T89S52单片机片内有( )个定时器/计数器。 A.1 B.2 C.3 D.4 3.串口通信时,每秒传送120个字符,数据格式为1位起始位、8位数…

android前台进程视频教程,Android Twilio视频通话,唤醒应用程序并进入前台

因此,我们已经找到了解决方案(当收到通知时,将应用程序置于前台),即使已经有一段时间了,我仍在发布它:> FCM通知(firebase云消息传递通知)只需在通知中发送“数据”.因此,通知的JSON结构中没有Notification对象,只有数据.这样,通知便由您应用的FirebaseMessaging…

[渝粤教育] 西南科技大学 土木工程施工 在线考试复习资料(1)

土木工程施工——在线考试复习资料 一、单选题 1.先张法预应力筋放张时,其混凝土应到达设计强度的( )。 A.50% B.75% C.90% D.100% 2.抹灰标志块的厚度为( )。 A.底层厚度 B.中层厚度 C.底层中层厚度 D.底层中层面层厚度 3.预应力超张拉是为了( )。 A.减少预应力筋与孔道摩擦…

[渝粤教育] 西南科技大学 审计原理与实务 在线考试复习资料2021

审计原理与实务——在线考试复习资料2021 一、单选题 1. 注册会计师在执行报表审计业务中,若发现有违法行为,应当予以( )。 A.向主管部门报告 B.拒绝审计 C.向法院起诉 D.向董事会报告 答案:看左边查询 2.注册会计师从1000个应收账款明细账…

android 日期相,Android日历始终保持相同的日期

当用户签入复选框时,我希望闹钟响起。这是我的代码:if (cb1.isChecked()){Calendar calA Calendar.getInstance();//calA.set(Calendar.YEAR, Calendar.YEAR);//calA.set(Calendar.MONTH, Calendar.MONTH);//calA.set(Calendar.DAY_OF_MONTH, Calendar.…

[渝粤教育] 西南科技大学 广告学 在线考试复习资料

广告学——在线考试复习资料 一、单选题 1.下列不属于平面广告表现形式的是( ) A.漫画 B.照片 C.广告视频 D.广告画 2.下列广告媒体出现相对最早的是( ) A.电视 B.网络 C.报纸 D.户外广告牌 3.下列不属于视觉广告的是( ) A.报纸广告 B.电视广告 C.广播广告 D.霓虹灯广告 4.在…

jedis与redis_Redis与Jedis排序

jedis与redis在本文中,我们将讨论Redis SORT命令。 Redis提供了SORT命令,我们可以使用该命令从LIST,SET或ZSET中检索或存储排序的值。 我们可以使用最简单的形式在KEY上使用命令,如下例所示: SORT numbers_list这将…

[渝粤教育] 西南科技大学 微机原理与应用 在线考试复习资料(1)

微机原理与应用——在线考试复习资料 一、单选题 1.十六进制数0A95转换成二进制数是? A.1010 1001 0101 B.0000 1010 0101 C.1000 1010 1001 D.0000 1110 1001 2.设BX2000H,[0003H]16H,[2000H]25H,[2003H]74H,执行指令MOV BX,2000H和指令MOV AL,[BX03H]后,AL中的数据是? A.7…

计算机发送到桌面快捷方式,windows7添加到桌面快捷方式无故消失!

您好,Windows 7设计者在Windows 7中所添加的设计。在默认情况下,只要System Maintenance troubleshooter(系统故障维护,以下简称SMT)检测到桌面的快捷方式已经无效了,将会自动将其删除。每周,SMT(系统故障维护)都会对操…