一、概念
IMEI
IMEI(International Mobile Equipment Identity) 是国际移动设备身份码的缩写,国际移动装备辨识码,是由 15 位数字组成的 “电子串号”,它与每台手机一一对应,而且该码是全世界唯一的。每一部手机在组装完成后都将被赋予一个全球唯一的一组号码,这个号码从生产到交付使用都将被制造生产的厂商所记录。IMEI 码由 GSM(全球移动通信协会)统一分配,授权 BABT(英国通信认证管理委员会)审受。
IMEI 组成为:
1、前 6 位数(TAC,Type ApprovalCode) 是 “型号核准号码”,一般代表机型。
2、接着的 2
位数(FAC,Final Assembly Code) 是 “最后装配号”,一般代表产地。
3、之后的 6 位数(SNR) 是"串号",一般代表生产顺序号。 4、最后 1 位数(SP) 通常是 “0”,为检验码,备用。
一般在 Android 手机上可以在关于手机里面查看到
IMSI
国际移动用户识别码(IMSI:International Mobile Subscriber Identification Number)是区别移动用户的标志,储存在 SIM 卡中,可用于区别移动用户的有效信息。其总长度不超过 15 位,同样使用 0~9 的数字。
ICCID
ICCID:Integrate circuit card identity 集成电路卡识别码(固化在手机 SIM 卡中),简单来说就是 SIM 卡序列号,它拥有独一无二的特性,类似于手机的序列号,仅仅指向一张手机卡。共有 20 位数字组成,不同运营商编码格式不一样。并且前六位数字为运营商代码:比如中国移动的为:898600;中国联通的为:898601,中国电信的为:898603。
简而言之:IMEI / MEID 是和设备相关的,移动设备的唯一标志码;而 IMSI 和 ICCID 是和手机卡相关的,信息存储到手机卡上,没有安装手机卡的手机,上面获取这两个值为 null。
二、TelephonyManager
//注意代码使用需要在Manifest配置权限
// <uses-permission android: />
//在API 23(Android6.0 )及其以上版本phone组权限需要动态申请
TelephonyManager tm = (TelephonyManager) this.getSystemService(Context.TELEPHONY_SERVICE);
String deviceid = tm.getDeviceId(); //取 IMEI或者MEID
String tel = tm.getLine1Number(); //取出用户手机号码,手机没有安装SIM卡,值为null
String imsi =tm.getSubscriberId(); //取出IMSI,手机没有安装SIM卡,值为null
String imei =tm.getSimSerialNumber(); //取出ICCID,手机没有安装SIM卡,值为null
其实上面的信息分开来看总共分为两部分,一部分是设备相关的信息,一部分是 SIM 卡相关的信息。关于 SIM 卡相关的信息,一般来说没有办法标志设备,因为手机可以任意替换 SIM 卡,而且现在手机都是双卡双待的,关于双卡手机获取和手机卡相关的信息参考这篇文章
我们这里主要关心设备 ID(IMEI 或者 MEID),解释下这两个东西:IMEI 是国际移动设备识别码的简称,而 MEID 是 动设备识别码的简称,一般 IMEI 是所有设备都有,而 MEID 一般只在只有支持 CDMA 制式的设备才有的。
OPPO 手机:进入手机设置 – 常规 – 关于手机 – 状态信息 --IMEI 即可看到。 小米手机: 设置 – 我的设备 – 全部参数 – 状态信息 —IMEI 信息 华为手机:设置 — 关于手机
注意:平板没有 imei 号
三、设备唯一 ID
1. IMEI 或者 MEID
Android 系统关于双卡的支持的知识需要知道一些,在 Android4.x 及其以下版本的时候,原生 Android 是不支持双卡的,在
5.x 左右开始支持,但是 api 是隐藏的,在 Android 6.0 才开始公开开放双卡的 API。
来看下我们获取 IMEI 或者 MEID 的基本方法
//注意动态权限申请
TelephonyManager telephonyManager = (TelephonyManager) this.getSystemService(Context.TELEPHONY_SERVICE);
String imei = telephonyManager.getDeviceId();
这个方法在 4.x 及其以下版本的时候,运行这个方法是没有问题的,因为 4.x 是不支持双卡的,也就是说 4.x 的手机要么是 GSM 要么是 CDMA 制式的。所以,getDeviceId的文档这样写道:
/**
* 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.
* 翻译过来就是:这个方法会返回唯一的设备id,
* 比如在GSM的手机上返回的是IMEI,而在CDMA 手机上返回的是MEID或者ESN。
* 如果设备id不可读取,那么返回null。
*/
但是这种情况到了 Android 6.0 (先不考虑 5.x 那个版本不稳定)上就不一样了,6.0 支持双卡&#x