国产 无码 综合区,色欲AV无码国产永久播放,无码天堂亚洲国产AV,国产日韩欧美女同一区二区

Android 如何獲取有效的DeviceId

這篇具有很好參考價值的文章主要介紹了Android 如何獲取有效的DeviceId。希望對大家有所幫助。如果存在錯誤或未考慮完全的地方,請大家不吝賜教,您也可以點擊"舉報違法"按鈕提交疑問。

android 獲取設(shè)備id,android開發(fā),android

前言

從 Android 10 開始,應(yīng)用必須具有 READ_PRIVILEGED_PHONE_STATE 特許權(quán)限才能訪問設(shè)備的不可重置標(biāo)識符(包含 IMEI 和序列號)。

而這個權(quán)限是系統(tǒng)權(quán)限,也就是說一般應(yīng)用將無法再獲取IMEI 和序列號

受影響的方法包括:

  • Build

    • getSerial()
  • TelephonyManager

    • getImei()
    • getDeviceId()
    • getMeid()
    • getSimSerialNumber()
    • getSubscriberId()

如果您的應(yīng)用沒有該權(quán)限,但您仍嘗試查詢不可重置標(biāo)識符的相關(guān)信息,則平臺的響應(yīng)會因目標(biāo) SDK 版本而異:

  1. 如果應(yīng)用以 Android 10 或更高版本為目標(biāo)平臺,則會發(fā)生 SecurityException。
  2. 如果應(yīng)用以 Android 9(API 級別 28)或更低版本為目標(biāo)平臺,則相應(yīng)方法會返回 null 或占位符數(shù)據(jù)(如果應(yīng)用具有 READ_PHONE_STATE 權(quán)限)。否則,會發(fā)生 SecurityException。

google也給出了一個解決方案

許多使用場景都不需要不可重置的設(shè)備標(biāo)識符。例如,如果您的應(yīng)用將不可重置的設(shè)備標(biāo)識符用于廣告跟蹤或用戶分析目的,請為這些特定使用場景使用 Android 廣告 ID。要了解詳情,請參閱唯一標(biāo)識符的最佳做法。

這里大部分方案對國內(nèi)無效,比如廣告ID,需要google play的服務(wù),但是國內(nèi)的手機上都閹割掉了。所以我們只能參考一些可用的方案。

官方唯一標(biāo)識符建議

這部分我們一起來看官方唯一標(biāo)識的建議

使用廣告 ID

國內(nèi)就不要考慮了,需要依賴google play服務(wù)

使用實例 ID 和 GUID

只對單一應(yīng)用有效,卸載了就變了,不可取。

不要使用 MAC 地址

MAC 地址具有全局唯一性,無法由用戶重置,在恢復(fù)出廠設(shè)置后也不會變化。因此,一般不建議使用 MAC 地址進行任何形式的用戶標(biāo)識。運行 Android 10(API 級別 29)和更高版本的設(shè)備會報告不是設(shè)備所有者應(yīng)用的所有應(yīng)用的隨機化 MAC 地址。

在 Android 6.0(API 級別 23)到 Android 9(API 級別 28)中,無法通過第三方 API 使用 Wi-Fi 和藍牙等本地設(shè)備 Mac 地址。WifiInfo.getMacAddress() 方法和 BluetoothAdapter.getDefaultAdapter().getAddress() 方法都返回 02:00:00:00:00:00。

此外,在 Android 6.0 到 Android 9 版本中,您還必須擁有下列權(quán)限,才能訪問通過藍牙和 Wi-Fi 掃描獲得的附近外部設(shè)備的 MAC 地址:

方法/屬性 所需權(quán)限
WifiManager.getScanResults() ACCESS_FINE_LOCATION 或 ACCESS_COARSE_LOCATION
BluetoothDevice.ACTION_FOUND ACCESS_FINE_LOCATION 或 ACCESS_COARSE_LOCATION
BluetoothLeScanner.startScan(ScanCallback) ACCESS_FINE_LOCATION 或 ACCESS_COARSE_LOCATION

所以,mac是僅次于DeviceId的靠譜的標(biāo)識,不過android 6.0之后獲取不到了。不過有其他方法完善,見后面。

標(biāo)識符特性

一堆廢話

常見用例和適用的標(biāo)識符

也是一堆廢話,要么就是國內(nèi)無法使用,不過提到了SSAID。

SSAID,即ANDROID_ID(Settings.Secure.ANDROID_ID),在8.0系統(tǒng)迎來改變,具體如下:

