1. 程式人生 > >如何唯一的標識一臺Android裝置

如何唯一的標識一臺Android裝置

首先說結論我們到底能不能唯一的標識一臺Android裝置?很遺憾,暫時沒有一個很完美的方法能夠解決這個問題。Android開發者部落格的原文是:

Suppose you feel that for the needs of your application, you need an actual hardware device identifier. This turns out to be a tricky problem.

既然這樣,我們就來談談那些不太完美的方法。在這之前我們需要先知道幾個概念:

UUID : (Universally Unique Identifier)全域性唯一識別符號,是指在一臺機器上生成的數字,它保證對在同一時空中的所有機器都是唯一的。由以下幾部分的組合:當前日期和時間(UUID的第一個部分與時間有關,如果你在生成一個UUID之後,過幾秒又生成一個UUID,則第一個部分不同,其餘相同),時鐘序列,全域性唯一的IEEE機器識別號(如果有網絡卡,從網絡卡獲得,沒有網絡卡以其他方式獲得)。

IMEI : (International Mobile Equipment Identity) 是國際移動裝置身份碼的縮寫,國際移動裝備辨識碼,是由15位數字組成的"電子串號",它與每臺手機一一對應,而且該碼是全世界唯一的。

MEID :( Mobile Equipment IDentifier )是全球唯一的56bit CDMA制式移動終端標識號。標識號會被燒入終端裡,並且不能被修改。可用來對CDMA制式移動式裝置進行身份識別和跟蹤。

兩者的區別在於:IMEI是手機的身份證,MEID是CDMA制式(電信運營的)的專用身份證;IMEI是15位,MEID是14位。

DEVICE_ID

根據不同的手機裝置返回IMEI,MEID或者ESN碼,可以根據以下程式碼獲得:


Device_Id

非手機裝置:最開始搭載Android系統都手機裝置,而現在也出現了非手機裝置:如平板電腦、電視、音樂播放器等。這些裝置沒有通話的硬體功能,系統中也就沒有TELEPHONY_SERVICE,自然也就無法通過上面的方法獲得DEVICE_ID。

許可權問題:獲取DEVICE_ID需要READ_PHONE_STATE許可權,在Android 6.0上使用執行時動態授予許可權的機制,一旦使用者不給予授權,將獲取不到DEVICE_ID。 

廠商定製系統中的Bug:少數手機裝置上,由於該實現有漏洞,會返回垃圾(這是開發者部落格的原話,沒有實踐過)。

MAC ADDRESS


MAC_Address

可以使用手機WiFi或藍芽的MAC地址作為裝置標識,但是並不推薦這麼做,原因有以下兩點:

硬體限制:並不是所有的裝置都有WiFi和藍芽硬體,硬體不存在自然也就得不到這一資訊。

獲取的限制:如果WiFi沒有開啟過,是無法獲取其Mac地址的;而藍芽是隻有在開啟的時候才能獲取到其Mac地址。

Serial Number

硬體序列,在Android 2.2 以上可以通過 android.os.Build.SERIAL 獲得序列號。在一些沒有電話功能的裝置會提供,某些手機上也可能提供(所以就是經常會返回Unknown)

ANDROID_ID

ANDROID_ID是裝置第一次啟動時產生和儲存的64bit的一個數,當裝置被wipe後該數重置。


Android_Id

ANDROID_ID似乎是獲取Device ID的一個好選擇,但它也有缺陷:在主流廠商生產的裝置上,有一個很經常的bug,就是每個裝置都會產生相同的ANDROID_ID:9774d56d682e549c 。同時刷機,或者重置ANDROID_ID的值都會變化。

接下來就來看看實際的標識方法:

第一種:Installtion ID

在程式安裝後第一次執行時生成一個ID,該方式和裝置唯一標識不一樣,不同的應用程式會產生不同的ID,同一個程式重新安裝也會不同。所以這不是裝置的唯一ID,但是可以保證每個使用者的ID是不同的。 可以說是用來標識每一份應用程式的唯一ID(即Installtion ID),可以用來跟蹤應用的安裝數量等(其實就是UUID)。


Installtion Id 獲取方法

第二種:UniquePsuedoID

通過讀取裝置的ROM版本號、廠商名、CPU型號和其他硬體資訊來組合出一串15位的號碼和裝置硬體序列號作為種子生成UUID。一串15位的號碼(批量生產的裝置每項資訊基本相同,所以這一段相同的可能性特別高);硬體序列,在一些沒有電話功能的裝置會提供,某些手機上也可能提供(Devices without telephony are required to report a unique device ID here; some phones may do so also.),所以就是經常會返回Unknown。


UniquePsuedoID  獲取方法

第三種:Universal ID

首先通過讀取Android_id,作為UUID的種子。若得到Android_Id等於9774d56d682e549c或者 發生錯誤則random一個UUID作為備用方案,最後把得到的UUID同時存入內部儲存和外部儲存。下次使用UUID的時候優先從外部儲存讀取,再從背部儲存讀取,最後在重新生成,儘可能的保證其不變性。


Universal_id獲取方法