手機唯一標識生成方案
首先,就目前掌握的資料來看,該問題沒有徹底的解決方案。網路資料很多,主要分為4類。建議採用方案4。
方案一:Android裝置標識或裝置硬體資訊
常用的有:
1)藍芽/Wifi的Mac地址、IMSI、sim卡序列號;
2)CPU 的名稱、核數、頻率,Ram大小、Rom大小、螢幕解析度,CPU的序列號在目前的測試裝置中,顯示為一串0;
3)device_id、android_id、serialno。
首先,有些在Android低版本(2.1到2.3)不穩定。其次,上面的幾類各有缺點:
第1類受使用者行為影響較大,比如開關wifi或藍芽,插拔sim卡;
第2類表徵能力差,同一型號手機中,這些特點沒有區分度;
第3類是推薦的,但不能抵抗wipe,其中android_id的生成是以serialno為基礎的。
方案二:採用UUID跟蹤特定安裝,不必繫結具體的裝置
隨機生成UUID,在本地儲存。不做贅述。詳見:
方案三:Android Backup Service
AndroidBackup Service provides a backup transport for Android's data backup framework,which allows you to copy a user's persistent app data to remote "cloud" storage. 未做深入研究。
詳見:
方案四:方案1和方案2的結合
這種方法是,以一些特定的資訊為基礎,生成裝置的唯一標識。
首先,演算法角度,常用的有UUID、摘要兩種。這兩種演算法都是以特定的資料為基礎,生成一個唯一的、固定長度的字串。這裡選擇UUID。
其次,計算的基礎資料,建議選擇divice_id和android_id。原因是,1)這兩個標識雖然不能抵抗wipe操作,但受使用者的行為影響比較小;2)如果正常獲取,都是唯一的;③如果不能正常獲取,結果也是固定的,不會頻繁變化。
再次,優先順序的考慮。從這兩個標識的缺點考慮。
1)device_id。
①不能標識非手機裝置,例如Pad。
②許可權問題,因為使用者的反感。
③獲取異常,廠商定製系統中存在的bug,致使返回結果為空,或者為一串“0”或“*”。
④對於雙卡雙待手機,會返回兩個device_id。
2)android_id。
①Android2.3以前,系統Bug,導致不同的裝置產生相同的結果:9774d56d682e549c。
②有些可能返回null。
③裝置差異:對於CDMA裝置,與device_id返回相同的值。
綜合考慮,device_id不能標識某些pad,以及使用者的許可權問題,是我們不能接受的,所以優先使用android_id。對於android_id返回為null的情況,再考慮使用device_id。
最後,當android_id和device_id都返回異常的情況,我們可以隨機生成一個UUID。
關於android_id的生成機制見參考資料:
主要程式碼
主要程式碼如下,詳見Demo程式。
private String getUUID(){
UUID uuid;
String androidId = android_id;
try {
if(!"9774d56d682e549c".equals(androidId)) {
//在Android2.3版本之前才會有這個問題。
uuid = UUID.nameUUIDFromBytes(androidId.getBytes("utf8"));
} else {
String deviceId = device_id;
uuid = deviceId != null ?UUID.nameUUIDFromBytes(deviceId.getBytes("utf8")) :UUID.randomUUID();
}
} catch (UnsupportedEncodingExceptione) {
throw new RuntimeException(e);
}
return uuid.toString();
}
測試結果
根據在現有測試機上的測試結果,android_id可以正常獲取到,所以生成的UUID都是以此為基礎的。
以下是測試結果資料。
手機型號:GT-I9300I
android_id:c3bec6b0ed7cbc20
device_id:359776058450570
andr_uuid:f205bf07-ee2f-3d27-b3ff-c8db52bed45c
dev_uuid:915c5b80-2368-3fa4-85aa-c1316d852be2
UUID:f205bf07-ee2f-3d27-b3ff-c8db52bed45c
手機型號:HONORH30-L01
android_id:4e5d03bca1d55673
device_id:864502020279410
andr_uuid:89101b66-2d8a-3f82-8bc2-cfba09edff7c
dev_uuid:0fc0f0d0-0b82-3476-a674-0e285427c650
UUID:89101b66-2d8a-3f82-8bc2-cfba09edff7c
手機型號:vivoS7i(t)
android_id:b0374e0856f27689
device_id:863880029053270
andr_uuid:1cf7fb3f-f836-3510-9fe2-ee08cd9b1cd2
dev_uuid:34053b22-f29b-3039-a593-23f534a0207c
UUID:1cf7fb3f-f836-3510-9fe2-ee08cd9b1cd2
手機型號:GT-S7572
android_id:c09ff3a16a57e6bc
device_id:358905059907129
andr_uuid:da400450-c131-3399-be5e-facfc0866ceb
dev_uuid:077c827d-96c6-3d4f-b508-283c1cdd6e0f
UUID:da400450-c131-3399-be5e-facfc0866ceb
手機型號:HUAWEIY320-T00
android_id:4d40a1dfa74973c5
device_id:860271022990473
andr_uuid:77fe6e20-5afe-37ec-b916-f11be3b9dbf5
dev_uuid:e6ef768a-9398-33aa-a925-15c7696deef5
UUID:77fe6e20-5afe-37ec-b916-f11be3b9dbf5
手機型號:HTCSensation XE with Beats Audio Z715e
android_id:c5dc41f5caabe5d2
device_id:358313045847881
andr_uuid:e282e4f1-70ed-3d95-af5b-ebdfd2c90a28
dev_uuid:133095a2-0f3e-325b-ada5-b486fb351e0a
UUID:e282e4f1-70ed-3d95-af5b-ebdfd2c90a28
不足之處與改進
就目前的調研結果,對android_id飽受詬病的地方是,wipe之後會變化或者無法得到正常返回。device_id在wipe之後,有說有影響的,有說不變化的。
再考慮到device_id的許可權申請問題、不能標識非手機的移動裝置等問題,建議只用android_id即可,如果android_id不能正常返回,則隨機生成一個。
最後,選擇android_id與device_id而非其它的硬體資訊的原因已經在方案一中提到。雖然android_id是基於serialno生成,而後者也是一種硬體資訊,但這受wipe的影響,並不是不變的。
如果堅持要從硬體角度唯一的標識裝置,恐怕還要從wifi與藍芽mac地址等角度考慮,而這受使用者的行為影響較大。比如,註冊時同時取得mac與sim卡序列號,根據兩者確定一個準則;後續對裝置的確定方法,在wifi下采用mac,在2G/3G下根據sim序列號。