對于在 OTA 之前安裝到某個版本 Android 8.0(API 級別 26)的應(yīng)用,除非在 OTA 后卸載并重新安裝,否則 ANDROID_ID 的值將保持不變。要在 OTA 后在卸載期間保留值,開發(fā)者可以使用密鑰/值備份關(guān)聯(lián)舊值和新值。

對于安裝在運行 Android 8.0 的設(shè)備上的應(yīng)用,ANDROID_ID 的值現(xiàn)在將根據(jù)應(yīng)用簽署密鑰和用戶確定作用域。應(yīng)用簽署密鑰、用戶和設(shè)備的每個組合都具有唯一的 ANDROID_ID 值。因此,在相同設(shè)備上運行但具有不同簽署密鑰的應(yīng)用將不會再看到相同的 Android ID(即使對于同一用戶來說,也是如此)。

只要簽署密鑰相同(并且應(yīng)用未在 OTA 之前安裝到某個版本的 O),ANDROID_ID 的值在軟件包卸載或重新安裝時就不會發(fā)生變化。

即使系統(tǒng)更新導(dǎo)致軟件包簽署密鑰發(fā)生變化,ANDROID_ID 的值也不會變化。

可以看到8.0之后ANDROID_ID是與應(yīng)用簽名關(guān)聯(lián)的,同簽名的應(yīng)用共用相同的ANDROID_ID,而且卸載重裝不會變化。

而8.0之前,ANDROID_ID是與設(shè)備關(guān)聯(lián)的,當(dāng)設(shè)備首次啟動時,系統(tǒng)會隨機生成一個64位的數(shù)字,并以16進制字符串的形式保存到手機系統(tǒng)中,當(dāng)手機恢復(fù)出廠設(shè)置后,Android ID會被重置,這是Android ID與Device ID的主要區(qū)別。當(dāng)然還有其他bug,比如有些廠家獲取為null之類的。

所以,ANDROID_ID是可以考慮的選擇之一,后面細說。

解決方案

想要一個行為獲取穩(wěn)定的DeviceId是不可能的,我們需要多個行為結(jié)合處理。

DeviceId

首先就是傳統(tǒng)的DeviceId,在Android 10一下還是很穩(wěn)定的。

ANDROID_ID

在Android 8.0之后,就可以考慮用ANDROID_ID來代替DeviceId了。

Settings.System.getString(BaseApp.getAppContext().getContentResolver(), Settings.Secure.ANDROID_ID);

這樣可以做一個版本判斷,低于10.0(或8.0)獲取DeviceId,否則獲取ANDROID_ID

Mac地址

如果上面兩步獲取的還是null,那么可以使用mac地址,但是mac由于6.0之后無法通過WifiInfo.getMacAddress()獲取了,所以我們需要處理一下,代碼如下:

public static String getMac(Context context) {
    String mac = "";
    if (context == null) {
        return mac;
    }
    if (Build.VERSION.SDK_INT < 23) {
        mac = getMacBySystemInterface(context);
    } else {
        mac = getMacByJavaAPI();
        if (TextUtils.isEmpty(mac)){
            mac = getMacBySystemInterface(context);
        }
    }
    return mac;

}

@TargetApi(9)
private static String getMacByJavaAPI() {
    try {
        Enumeration<NetworkInterface> interfaces = NetworkInterface.getNetworkInterfaces();
        while (interfaces.hasMoreElements()) {
            NetworkInterface netInterface = interfaces.nextElement();
            if ("wlan0".equals(netInterface.getName()) || "eth0".equals(netInterface.getName())) {
                byte[] addr = netInterface.getHardwareAddress();
                if (addr == null || addr.length == 0) {
                    return null;
                }
                StringBuilder buf = new StringBuilder();
                for (byte b : addr) {
                    buf.append(String.format("%02X:", b));
                }
                if (buf.length() > 0) {
                    buf.deleteCharAt(buf.length() - 1);
                }
                return buf.toString().toLowerCase(Locale.getDefault());
            }
        }
    } catch (Throwable e) {
    }
    return null;
}

private static String getMacBySystemInterface(Context context) {
    if (context == null) {
        return "";
    }
    try {
        WifiManager wifi = (WifiManager) context.getSystemService(Context.WIFI_SERVICE);
        if (checkPermission(context, Manifest.permission.ACCESS_WIFI_STATE)) {
            WifiInfo info = wifi.getConnectionInfo();
            return info.getMacAddress();
        } else {
            return "";
        }
    } catch (Throwable e) {
        return "";
    }
}

