1. 程式人生 > >穩定獲取Android裝置唯一碼(UUID)的解決方案

穩定獲取Android裝置唯一碼(UUID)的解決方案

最近做的一個專案中需要用到Android裝置唯一碼(UUID)來標識一臺裝置,

Android中裝置唯一碼有很多,如:MAC地址、IMEI號(DeviceId)、IMSI號、ANDROID_ID、序列號(SerialNumber)等,

但並不是所有裝置上都能穩定獲取到這些值。

最後專案中採用的是MAC地址。

先總結一些搜尋得知的各種值的缺點,再說說最後採用MAC地址的解決方案吧。

1.MAC地址:

獲取MAC地址的方法有兩種:

(1). 通過Linux命令查詢

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 public String getMacAddress() {
String macAddress =null; String str =""; try{ //linux下查詢網絡卡mac地址的命令 Process pp = Runtime.getRuntime().exec("cat /sys/class/net/wlan0/address"); InputStreamReader ir =newInputStreamReader(pp.getInputStream()); LineNumberReader input =newLineNumberReader(ir); for(;null != str;) { str = input.readLine(); if(str !=
null) { macAddress = str.trim();// 去空格 break; } } }catch(IOException ex) { ex.printStackTrace(); } returnmacAddress; }

缺點:

在當前沒開啟WiFi的情況下獲取得到的MAC地址值為空,即使在執行這段程式碼前是有開啟過WiFi,而執行這段程式碼時WiFi狀態是關閉的,也不能獲取到MAC地址。

(2). 通過Android官方的WifiManager類獲取

1 2 3 4 5 6 7 8 9 10 11 public String getMacAddress() {
String macAddress =null; WifiManager wifiManager = (WifiManager)MyApplication.getContext().getSystemService(Context.WIFI_SERVICE); WifiInfo info = (null== wifiManager ?null: wifiManager.getConnectionInfo()); macAddress = info.getMacAddress(); returnmacAddress; }

需要加入許可權

1 <uses-permissionandroid:name="android.permission.ACCESS_WIFI_STATE"/>

缺點:

這種方法雖然能在當前Wifi狀態為關閉的情況下獲取到MAC地址,但前提是在手機開機後要開啟過一次Wifi,如果在某次開機後沒開啟過Wifi就呼叫這段程式碼,獲取地址也是為空。

網上給出的解釋是:WiFi的Mac address是一個被動資訊。一般在開機後,不會主動上報到系統裡。要待WiFi硬體啟動後,才會把有關Mac address資料記載入系統去。

2.IMEI號(DeviceId)、IMSI號:

1 2 3 TelephonyManager mTelephonyMgr = (TelephonyManager) getSystemServic(Context.TELEPHONY_SERVICE); String imsi = mTelephonyMgr.getSubscriberId(); //獲取IMSI號 String imei = mTelephonyMgr.getDeviceId(); //獲取IMEI號

需要加入許可權

1 <uses-permissionandroid:name="android.permission.READ_PHONE_STATE"/>

缺點:

IMEI號(國際移動裝置身份碼)、IMSI號(國際移動裝置識別碼)這兩個是有電話功能的移動裝置才具有,也就是說某些沒有電話功能的平板是獲取不到IMEI和IMSI號的。且在某些裝置上getDeviceId()返回垃圾資料。

3.ANDROID_ID:

ANDROID_ID 是裝置首次啟動時由系統隨機生成的一串64位的十六進位制數字。

1 String ANDROID_ID = Settings.System.getString(getContentResolver(), Settings.System.ANDROID_ID);

缺點:

①.裝置刷機wipe資料或恢復出廠設定時ANDROID_ID值會被重置。

②.現在網上已有修改裝置ANDROID_ID值的APP應用。

③.某些廠商定製的系統可能會導致不同的裝置產生相同的ANDROID_ID。

④.某些廠商定製的系統可能導致裝置返回ANDROID_ID值為空。

⑤.CDMA裝置,ANDROID_ID和DeviceId返回的值相同

4.序列號SerialNumber:

從Android 2.3開始,通過android.os.Build.SERIAL方法可獲取到一個序列號。沒有電話功能的裝置也都需要上給出此唯一的序列號。

1 String SerialNumber = android.os.Build.SERIAL;

缺點:

在某些裝置上此方法會返回垃圾資料。

解決方案:

一種比較折衷的辦法,在獲取MAC地址之前先判斷當前WiFi狀態,若開啟了Wifi,則直接獲取MAC地址,若沒開啟Wifi,則用程式碼開啟Wifi,然後馬上關閉,再獲取MAC地址。

目前此方法測試成功,無論在哪種狀態下都能正確取得裝置的MAC地址(包括開機後未啟動過Wifi的狀態下),且在未開啟Wifi的狀態下,用程式碼開啟Wifi並馬上關閉,過程極短,不會影響到使用者操作。

程式碼如下:

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 public String getMacAddress() { String macAddress =null; WifiManager wifiManager = (WifiManager)MyApplication.getContext().getSystemService(Context.WIFI_SERVICE); WifiInfo info = (null== wifiManager ?null: wifiManager.getConnectionInfo()); if(!wifiManager.isWifiEnabled()) { //必須先開啟,才能獲取到MAC地址 wifiManager.setWifiEnabled(true); wifiManager.setWifiEnabled(false); } if(null!= info) { macAddress = info.getMacAddress(); } returnmacAddress; }

需要加入如下許可權

1 2 3 <uses-permissionandroid:name="android.permission.ACCESS_WIFI_STATE"> </uses-permission> <uses-permissionandroid:name="android.permission.CHANGE_WIFI_STATE"> </uses-permission> <uses-permissionandroid:name="android.permission.WAKE_LOCK"> </uses-permission>