由于項(xiàng)目需要痊项,最近在調(diào)用Android設(shè)備唯一標(biāo)識(shí)符方案胳赌。由于項(xiàng)目涉及支付相關(guān)內(nèi)容,對(duì)設(shè)備唯一標(biāo)識(shí)符識(shí)別有較高的準(zhǔn)確率要求夏醉。而考慮到項(xiàng)目app在海外運(yùn)營(yíng)姚糊,主要通過google play store發(fā)布,而google由于GDPR等政策最近對(duì)設(shè)備標(biāo)識(shí)符采集進(jìn)行了嚴(yán)控授舟,如何才能在不采集用戶危險(xiǎn)權(quán)限的前提下救恨,準(zhǔn)確唯一的標(biāo)識(shí)到用戶的設(shè)備呢?這里分享下方案輸出前期的一些調(diào)研內(nèi)容释树。
IMEI/MEID/Device ID
國(guó)際移動(dòng)設(shè)備識(shí)別碼(International Mobile Equipment Identity肠槽,IMEI)
國(guó)際移動(dòng)設(shè)備識(shí)別碼一般貼于機(jī)身背面與外包裝上,同時(shí)也存在于手機(jī)內(nèi)存中奢啥,通過輸入*#06#即可查詢
GSM設(shè)備返回的是IMEI碼秸仙,CDMA設(shè)備返回的是MEID碼或者ESN碼
雙卡雙待手機(jī)存在兩個(gè),需根據(jù)具體硬件適配獲取
只有Android手機(jī)才有桩盲,非手機(jī)設(shè)備沒有
需要權(quán)限:android.permission.READ_PHONE_STATE
TelephonyManager TelephonyMgr = (TelephonyManager)getSystemService(TELEPHONY_SERVICE);
String szImei = TelephonyMgr.getDeviceId();
IMSI
國(guó)際移動(dòng)用戶識(shí)別碼(IMSI:International Mobile Subscriber Identification Number)
儲(chǔ)存在SIM卡中, 跟SIM卡綁定的寂纪,更換SIM卡就會(huì)發(fā)生變化
在僅支持wifi的pad設(shè)備上是沒有的
需要權(quán)限:android.permission.READ_PHONE_STATE
TelephonyManager manager = (TelephonyManager) context.getSystemService(Context.TELEPHONY_SERVICE);
String imsi = manager.getSubscriberId();
Android ID
在設(shè)備首次啟動(dòng)時(shí),系統(tǒng)會(huì)隨機(jī)生成一個(gè)64位的數(shù)字,并把這個(gè)數(shù)字以16進(jìn)制字符串的形式保存下來捞蛋,即Android id
恢復(fù)出廠設(shè)置孝冒,重新生成
root手機(jī),可以改寫
部分廠商bug拟杉,導(dǎo)致補(bǔ)發(fā)機(jī)型上Android id相同
不需要權(quán)限庄涡,與系統(tǒng)強(qiáng)依賴,穩(wěn)定性不足
String m_szAndroidID = Secure.getString(getContentResolver(), Secure.ANDROID_ID);
MAC地址
手機(jī)wifi無線網(wǎng)卡的MAC地址搬设,與終端硬件關(guān)聯(lián)穴店,可用作設(shè)備的唯一標(biāo)識(shí)
從Android 6.0開始,系統(tǒng)接口采集到的MAC地址返回固定串:02:00:00:00:00:00
未連wifi獲取不到拿穴,需要權(quán)限: android.permission.ACCESS_WIFI_STATE
WifiManager wm = (WifiManager)getSystemService(Context.WIFI_SERVICE);
String m_szWLANMAC = wm.getConnectionInfo().getMacAddress();
藍(lán)牙MAC
從Android 6.0開始泣洞,系統(tǒng)接口統(tǒng)一返回:02:00:00:00:00:00
需要權(quán)限: android.permission.BLUETOOTH
BluetoothAdapter m_BluetoothAdapter = null;
m_BluetoothAdapter = BluetoothAdapter.getDefaultAdapter();
String m_szBTMAC = m_BluetoothAdapter.getAddress();
Pseudo-Unique ID
API<9時(shí),通過讀取設(shè)備的ROM版本號(hào)默色、廠商名球凰、CPU型號(hào)和其他硬件信息來組合出一串15位的號(hào)碼
API >=9時(shí),通過“Build.SERIAL”這個(gè)屬性來保證ID的獨(dú)一無二
//獲得獨(dú)一無二的Psuedo ID
public static String getUniquePsuedoID() {
String serial = null;
String m_szDevIDShort = "35" +
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 位
try {
serial = android.os.Build.class.getField("SERIAL").get(null).toString();
//API>=9 使用serial號(hào)
return new UUID(m_szDevIDShort.hashCode(), serial.hashCode()).toString();
} catch (Exception exception) {
//serial需要一個(gè)初始化,隨意值
serial = "serial";
}
//使用硬件信息拼湊出來的15位號(hào)碼
return new UUID(m_szDevIDShort.hashCode(), serial.hashCode()).toString();
存在問題
翻看Build.class的源碼该窗,可以發(fā)現(xiàn)字段SERIAL已經(jīng)被標(biāo)注為@Deprecated了,google建議通過新接口getSerial獲取手機(jī)的序列號(hào)蚤霞。這里存在問題:
- 被標(biāo)注為@Deprecated的SERIAL以后可能被google下掉(或加入黑名單)酗失,后續(xù)通過反射或許拿不到。
-
getSerial接口需要READ_PHOE_STATE權(quán)限
企業(yè)微信截圖_15560952357236.png
參考