Android 設備標識符

由于安卓平臺的開放性和碎片化,對于我們獲取唯一可靠的設備標識符帶來了很大的困難,在本片文章中我們將介紹安卓平臺下的,各種獲取設備標識符的方式以及這些方式的利弊,那什么是設備標識符呢?
簡單說,設備標識符就是唯一標識該設備的一串代碼或符號。

設備標識符在Android開發中的作用

  • 跟蹤用戶安裝
  • 識別物理設備
獲取Android設備ID(DeviceId)

設備ID(DeviceId)是手機唯一標識符,屬于比較穩定的設備標識符。對于GSM返回IMEI,對于CDMA返回MEID或ESN。

//uses-permission android:name="android.permission.READ_PHONE_STATE"
private String getDeviceId() {
    TelephonyManager telephonyManager = (TelephonyManager) getSystemService(Context.TELEPHONY_SERVICE);
    String deviceId = telephonyManager.getDeviceId();
    return deviceId;
}

缺陷:

  • 非手機設備沒有這種唯一的標識符,比如平板電腦、機頂盒、音樂播放器等。
  • 權限問題:調用方法需要READ_PHONE_STATE權限,特別是Android 6.0以后,權限需要用戶手動確認。
  • Bug:在一些設備制造商的設備上,這個只是不準確的 ,比如會返回一堆0或者星號。
獲取Mac Address

通過檢索設備的Wi-Fi或者藍牙硬件是有可能取得設備的Mac地址的。

// uses-permission android:name="android.permission.ACCESS_WIFI_STATE"
private String getWifiMacDId() {
    WifiManager wifiManager = (WifiManager) getSystemService(Context.WIFI_SERVICE);
    String wifMacId = wifiManager.getConnectionInfo().getMacAddress();
    return wifMacId;
}

//uses-permission android:name="android.permission.BLUETOOTH" 
private String getBlueToothMacDId() {
    BluetoothAdapter bluetoothAdapter = BluetoothAdapter.getDefaultAdapter();
    String blueToothMacId = bluetoothAdapter.getAddress();
    return blueToothMacId;
}

缺陷:

  • 硬件限制: 并不是所有的設備都有WiFi和藍牙硬件
  • 權限問題:需要ACCESS_WIFI_STATE或者BLUETOOTH權限
  • 系統限制:為了保護用戶隱私,從Android 6.0開始將不能獲取WIFI和藍牙有效地Mac地址(02:0:00:00:00:0)
SERIAL

從Android 2.3 開始,可以獲取設備的硬件序列號

private String getSerialId(){
      return android.os.Build.SERIAL;
}

缺陷:
Bug:可能不存在序列號的情況

Sim Serial Number 獲取SIM卡的序列號
//uses-permission android:name="android.permission.READ_PHONE_STATE"
private String getSimSerialNumber() {
    TelephonyManager telephonyManager = (TelephonyManager) getSystemService(Context.TELEPHONY_SERVICE);
    String simSerialNumber = telephonyManager.getSimSerialNumber();
    return simSerialNumber;
}

缺陷:

  • 設備限制:僅裝有SIM卡的設備才能獲取到
  • 權限問題:調用方法需要READ_PHONE_STATE權限,特別是Android 6.0以后,權限需要用戶手動確認。
  • Bug :對于CDMA設備,返回的是一空值
Android ID

設備第一次啟動時產生和存儲的 64-bit 字符串

private String getAndroidId() {
    return Settings.Secure.getString(getContentResolver(), Settings.Secure.ANDROID_ID);
}

缺陷:

  • 恢復出廠設置后可能會重置該值。
  • 部分設備由于制造商錯誤實現,導致返回相同的 Android_ID 。
  • 在 Android 4.2 及以上,設備啟用多用戶功能后,每個用戶的 Android ID 不同。

UUID

全局唯一標識符,是指在一臺機器上生成的數字,它保證對在同一個時空中所有的機器都是唯一的

private String getUUID() {
    return java.util.UUID.randomUUID().toString();
}

缺陷:

  • 和設備無關,不同的應用會產生不同的ID,無法做到設備唯一

如何選擇設備標識符

  • 跟蹤用戶安裝,不需要嚴格意義上設備唯一的ID,使用UUID即可跟蹤用戶的安裝
  • 識別物理設備,使用多個硬件標識符進行拼裝
private String getUUID() {
    return md5(androidId()+serialNumber()+" ");
}

識別模擬器

public static boolean runnigOnEmulator() {
    if (!TextUtils.isEmpty(Build.MODEL) && Build.MODEL.toLowerCase().contains("sdk")) {
        return true;
    }
    if (!TextUtils.isEmpty(Build.MANUFACTURER) && Build.MANUFACTURER.toLowerCase().contains("unknown")) {
        return true;
    }
    if (!TextUtils.isEmpty(Build.DEVICE) && Build.DEVICE.toLowerCase().contains("generic")) {
        return true;
    }
    return false;
}

Demo下載

最后編輯于
?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。

推薦閱讀更多精彩內容

  • Android 自定義View的各種姿勢1 Activity的顯示之ViewRootImpl詳解 Activity...
    passiontim閱讀 172,820評論 25 708
  • 在上一篇谷歌博客 (識別應用安裝[http://www.lxweimin.com/p/a25111ee33dc])...
    totato閱讀 34,602評論 3 51
  • 概述 有時需要對用戶設備進行標識,所以希望能夠得到一個穩定可靠并且唯一的識別碼。雖然Android系統中提供了這樣...
    LeMou閱讀 6,557評論 0 14
  • ¥開啟¥ 【iAPP實現進入界面執行逐一顯】 〖2017-08-25 15:22:14〗 《//首先開一個線程,因...
    小菜c閱讀 6,497評論 0 17
  • Vue筆記系列1、Vue.js入門3、Vue.js進階 API 以下會隨用隨記一些API,可能會不定期更新。 Vu...
    其心閱讀 2,072評論 0 10