赞
踩
在Android App开发过程中有时需要确定手机设备的唯一性。但是Android 手机设备的唯一标识的获取并不能保持每次都能获取成功,因而无法保持手机的唯一性。Android手机获取唯一标识一直没有统一标准,每个公司都有自己的一套规则。首先说一下几种比较常用的作为手机设备唯一标识的:
IMEI
范围:只能支持拥有通话功能的设备,对于平板不可以。
持久性:返厂,数据擦除的时候不彻底,保留了原来的标识。
权限:需要权限:Android.permission.READ_PHONE_STATE
bug: 有些厂家的实现有bug,返回一些不可用的数据
Mac地址
范围:有支持无限上网的设备
权限:需要ACCESS_WIFI_STATE权限
持久性:有些设备没有WiFi,或者蓝牙,就不可以,如果WiFi没有打开,硬件也不会返回Mac地址,不建议使用
Android_ID
范围:所有Android系统设备
Bug:2.2(Froyo,8)版本系统会不可信,来自主要生产厂商的主流手机,至少有一个普遍发现的bug,这些有问题的手机相同的ANDROID_ID: 9774d56d682e549c但是如果返厂的手机,或者被root的手机,可能会变
Serial Number
范围:从android 2.3 (“Gingerbread”)开始可用,可以通过android.os.Build.SERIAL获取,对于没有通话功能的设备,它会返回一个唯一的device ID,
验证在手机Wifi关闭情况下获取标识的情况:
品牌 | 型号 | 系统版本 | IMEI | Mac | Android id | Serial Number |
---|---|---|---|---|---|---|
Vivo | X5Pro V | 5.0.2 | 有 | 有 | 有 | 有 |
Oppo | R7s | 4.4.4 | 有 | 有 | 有 | 有 |
华为 | ALE-UL00 | 5.0.2 | 有 | 有 | 有 | 有 |
小米 | Redmi note2 | 5.0.2 | 有 | 有 | 有 | 有 |
小米 | 4LTE | 6.0.1 | 有 | 无 | 有 | 有 |
魅族 | M2 note | 5.1 | 有 | 有 | 有 | 有 |
HTC | m8sw | 5.0.2 | 有 | 有 | 有 | 有 |
华为 | MT7-TL10 | 5.1.1 | 有 | 有 | 有 | 有 |
三星 | SM-G9200 | 6.0.1 | 有 | 无 | 有 | 有 |
IMEI码、Android ID、Serial Number的获取:
String macId = getMacAddress(this);
Log.e("yushan", "macId:::" + macId);
String IMIESId = getIMIEStatus(this);
Log.e("yushan", "IMIESId:::" + IMIESId);
String AndroidId = getAndroidId(this);
Log.e("yushan", "AndroidId:::" + AndroidId);
String AndroidSerial = getAndroidSerial();
Log.e("yushan", "AndroidSerial:::" + AndroidSerial);
public static String getMacAddress(Context context) {
String macAddress = null;
WifiInfo wifiInfo = getWifiInfo(context);
if (wifiInfo != null) {
macAddress = wifiInfo.getMacAddress();
}
return macAddress;
}
/**
* 获取WifiInfo
*/
public static WifiInfo getWifiInfo(Context context) {
WifiManager wifiManager = (WifiManager) context.getSystemService(Context.WIFI_SERVICE);
WifiInfo info = null;
if (null != wifiManager) {
info = wifiManager.getConnectionInfo();
}
return info;
}
private static String getIMIEStatus(Context context) {
String deviceId = "";
if (ActivityCompat.checkSelfPermission(context, Manifest.permission.READ_PHONE_STATE) != PackageManager.PERMISSION_GRANTED) {
ActivityCompat.requestPermissions(activity, new String[]{Manifest.permission.READ_PHONE_STATE}, 1);
} else {
TelephonyManager tm = (TelephonyManager) context.getSystemService(Context.TELEPHONY_SERVICE);
deviceId = tm.getDeviceId();
}
return deviceId;
}
private static String getAndroidId(Context context) {
String androidId = Settings.Secure.getString(context.getContentResolver(), Settings.Secure.ANDROID_ID);
return androidId;
}
private String getAndroidSerial() {
String serialNum = Build.SERIAL;
return serialNum;
}
![](https://csdnimg.cn/release/blogv2/dist/pc/img/newCodeMoreWhite.png)
通过MD5加密生成唯一标识:
String pseudoId = "21" + // 加盐
getIMIEStatus(this) + // IMEI码
getAndroidSerial() + // Serial num
getAndroidId(this); // Android Id
String md5Str = makeMD5(pseudoId);
Log.e("yushan", "md5Str:::" + md5Str);
// MD5加密
public static String makeMD5(String password) {
try {
// 生成一个MD5加密计算摘要
MessageDigest md = MessageDigest.getInstance("MD5");
// 计算md5函数
md.update(password.getBytes());
// digest()最后确定返回md5 hash值,返回值为8为字符串。因为md5 hash值是16位的hex值,实际上就是8位的字符
// BigInteger函数则将8位的字符串转换成16位hex值,用字符串来表示;得到字符串形式的hash值
return new BigInteger(1, md.digest()).toString(16);
} catch (Exception e) {
e.printStackTrace();
}
return password;
}
![](https://csdnimg.cn/release/blogv2/dist/pc/img/newCodeMoreWhite.png)
关于Android 手机设备唯一标识符的生成就到这里,希望这篇博客能够为小伙伴们提供一些帮助。
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。