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

Android 獲取裝置唯一ID

只能在安卓手機上,需要支援Sim晶片,需要在AndroidManifest.xml中加入一個許可:android.permission.READ_PHONE_STATE,並且使用者應當允許安裝此應用。作為手機來講,IMEI是唯一的,它應該類似於 359881030314356(除非你有一個沒有量產的手機(水貨)它可能有無效的IMEI,如:0000000000000)。注意:在雙卡雙待的手機上imei不是唯一,因為有2個還有getDeviceId在電信卡上得到的是meid,和imei完全不一樣。
獲取辦法:
String serialNum = android.os.Build.SERIAL;
裝有SIM卡的裝置獲取辦法:getSystemService(Context.TELEPHONY_SERVIEC).getSimSerialNumber();

 private String getImei(){
        TelephonyManager TelephonyMgr = (TelephonyManager)getSystemService(TELEPHONY_SERVICE);
        String szImei = TelephonyMgr.getDeviceId();
        return szImei;
    }

android ID常被認為不可信,因為它有時為null。開發文件中說明了:這個ID會改變如果進行了出廠設定。並且,如果某個Andorid手機被Root過的話,這個ID也可以被任意改變。

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

獲取wlan晶片的mac地址,是另一個唯一ID。但是你需要為你的工程加入android.permission.ACCESS_WIFI_STATE 許可權,否則這個地址會為null。
不需要開啟wifi

 private String getWlanId
(){ WifiManager wm = (WifiManager)getSystemService(getApplicationContext().WIFI_SERVICE); String m_szWLANMAC = wm.getConnectionInfo().getMacAddress(); return m_szWLANMAC; }

獲取藍芽晶片的mac地址,只在有藍芽的裝置上執行。並且要加入android.permission.BLUETOOTH 許可權,不需要開啟藍芽

  private String getBlueTooth(){
        BluetoothAdapter m_BluetoothAdapter = null; // Local Bluetooth adapter
        m_BluetoothAdapter = BluetoothAdapter.getDefaultAdapter();
        String m_szBTMAC = m_BluetoothAdapter.getAddress();
        return m_szBTMAC;
    }

Pseudo-Unique ID, 這個在任何Android手機中都有效
有一些特殊的情況,一些如平板電腦的設定沒有通話功能,或者你不願加入READ_PHONE_STATE許可。而你仍然想獲得唯一序列號之類的東西。這時你可以通過取出ROM版本、製造商、CPU型號、以及其他硬體資訊來實現這一點。這樣計算出來的ID不是唯一的(因為如果兩個手機應用了同樣的硬體以及Rom 映象)。但應當明白的是,出現類似情況的可能性基本可以忽略。要實現這一點,你可以使用Build類:

  private String getPseudo(){
        String m_szDevIDShort = "35" + "/"+//we make this look like a valid IMEI

                Build.BOARD.length()%10 +"/"+
                Build.BRAND.length()%10 +"/"+
                Build.CPU_ABI.length()%10 +"/"+
                Build.DEVICE.length()%10 +"/"+
                Build.DISPLAY.length()%10 +"/"+
                Build.HOST.length()%10 +"/"+
                Build.ID.length()%10 +"/"+
                Build.MANUFACTURER.length()%10 +"/"+
                Build.MODEL.length()%10 +"/"+
                Build.PRODUCT.length()%10 +"/"+
                Build.TAGS.length()%10 +"/"+
                Build.TYPE.length()%10 +"/"+
                Build.USER.length()%10+"/"; //13 digits
        return m_szDevIDShort;
    }
android.os.Build.BOARD:獲取裝置基板名稱
android.os.Build.BOOTLOADER:獲取裝置載入程式版本號
android.os.Build.BRAND:獲取裝置品牌
android.os.Build.CPU_ABI:獲取裝置指令集名稱(CPU的型別)
android.os.Build.CPU_ABI2:獲取第二個指令集名稱
android.os.Build.DEVICE:獲取裝置驅動名稱
android.os.Build.DISPLAY:獲取裝置顯示的版本包(在系統設定中顯示為版本號)和ID一樣
android.os.Build.FINGERPRINT:裝置的唯一標識。由裝置的多個資訊拼接合成。
android.os.Build.HARDWARE:裝置硬體名稱,一般和基板名稱一樣(BOARD)
android.os.Build.HOST:裝置主機地址
android.os.Build.ID:裝置版本號。
android.os.Build.MODEL :獲取手機的型號 裝置名稱。
android.os.Build.MANUFACTURER:獲取裝置製造商
android:os.Build.PRODUCT:整個產品的名稱
android:os.Build.RADIO:無線電韌體版本號,通常是不可用的 顯示unknown
android.os.Build.TAGS:裝置標籤。如release-keys 或測試的 test-keys 
android.os.Build.TIME:時間
android.os.Build.TYPE:裝置版本型別  主要為"user""eng".
android.os.Build.USER:裝置使用者名稱 基本上都為android-build
android.os.Build.VERSION.RELEASE:獲取系統版本字串。如4.1.22.22.3等
android.os.Build.VERSION.CODENAME:裝置當前的系統開發代號,一般使用REL代替
android.os.Build.VERSION.INCREMENTAL:系統原始碼控制值,一個數字或者git hash值
android.os.Build.VERSION.SDK:系統的API級別 一般使用下面大的SDK_INT 來檢視
android.os.Build.VERSION.SDK_INT:系統的API級別 數字表示

裝置唯一標識碼還是以utdid做標識,但是在Android6.0+系統上,外儲存許可權越來越難獲取和越來越不可靠的情況下,除考慮加入LocalSocket和Broadcast等機制做多應用間的utdid同步(問題也很明顯)外,必須依賴網路,構建裝置ID庫來提升裝置標識的可靠性。
因此需要考慮在伺服器上建立utdid與各裝置資料間的對應關係,通過做大規模的適配和資料上報,來解決問題。通過可獲得手機引數做伺服器請求,伺服器的utdid與各裝置資料間的對應關係表來尋找最匹配utdid值。
可以考慮的資料關係體系是以Wifi Mac地址、裝置序列號、ANDROID_ID為主要基準,配合android.os.Build中手機基本資訊為參考(用手機root相關資訊採集做修正),DEVICE_ID(用READ_PHONE_STATE許可權做修正),常用ip地址等。如果可以的話,還可以參考手機號碼、業務登入賬號等。目前只是一些初步想法,可行性還有待實際資料驗證,方案還在探索階段。