可以看到6.0即23以下直接獲取,否則先通過NetworkInterface獲取,獲取不到再通過原方法獲取。
目前來看這一步還是能穩(wěn)定獲取的。

UUID

兜底行為。因為需要我們手動生成,且每次生成的都不一樣。

UUID.randomUUID().toString()

所以必須生成一次保存起來。這樣就有一個問題,如果保存到應(yīng)用內(nèi)部存儲,卸載后重裝一定要重新生成,這樣就無法判斷是同一設(shè)備了。

所以最好將其保存到外部存儲,保證卸載重裝后還能讀取到上次的值。

這樣一般情況下是最穩(wěn)定的,除非手動刪除該文件。

所以最好的方案,就是將上面四個方案融合在一起,一個個兜底。目前來看,各手機廠商的指導(dǎo)方案也就這幾個方案。

補充

除了上面的方案,還有移動安全聯(lián)盟(信通院牽頭)提供的sdk,可以獲取幾種設(shè)備標(biāo)識符,大部分國內(nèi)廠商都支持。

不過需要申請使用,還沒測試過。

總結(jié)

通過上面分析可以看到,官方確實給出了不少替代方案,但是大部分都由于國內(nèi)的限制而無法使用。所以國內(nèi)基本上都是通過依次獲取DeviceId、ANDROID_ID、MAC、UUID的方式來得到一個唯一id,流程大致如下:

你可能感興趣:
Android 13發(fā)布,一起來看看有哪些新功能

詳細解讀Android中的事件分發(fā)機制文章來源地址http://www.zghlxwxcb.cn/news/detail-597940.html

到了這里,關(guān)于Android 如何獲取有效的DeviceId的文章就介紹完了。如果您還想了解更多內(nèi)容,請在右上角搜索TOY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!

本文來自互聯(lián)網(wǎng)用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務(wù),不擁有所有權(quán),不承擔(dān)相關(guān)法律責(zé)任。如若轉(zhuǎn)載,請注明出處: 如若內(nèi)容造成侵權(quán)/違法違規(guī)/事實不符,請點擊違法舉報進行投訴反饋,一經(jīng)查實,立即刪除!

領(lǐng)支付寶紅包贊助服務(wù)器費用

