获取安卓设备唯一ID

先介绍安卓设备中的几种ID
1、IMEI
Android系统为开发者提供的用于标识手机设备的串号,也是各种方法中普适性较高的,可以说几乎所有的设备都可以返回这个串号,并且唯一性良好。它根据不同的手机设备返回IMEI,MEID或者ESN码。
缺陷:
非手机设备: 如果只带有Wifi的设备或者音乐播放器没有通话的硬件功能的话就没有这个DEVICE_ID;
权限: 获取DEVICE_ID需要READ_PHONE_STATE权限;
在少数的一些手机设备上,该实现有漏洞,会返回垃圾,如:zeros或者asterisks的产品;
模拟器上可以刷IMEI。
获取方法:

public static String getIMEI(Context context) {
	String imei;
	try {
		TelephonyManager telephonyManager = (TelephonyManager) context.getSystemService(Context.TELEPHONY_SERVICE);
		imei = telephonyManager.getDeviceId();
	} catch (Exception e) {
		imei = "";
	}
	return imei;
}

2、MAC
可以使用手机Wifi或蓝牙的MAC地址作为设备标识。
硬件限制:并不是所有的设备都有Wifi和蓝牙硬件,硬件不存在自然也就得不到这一信息。
添加权限:ACCESS_WIFI_STATE
获取到的,不是一个真实的地址,而且这个地址能轻易地被伪造。wLan不必打开,就可读取些值。

public static String getMac (Context context) {
	//wifi mac地址
	WifiManager wifi = (WifiManager) context.getSystemService(Context.WIFI_SERVICE);
	WifiInfo info = wifi.getConnectionInfo();
	String wifiMac = info.getMacAddress();
	if(!isEmpty(wifiMac)){
	}
	return wifiMac;
}

蓝牙需要添加权限:android.permission.BLUETOOTH

BluetoothAdapter m_BluetoothAdapter = null; // Local Bluetooth adapter
m_BluetoothAdapter = BluetoothAdapter.getDefaultAdapter();
String m_szBTMAC = m_BluetoothAdapter.getAddress();

3、SIM ID – 手机SIM卡唯一标识
装有SIM卡的Android 2.3设备,可以通过下面的方法获取到Sim Serial Number,对于CDMA设备,返回的是一个空值。

public static String getSimId (Context context) {
	TelephonyManager tm = (TelephonyManager)context.getSystemService(Context.TELEPHONY_SERVICE);
	String SimSerialNumber = tm.getSimSerialNumber();
	return SimSerialNumber;
}

4、ANDROIDID - 安卓ID
在设备首次启动时,系统会随机生成一个64位的数字,并把这个数字以16进制字符串的形式保存下来,这个16进制的字符串就是ANDROID_ID,当设备被wipe后该值会被重置。
厂商定制系统的Bug:不同的设备可能会产生相同的ANDROID_ID:9774d56d682e549c。
厂商定制系统的Bug:有些设备返回的值为null。
设备差异:对于CDMA设备,ANDROID_ID和TelephonyManager.getDeviceId() 返回相同的值。
它在Android <=2.1 or Android >=2.3的版本是可靠、稳定的,但在2.2的版本并不是100%可靠的。
通常被认为不可信,因为它有时为null。开发文档中说明了:这个ID会改变如果进行了出厂设置。并且,如果某个Andorid手机被Root过的话,这个ID也可以被任意改变。

public static String getAndroidId (Context context) {
	String ANDROID_ID = Settings.System.getString(context.getContentResolver(), Settings.System.ANDROID_ID);
	return ANDROID_ID;
}

5、Serial Number
Android系统2.3版本以上可以通过下面的方法得到Serial Number,且非手机设备也可以通过该接口获取。

public static String getSerialNumber (Context context) {
	String SerialNumber = android.os.Build.SERIAL;
	return SerialNumber;
}

获取唯一ID方法一:

