Android设备的唯一ID

时间:2010-12-17 06:22:32

标签: android

我想要一些Android设备的唯一ID。我已经尝试使用以下代码

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

但我知道这只适用于手机。

如果我的应用程序在某些笔记本电脑,上网本或其他类型的设备上运行怎么办?在这种情况下如何获得唯一ID?

13 个答案:

答案 0 :(得分:39)

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);
    

答案 1 :(得分:21)

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

这不适用于所有设备。

某些Android设备有问题当我们尝试获取设备ID时,有些设备会返回null。解决此问题的唯一方法是创建一个应该由我们自己生成的伪设备ID。此函数将生成一个唯一的设备你的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;

}

答案 2 :(得分:13)

看看常数 android.provider.Secure.Settings中的ANDROID_ID,看看是否有帮助。

我正在从官方文档中添加一些有用的链接;

答案 3 :(得分:12)

很抱歉碰到一个旧线程,但这个问题让我很头疼,我发现一篇好文章供有人阅读,这对我很有帮助。

有时在Android应用程序开发期间需要获取基于Android的智能手机设备的唯一ID。当用户想要跟踪应用程序的唯一设备安装时,这是必要的。

这对于Android开发人员只想向少数特定设备发送Push消息的情况也很有用。所以在这里有必要为每个设备都有一个UDID。

在Android中,设备的UDID有很多替代方案。下面列出了在Android应用程序中获取UDID的一些方法及其优点和缺点以及获取设备ID所需的任何权限。

  • IMEI :(国际移动设备识别码)
  • Android 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依赖于设备的SIM卡插槽,因此无法为不使用Simcard的设备获取IMEI。 在双SIM卡设备中,我们为同一设备获得2个不同的IMEI,因为它有2个用于SIM卡的插槽。

2)Android 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地址获取Android手机的唯一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地址作为设备ID的优点:

它是所有类型设备(智能手机和平板电脑)的唯一标识符。 如果重新安装该应用程序,它仍然是唯一的。

使用WLAN MAC地址作为设备ID的缺点:

如果设备没有wifi硬件,那么你会获得空MAC地址,但通常可以看到大多数Android设备都有wifi硬件,市场上几乎没有设备没有wifi硬件。

4)蓝牙地址字符串

我们也可以使用蓝牙设备获取Android手机的唯一ID。蓝牙设备地址对于每个具有蓝牙硬件的设备都是唯一的。

获取蓝牙设备地址的代码段如下所示,

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

要获取上述代码,您的应用程序需要清单文件中给出的权限“android.permission.BLUETOOTH”。

使用蓝牙设备地址作为设备ID的优点: 它是所有类型设备(智能手机和平板电脑)的唯一标识符。 所有设备中通常都有一个蓝牙硬件,并且不会发生变化。

使用蓝牙设备地址作为设备ID的缺点: 如果设备没有蓝牙硬件,那么你会得到null。

根据我的说法,这些是获取Android智能手机设备唯一设备ID的最佳方法,以及使用它的优缺点。现在,您可以根据Android应用程序开发要求决定使用哪种方法。

如果有任何其他方法可以获得UDID并且可以弥补上述方法的缺点,那么我很乐意在Android应用程序中探索这些方法。 PL。在评论框中分享这些内容以及任何建议或疑问。

Here's the article

答案 4 :(得分:8)

有关如何为安装应用程序的每个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();
    }
}

答案 5 :(得分:6)

使用MAC address

  

媒体访问控制地址(MAC   address)是唯一标识符   分配给网络接口

任何连接到网络的设备都保证拥有MAC地址,您可以通过转到设置&gt;在Android上找到它。关于手机&gt;状态。

您应该可以使用Bluetooth API获取蓝牙Mac地址。

答案 6 :(得分:2)

如果系统中已启用网络设备(蓝牙等),则可以获取MAC地址(已打开)。但设备可能有蓝牙,WiFi等,或者什么也没有。

您可以编写自己的唯一ID生成器(例如,随机添加20个数字或符号)

答案 7 :(得分:2)

Settings.Secure#ANDROID_ID将Android ID作为唯一的64位十六进制字符串返回。

import android.provider.Settings.Secure;

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

答案 8 :(得分:1)

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();

答案 9 :(得分:1)

你可以试试这个:

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

答案 10 :(得分:0)

TextView textAndroidId = (TextView)findViewById(R.id.androidid);
String AndroidId = Settings.Secure.getString(getContentResolver(), Settings.Secure.ANDROID_ID);
textAndroidId.setText("My ID is: " + AndroidId);

答案 11 :(得分:0)

由于对 MAC 地址和其他与电话相关的 API 应用了新的限制,并且只有当这些与硬件相关的唯一标识符是系统应用的一部分并具有所需的权限时,才能访问它们。

来自docs

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()
}

答案 12 :(得分:0)

您可以检查权限并评估它会给您设备 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