天天看點

Android開發 - 擷取Android裝置的唯一辨別碼(Android 6.0或更高)

在我們的APP開發中,通常需要擷取到裝置的唯一辨別。在Android6.0之前,有很多方法我們可以友善擷取到硬體的唯一辨別,但是在Android6.0之後,Android系統大幅限制了我們擷取裝置的硬體資訊。

Android6.0之前的方法(已過時)

  1. DEVICE_ID

    通getSystemService(Context.TELEPHONY_SERVICE).getDeviceId()擷取,但是6.0之後必須申請READ_PHONE_STATE,并且擷取到的這個值在不同的廠商和裝置中并不可靠。

  2. MAC位址

    這個是無線網卡的MAC位址,這個需要ACCESS_WIFI_STATE權限,并且很多情況下并擷取不到這個值,也并不是十分可靠。

  3. ANDROID_ID

    這個值是當一個新的裝置第一次啟動時,或者恢複出廠設定時,系統會生成一個64位的數字,這個值目前(Android4.0之後)已經非常可靠,但是仍有個别廠商的定制系統的BUG,導緻這個值傳回null。

擷取裝置唯一辨別的正确姿勢

由于ANDROID_ID的值相對穩定和可靠,并且不需要申請權限,是以我們擷取裝置的唯一辨別應該使用這個值,同時我們應該考慮到一些極端情況和安全問題。

  1. 擷取ANDROID_ID
public static String getAndroidID() {
    String id = Settings.Secure.getString(
            Utils.getApp().getContentResolver(),
            Settings.Secure.ANDROID_ID
    );
    return id == null ? "" : id;
}
           
  1. 構造UUID,防止直接暴露ANDROID_ID
private static String getDeviceUUid()
{
   String androidId = DeviceUtils.getAndroidID();
   UUID deviceUuid = new UUID(androidId.hashCode(), ((long)androidId.hashCode() << 32));
   return deviceUuid.toString();
}
           
  1. 考慮極端情況,我們自己生成一個應用級别的UUID

    這種情況我們需要将生成的UUID儲存到SharedPreference中,隻要應用不被解除安裝或者清除資料,這個值就不會變。

private static String getAppUUid() {
   String uuid = SPUtils.getInstance().getString(PREF_KEY_UUID);
   if (TextUtils.isEmpty(uuid)) {
       uuid = UUID.randomUUID().toString();
       //這裡需要儲存到SharedPreference中
       ...
   }
   return uuid;
}
           
  1. 将上面的擷取方法封裝到一個方法中
public static String getUUID() {
    String uuid = getDeviceUUid();
    if (TextUtils.isEmpty(uuid)) {
        uuid = getAppUUid();
    }
    return uuid;
}
           

總結

這些擷取UUID方法非常簡單,并且在應用的開發中可以滿足99%的需求,不需要動态申請權限,也非常可靠,但是在使用時需要清楚其生成過程,以便應用到安全性要求非常高的場景中。

如有更多疑問,請參考我的其它Android相關部落格:

我的部落格位址

繼續閱讀