实现在设备上更通用的获取设备唯一标识(为每个设备产生唯一的UUID,以ANDROID_ID为基础,在获取失败时以TelephonyManager.getDeviceId()为备选方法,如果再失败,使用UUID的生成策略。

public class DeviceUuidFactory {
    protected static final String PREFS_FILE = "device_id";

    protected static final String PREFS_DEVICE_ID = "device_id";

    protected static UUID uuid;

    private static String deviceType = "0";

    private static final String TYPE_ANDROID_ID = "1";

    private static final String TYPE_DEVICE_ID = "2";

    private static final String TYPE_RANDOM_UUID = "3";

    public DeviceUuidFactory(Context context) {
        if (uuid == null) {
            synchronized (DeviceUuidFactory.class) {
                if (uuid == null) {
                    final SharedPreferences prefs = context.getSharedPreferences(PREFS_FILE, 0);
                    final String id = prefs.getString(PREFS_DEVICE_ID, null);
                    if (id != null) {
                        uuid = UUID.fromString(id);
                    } else {
                        final String androidId = Secure.getString(context.getContentResolver(), Secure.ANDROID_ID);
                        try {
                            if (!"9774d56d682e549c".equals(androidId)) {
                                deviceType = TYPE_ANDROID_ID;
                                uuid = UUID.nameUUIDFromBytes(androidId.getBytes("utf8"));
                            } else {
                                final String deviceId = ((TelephonyManager) context.getSystemService(Context.TELEPHONY_SERVICE)).getDeviceId();
                                if (deviceId != null
                                        && !"0123456789abcdef".equals(deviceId.toLowerCase())
                                        && !"000000000000000".equals(deviceId.toLowerCase())) {
                                    deviceType = TYPE_DEVICE_ID;
                                    uuid = UUID.nameUUIDFromBytes(deviceId.getBytes("utf8"));
                                } else {
                                    deviceType = TYPE_RANDOM_UUID;
                                    uuid = UUID.randomUUID();
                                }
                            }
                        } catch (UnsupportedEncodingException e) {
                            deviceType = TYPE_RANDOM_UUID;
                            uuid = UUID.randomUUID();
                        } finally {
                            uuid = UUID.fromString(deviceType + uuid.toString());
                        }

                        prefs.edit().putString(PREFS_DEVICE_ID, uuid.toString()).commit();
                    }
                }
            }
        }
    }

    public UUID getDeviceUuid() {
        Log.d("DeviceUuidFactory", "------>获取的设备ID号为:" + uuid.toString());
        return uuid;
    }
}

获取唯一ID方法二:
先获取IMEI,如果IMEI为以下值,

device_id == null || isEmpty(device_id) || "0".equals(device_id) || "00000000000000".equals(device_id) || "000000000000000".equals(device_id)

那么,再用方法一获取。
获取唯一ID方法三:
添加权限:

READ_PHONE_STATE
final TelephonyManager tm = (TelephonyManager) getBaseContext().getSystemService(Context.TELEPHONY_SERVICE);
final String tmDevice, tmSerial, androidId;
tmDevice = "" + tm.getDeviceId();
tmSerial = "" + tm.getSimSerialNumber();
androidId = "" + android.provider.Settings.Secure.getString(getContentResolver(), android.provider.Settings.Secure.ANDROID_ID);
UUID deviceUuid = new UUID(androidId.hashCode(), ((long)tmDevice.hashCode() << 32) | tmSerial.hashCode());
String deviceId = deviceUuid.toString();

获取唯一ID方法四:
虚拟ID

/**
 * 返回 唯一的虚拟 ID
 * @return ID
 */
public static String getUniquePsuedoID() {
    String m_szDevIDShort = "35" + (Build.BOARD.length() % 10) + (Build.BRAND.length() % 10) + (Build.CPU_ABI.length() % 10) + (Build.DEVICE.length() % 10) + (Build.MANUFACTURER.length() % 10) + (Build.MODEL.length() % 10) + (Build.PRODUCT.length() % 10);

    // API >= 9 的设备才有 android.os.Build.SERIAL
    // http://developer.android.com/reference/android/os/Build.html#SERIAL
    // 如果用户更新了系统或 root 了他们的设备,该 API 将会产生重复记录
    String serial = null;
    try {
        serial = android.os.Build.class.getField("SERIAL").get(null).toString();
        return new UUID(m_szDevIDShort.hashCode(), serial.hashCode()).toString();
    } catch (Exception exception) {
        serial = "serial";
    }

    // 最后,组合上述值并生成 UUID 作为唯一 ID
    return new UUID(m_szDevIDShort.hashCode(), serial.hashCode()).toString();
}

个人博客地址

github地址

  • 5
    点赞
  • 47
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值