個人淺談 Android設備唯一識別方案(待續~)

說明

在項目中,爲了統計用戶登錄設備數以及日活,獲取設備的惟一標識是一個很常見的需求,以前常用的一種方式是通過獲取當前設備的device_id。

但是這種方式存在一些問題。首先它是需要權限的,所有很多時候,你可能會獲取不到 device_id。特別是在 Android 6.0 後,在很大國產的 ROM 裏,

都可以在系統設置裏,修改相關的權限,來禁止應用程序獲取 device_id,Android Q以後只允許系統簽名的應用獲取device_id

  1. 現有方案
    現在我們的應用通過強制授權的方式獲取中device_id作爲設備標識符,這個device_id保存在App應用內 ,device_id不會隨着設備重置發生變化。

    device_id 通過 TelephonyManager.getDeviceId()獲取,獲取前必須先申請 READ_PHONE_STATE 權限。

  2. Android Q對現方案的影響
    Android Q開始 新增了權限READ_PRIVILEGED_PHONE_STATE並且刪除了READ_PHONE_STATE,應用必須擁有 READ_PRIVILEGED_PHONE_STATE才能獲取device_id;

    而這個權限普通應用是獲取不到的,這個權限只開放給系統級應用如果沒有該權限但卻嘗試去獲取這些標識符的話,根據應用目標版本的不同會有所不同:

    應用的目標版本爲 Android Q(targetSdkVersion = Q),會拋出 SecurityException ,這是一個運行時異常,會導致應用崩潰;

    應用的目標版本爲 Android 9.0 或更低(targetSdkVersion < Q),如果應用擁有 READ_PHONE_STATE權限,會返回 null 或佔位符數據(比如 Unknown),否則的話也會拋出 SecurityException。

  3. 關於android_id
    android_id是當設備在第一次啓動時,系統會隨機產生一個64位的數字,然後以16進制的形式保存在設備上,系統API提供了獲取這一參數的方法:

    Settings.System.getString(context.getContentResolver(), Settings.System.ANDROID_ID);

    android_id存在的一些問題:

    • 當設備刷機android_id會被重置
    • 不同的設備可能會產生相同的android_id
    • 對於CDMA的設備,android_id和device_id的值相同
    • 有極少部分國產定製ROM有可能獲取android_id值爲null的情況
  4. 最終方案
    通過以上知道android device_id 在Android Q上面是無法獲取的,我們在App啓動的時候判斷當前系統的版本號,當前系統版本號 < Q時

    走授權詢問READ_PHONE_STATE權限,獲取device_id保存本地,若deviceId爲空或者當前系統版本號>=Q時,通過系統API獲取android_id,判斷android_id是否爲空,

    不爲空保存在本地,供全局使用,爲空本地生成UUID並且在頭部拼上UUID標識

方案的影響:
Android Q以下還是老的設備唯一識別方案device id,若用戶通過OTA升級到Android Q,若程序不卸載重裝的或者不通過系統設置清除應用數據,

方案不變使用device id,反之獲取android id,android id爲空則使用本地生成的uuid並且拼上相關標識

方案流程圖參考下方:

在這裏插入圖片描述

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章