您的位置:首页 > 移动开发 > Android开发

Android手机设备唯一标识符

2017-07-12 11:36 309 查看
在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关闭情况下获取标识的情况:

品牌型号系统版本IMEIMacAndroid idSerial Number
VivoX5Pro V5.0.2
OppoR7s4.4.4
华为ALE-UL005.0.2
小米Redmi note25.0.2
小米4LTE6.0.1
魅族M2 note5.1
HTCm8sw5.0.2
华为MT7-TL105.1.1
三星SM-G92006.0.1
生成方案

常见手机设备唯一表示码选择上面的一种或几种,但是部分手机的Mac码的获取会与Wifi状态有关,改动较大因此舍弃Mac码。挑选出IMEI码、Android ID、Serial Number拼接成一个字符串,然后通过MD5加密生成一个唯一标识。

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


通过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;
}


关于Android 手机设备唯一标识符的生成就到这里,希望这篇博客能够为小伙伴们提供一些帮助。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: