簡體   English   中英

Android 設備的唯一 ID

[英]Unique ID of Android device

我想要一些 Android 設備的唯一 ID。 我用下面的代碼試過了

String ts = Context.TELEPHONY_SERVICE;
TelephonyManager telephonyManager = (TelephonyManager) this.getSystemService(ts);

但是我知道這僅適用於手機。

如果我的應用程序在某些筆記本、上網本或其他類型的設備上運行怎么辦? 在這種情況下如何獲得唯一 ID?

Android 手機上共有三種類型的標識符。

  1. IMEI
  2. IMSI

     String ts = Context.TELEPHONY_SERVICE; TelephonyManager mTelephonyMgr = (TelephonyManager) getSystemService(ts); String imsi = mTelephonyMgr.getSubscriberId(); String imei = mTelephonyMgr.getDeviceId();
  3. Android ID 它是一個 64 位十六進制字符串,在設備第一次啟動時生成。 除非恢復出廠設置,否則一般不會更改。

     Secure.getString(getContentResolver(), Secure.ANDROID_ID);

很抱歉碰到舊線程,但這個問題讓我頭疼,我找到了一篇好文章供某人閱讀,這確實對我有很大幫助。

有時在 Android 應用程序開發過程中需要獲取基於 Android 的智能手機設備的唯一 ID。 在用戶想要跟蹤應用程序的唯一設備安裝的情況下,這是必要的。

這在 Android 開發人員只想向少數特定設備發送推送消息的情況下也很有用。 所以在這里有必要為每個設備都有一個 UDID。

在 Android 中,設備的 UDID 有很多替代方案。 下面列出了在 android 應用程序中獲取 UDID 的一些方法及其優點和缺點以及獲取設備 ID 的任何必要權限。

  • IMEI:(國際移動設備標識)
  • 安卓 ID
  • WLAN MAC 地址字符串
  • 藍牙地址字符串

1)IMEI:(國際移動設備識別碼)

IMEI 號碼是獲取設備 ID 的一個非常好的主要來源。 它對於每個設備都是唯一的,並且取決於設備硬件。 因此,它對於每個設備也是唯一的,並且在設備的生命周期內都是永久的。

獲取設備IMEI的代碼片段如下,

TelephonyManager TelephonyMgr = (TelephonyManager)getSystemService(TELEPHONY_SERVICE);
String m_deviceId = TelephonyMgr.getDeviceId();

為此,您的應用程序將需要清單文件中給出的“android.permission.READ_PHONE_STATE”權限。

使用 IMEI 作為設備 ID 的優點:

每個設備的 IMEI 都是唯一的。 即使重新安裝了應用程序,或者如果設備已植根或恢復出廠設置,它對設備來說仍然是唯一的。

使用 IMEI 作為設備 ID 的缺點:

IMEI 依賴於設備的 Simcard 插槽,因此不使用 Simcard 的設備無法獲取 IMEI。 在雙卡設備中,我們為同一設備獲得 2 個不同的 IMEI,因為它有 2 個卡槽。

2)安卓ID

Android_ID 是一個唯一的 64 位數字,在設備首次啟動時生成並存儲。 當設備恢復出廠設置並生成新設備時,Android_ID 將被清除。

獲取Android_ID的代碼如下所示,

String m_androidId = Secure.getString(getContentResolver(), Secure.ANDROID_ID);

使用 Android_ID 作為設備 ID 的優點:

它是所有類型設備(智能手機和平板電腦)的唯一標識符。 不需要任何許可。

它將在所有設備中保持獨特,並且可以在沒有 Simcard 插槽的手機上使用。

使用 Android_ID 作為設備 ID 的缺點:

如果用戶升級了 Android 操作系統版本,則這可能會發生變化。 如果設備已植根或在設備上完成出廠重置,則 ID 會更改。 中國的 Android 設備制造商也存在一個已知問題,即某些設備具有相同的 Android_ID。

3) WLAN MAC 地址字符串

我們也可以使用 WLAN MAC 地址獲取安卓手機的唯一 ID。 MAC 地址對所有設備都是唯一的,它適用於所有類型的設備。

獲取設備的 WLAN MAC 地址的代碼片段如下所示,

WifiManager m_wm = (WifiManager)getSystemService(Context.WIFI_SERVICE); 
String m_wlanMacAdd = m_wm.getConnectionInfo().getMacAddress();

您的應用程序將需要清單文件中給出的權限“android.permission.ACCESS_WIFI_STATE”。

使用 WLAN MAC 地址作為 Device ID 的優點:

它是所有類型設備(智能手機和平板電腦)的唯一標識符。 如果重新安裝應用程序,它仍然是唯一的。

使用 WLAN MAC 地址作為 Device ID 的缺點:

如果設備沒有wifi硬件,那么你會得到空的MAC地址,但通常可以看到大多數Android設備都有wifi硬件,市場上幾乎沒有沒有wifi硬件的設備。

4) 藍牙地址串

我們也可以使用藍牙設備獲取安卓手機的唯一 ID。 每個具有藍牙硬件的設備的藍牙設備地址都是唯一的。