相關(guān)文章

  • 【Flutter】如何在 Flutter 中獲取設(shè)備 ID

    在移動應(yīng)用開發(fā)中,有時我們需要獲取設(shè)備的唯一標(biāo)識符,也就是設(shè)備 ID。設(shè)備 ID 可以幫助我們進行用戶跟蹤、分析用戶行為、推送通知等。在這篇文章中,我們將討論如何在 Flutter 中獲取設(shè)備 ID

    2024年02月09日
    瀏覽(17)
  • Android 設(shè)備 設(shè)置adb自動監(jiān)聽tcp 5555端口,重啟有效

    Android 設(shè)備 設(shè)置adb自動監(jiān)聽tcp 5555端口,重啟有效

    Android 設(shè)備調(diào)試有兩種連線方式:有線和無線; 有線是通過USB導(dǎo)線連接android設(shè)備和電腦端,無線方式是通過連接WIFI,通過TCP的方式,連接設(shè)備和電腦端,一般用 5555端口; 有線的調(diào)節(jié),只需要打開調(diào)試模式基本就可以了,無線連接方式比有線多一步操作,就是需要先通過usb導(dǎo)線連接后,ad

    2024年02月08日
    瀏覽(19)
  • Android 判斷當(dāng)前設(shè)備是手機還是平板的最有效的方法【2022版】

    之前已經(jīng)寫過一篇文章介紹了,詳見《Android 判斷當(dāng)前設(shè)備是手機還是平板的最有效的方法》 但是經(jīng)過一段的時間的使用,發(fā)現(xiàn)在一些學(xué)習(xí)機上會出現(xiàn)誤判。學(xué)習(xí)機明明是10英寸的,但是代碼算出來的結(jié)果卻是5英寸。我猜應(yīng)該是學(xué)習(xí)機的硬件信息有誤造成的。竟然會誤判,那

    2024年02月13日
    瀏覽(19)
  • Android獲取手機設(shè)備信息

    Android獲取手機設(shè)備信息 在Android應(yīng)用開發(fā)中,我們經(jīng)常需要獲取手機設(shè)備的信息來做一些個性化的邏輯處理。本文將介紹如何使用Android提供的API獲取手機設(shè)備信息,并給出相應(yīng)的源代碼示例。 獲取設(shè)備型號 設(shè)備型號可以幫助我們了解用戶所使用的具體設(shè)備類型,從而做出一

    2024年01月25日
    瀏覽(19)
  • Android Google登錄并獲取token(親測有效)

    背景: Android 需要用到Google的登錄授權(quán),用去token給到服務(wù)器,服務(wù)器再通過token去獲取用戶信息,實現(xiàn)第三方登錄。 我們通過登錄之后的email來獲取token,不需要server_clientId;如果用server_clientId還需要在google的控制臺配置測試的賬號,否則登錄的時候會返回錯誤碼10. 實現(xiàn)步驟

    2024年02月02日
    瀏覽(24)
  • Android 獲取設(shè)備的CPU型號和設(shè)備型號

    原文: Android 獲取設(shè)備的CPU型號和設(shè)備型號-Stars-One的雜貨小窩 之前整的項目的總結(jié)信息,可能不太全,湊合著用吧,代碼在最下面一節(jié) 華為: ro.mediatek.platform vivo: ro.vivo.product.platform oppo: ro.board.platform 或 ro.product.board 三星: ro.board.platform 小米: ro.soc.model 小米: GKI 2.0 之前,/proc/cpuin

    2024年03月11日
    瀏覽(13)
  • Android12以上獲取設(shè)備網(wǎng)絡(luò)信號數(shù)據(jù)

    Android12以上獲取設(shè)備網(wǎng)絡(luò)信號數(shù)據(jù)

    公司有很多物聯(lián)網(wǎng)設(shè)備,關(guān)鍵的信號參數(shù)是RSRP,總有些地方信號差,不適合安裝。所以讓開發(fā)一款測信號的app,用于現(xiàn)場的同事在判定是否符合設(shè)備信號條件,再考慮安裝設(shè)備。 由于與開發(fā)過程中使用的是Android sdk33,版本太高,網(wǎng)上搜到的很多舊的方法已經(jīng)棄用,用起來也

    2024年01月17日
    瀏覽(17)
  • android開發(fā)獲取手機麥克風(fēng)設(shè)備信息

    android開發(fā)獲取手機麥克風(fēng)設(shè)備信息

    之前為了測試藍牙耳機的麥克,想從藍牙耳機的麥克錄音。嘗試發(fā)現(xiàn)三星、小米自帶的錄音機并不能從藍牙錄音??戳司W(wǎng)上一篇文章,提供了一個特定的錄音APP,才支持開啟藍牙錄音功能。 非常令人疑惑。想到現(xiàn)在的手機,有不只一個麥克風(fēng),是否能開發(fā)一個可選擇錄音源的

    2024年04月16日
    瀏覽(22)
  • 將應(yīng)用設(shè)置成系統(tǒng)App/獲取Android設(shè)備SN號

    將應(yīng)用設(shè)置成系統(tǒng)App/獲取Android設(shè)備SN號

    1,和系統(tǒng)簽名一致;(簽名設(shè)置+簽名文件) 2,配置Manifest ?至此你的App就是一個系統(tǒng)App了,可以執(zhí)行一些系統(tǒng)App才能有的操作,如獲取機器SN號:

    2024年02月13日
    瀏覽(20)
  • adb 獲取 Android 設(shè)備中已安裝的 apk 文件

    adb 獲取 Android 設(shè)備中已安裝的 apk 文件

    今天發(fā)現(xiàn)手機上一個應(yīng)用在應(yīng)用商店已經(jīng)搜索不到了,想把其推薦給朋友使用,發(fā)現(xiàn)不知道從哪里找原始的 apk 安裝文件,記錄一下。 兩種方法 可以使用 MT管理器 ( Android 平臺逆向神器 ),它有個 安裝包提取 的功能,可以方便快捷的查看應(yīng)用包名及導(dǎo)出。MT管理器官方下載地

    2024年02月04日
    瀏覽(25)

覺得文章有用就打賞一下文章作者

支付寶掃一掃打賞

博客贊助

微信掃一掃打賞

請作者喝杯咖啡吧~博客贊助

支付寶掃一掃領(lǐng)取紅包,優(yōu)惠每天領(lǐng)

二維碼1

領(lǐng)取紅包

二維碼2

領(lǐng)紅包