1. 程式人生 > >獲取安卓裝置唯一ID

獲取安卓裝置唯一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();
}