獲取藍牙設備地址的代碼片段如下所示,

BluetoothAdapter m_BluetoothAdapter = BluetoothAdapter.getDefaultAdapter(); 
String m_bluetoothAdd = m_BluetoothAdapter.getAddress();

要獲得上述代碼,您的應用程序需要清單文件中給出的“android.permission.BLUETOOTH”權限。

使用藍牙設備地址作為設備 ID 的優點: 它是所有類型設備(智能手機和平板電腦)的唯一標識符。 所有設備中通常只有一個藍牙硬件,並且不會改變。

使用藍牙設備地址作為設備 ID 的缺點:如果設備沒有藍牙硬件,那么你會得到 null。

在我看來,這些是獲取 Android 智能手機設備的唯一設備 ID 及其使用優缺點的最佳方法中的幾種。 現在由您根據 Android 應用程序開發要求決定使用哪種方法。

如果有任何其他方法可以獲取 UDID 並且彌補了上述方法的缺點,那么我很樂意在我的 Android 應用程序中探索這些方法。 Pl。 在評論框中分享這些內容以及任何建議或疑問。

這是文章

Secure.getString(getContentResolver(), Secure.ANDROID_ID);

這不適用於所有設備。

一些android設備有問題一些設備在我們嘗試獲取Device ID時返回null。解決這個問題的唯一方法是制作一個應該由我們自己生成的pseudodeviceID。這個函數會為你生成一個唯一的設備ID .您可以根據需要更改此功能。我也為解決此問題付出了很多努力。

public String getDeviceID() {

/*String Return_DeviceID = USERNAME_and_PASSWORD.getString(DeviceID_key,"Guest");
return Return_DeviceID;*/

TelephonyManager TelephonyMgr = (TelephonyManager) getApplicationContext().getApplicationContext().getSystemService(Context.TELEPHONY_SERVICE);
String m_szImei = TelephonyMgr.getDeviceId(); // Requires
// READ_PHONE_STATE

// 2 compute DEVICE ID
String m_szDevIDShort = "35"
+ // we make this look like a valid IMEI
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 digits
// 3 android ID - unreliable
String m_szAndroidID = Secure.getString(getContentResolver(),Secure.ANDROID_ID);
// 4 wifi manager, read MAC address - requires
// android.permission.ACCESS_WIFI_STATE or comes as null
WifiManager wm = (WifiManager) getApplicationContext().getSystemService(Context.WIFI_SERVICE);
String m_szWLANMAC = wm.getConnectionInfo().getMacAddress();
// 5 Bluetooth MAC address android.permission.BLUETOOTH required
BluetoothAdapter m_BluetoothAdapter = null; // Local Bluetooth adapter
m_BluetoothAdapter = BluetoothAdapter.getDefaultAdapter();
String m_szBTMAC = m_BluetoothAdapter.getAddress();
System.out.println("m_szBTMAC "+m_szBTMAC);

// 6 SUM THE IDs
String m_szLongID = m_szImei + m_szDevIDShort + m_szAndroidID+ m_szWLANMAC + m_szBTMAC;
System.out.println("m_szLongID "+m_szLongID);
MessageDigest m = null;
try {
m = MessageDigest.getInstance("MD5");
} catch (NoSuchAlgorithmException e) {
e.printStackTrace();
                }
m.update(m_szLongID.getBytes(), 0, m_szLongID.length());
byte p_md5Data[] = m.digest();

String m_szUniqueID = new String();
for (int i = 0; i < p_md5Data.length; i++) {
int b = (0xFF & p_md5Data[i]);
// if it is a single digit, make sure it have 0 in front (proper
// padding)
if (b <= 0xF)
m_szUniqueID += "0";
// add number to string
m_szUniqueID += Integer.toHexString(b);
}
m_szUniqueID = m_szUniqueID.toUpperCase();

Log.i("-------------DeviceID------------", m_szUniqueID);
Log.d("DeviceIdCheck", "DeviceId that generated MPreferenceActivity:"+m_szUniqueID);

return m_szUniqueID;

}

查看android.provider.Secure.Settings中的常量ANDROID_ID看看是否有幫助。

我正在添加一些來自官方文檔的有用鏈接;

有關如何為安裝應用程序的每個 Android 設備獲取唯一標識符的詳細說明,請參閱此官方 Android 開發人員博客帖子:

http://android-developers.blogspot.com/2011/03/identifying-app-installations.html

似乎最好的方法是在安裝時自己生成一個,然后在重新啟動應用程序時閱讀它。

我個人認為這可以接受但並不理想。 Android 提供的任何標識符都不能在所有情況下都有效,因為大多數標識符取決於手機的無線電狀態(wifi 開/關、蜂窩網絡開/關、藍牙開/關)。 其他如 Settings.Secure.ANDROID_ID 必須由制造商實施,並且不保證是唯一的。

以下是將數據寫入 INSTALLATION 文件的示例,該文件將與應用程序在本地保存的任何其他數據一起存儲。

public class Installation {
    private static String sID = null;
    private static final String INSTALLATION = "INSTALLATION";

    public synchronized static String id(Context context) {
        if (sID == null) {  
            File installation = new File(context.getFilesDir(), INSTALLATION);
            try {
                if (!installation.exists())
                    writeInstallationFile(installation);
                sID = readInstallationFile(installation);
            } catch (Exception e) {
                throw new RuntimeException(e);
            }
        }
        return sID;
    }

    private static String readInstallationFile(File installation) throws IOException {
        RandomAccessFile f = new RandomAccessFile(installation, "r");
        byte[] bytes = new byte[(int) f.length()];
        f.readFully(bytes);
        f.close();
        return new String(bytes);
    }

    private static void writeInstallationFile(File installation) throws IOException {
        FileOutputStream out = new FileOutputStream(installation);
        String id = UUID.randomUUID().toString();
        out.write(id.getBytes());
        out.close();
    }
}

使用MAC 地址

媒體訪問控制地址(MAC 地址)是分配給網絡接口的唯一標識符

任何連接到網絡的設備都保證有一個 MAC 地址,您可以通過轉到設置 > 關於手機 > 狀態在 Android 上找到它。

您應該能夠使用藍牙 API獲取藍牙 Mac 地址。

你可以試試這個:

String deviceId = Secure.getString(this.getContentResolver(),
                Secure.ANDROID_ID);

Settings.Secure#ANDROID_ID將 Android ID 作為唯一的 64 位十六進制字符串返回。

import android.provider.Settings.Secure;

private String android_id = Secure.getString(getContext().getContentResolver(),
                                                        Secure.ANDROID_ID);

如果系統中啟用了網絡設備(藍牙等)(打開),您可以獲得 MAC 地址。 但設備可能有藍牙、WiFi 等或什么都沒有。

您可以編寫自己的唯一 ID 生成器(例如,隨機生成 20 個數字或符號)

final TelephonyManager tm = (TelephonyManager) getBaseContext().getSystemService(Context.TELEPHONY_SERVICE);

   final String tmDevice, tmSerial, tmPhone, androidId;
   tmDevice = "" + tm.getDeviceId();
   tmSerial = "" + tm.getSimSerialNumber();
   androidId = "" + android.provider.Settings.Secure.getString(getContentResolver(), android.provider.Settings.Secure.ANDROID_ID);

   UUID deviceUuid = new UUID(androidId.hashCode(), ((<span id="IL_AD3" class="IL_AD">long</span>)tmDevice.hashCode() << 32) | tmSerial.hashCode());
   String deviceId = deviceUuid.toString();
TextView textAndroidId = (TextView)findViewById(R.id.androidid);
String AndroidId = Settings.Secure.getString(getContentResolver(), Settings.Secure.ANDROID_ID);
textAndroidId.setText("My ID is: " + AndroidId);

由於對 MAC 地址和其他與電話相關的 API 應用了新的限制,並且只有當它們是系統應用程序的一部分並具有所需的權限時,才能訪問這些與硬件相關的唯一標識符。

來自 文檔

When working with Android identifiers, follow these best practices:

Avoid using hardware identifiers. In most use cases, you can avoid using hardware identifiers, such as SSAID (Android ID), without limiting required functionality.

Android 10 (API level 29) adds restrictions for non-resettable identifiers, which include both IMEI and serial number. Your app must be a device or profile owner app, have special carrier permissions, or have the READ_PRIVILEGED_PHONE_STATE privileged permission in order to access these identifiers.

Only use an Advertising ID for user profiling or ads use cases. When using an Advertising ID, always respect users' selections regarding ad tracking. Also, ensure that the identifier cannot be connected to personally identifiable information (PII), and avoid bridging Advertising ID resets.

Use a Firebase installation ID (FID) or a privately stored GUID whenever possible for all other use cases, except for payment fraud prevention and telephony. For the vast majority of non-ads use cases, an FID or GUID should be sufficient.

Use APIs that are appropriate for your use case to minimize privacy risk. Use the DRM API for high-value content protection and the SafetyNet APIs for abuse protection. The SafetyNet APIs are the easiest way to determine whether a device is genuine without incurring privacy risk.

The remaining sections of this guide elaborate on these rules in the context of developing Android apps.

最好的情況是我們使用 FID 或 GUID 來識別每次安裝的應用程序的唯一性,這是您可以這樣做的方法。

 fun getDeviceId(): String {
    return FirebaseInstallations.getInstance().id.result ?: UUID.randomUUID().toString()
}

您可以檢查權限並評估它會給您設備 ID 的值:

private static final int REQUEST_READ_PHONE_STATE = 1;

int permissionCheck = ContextCompat.checkSelfPermission(getContext(),
Manifest.permission.READ_PHONE_STATE);

    if (permissionCheck != PackageManager.PERMISSION_GRANTED) {
        ActivityCompat.requestPermissions(getActivity(), new String[]{Manifest.permission.READ_PHONE_STATE}, REQUEST_READ_PHONE_STATE);
    } else {
        TelephonyManager tManager = (TelephonyManager) getContext().getSystemService(Context.TELEPHONY_SERVICE);
        String uid = tManager.getDeviceId();
        System.out.print(uid);
    }

輸出:358240051111110

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM