简体   繁体   English

Android 设备的唯一 ID

[英]Unique ID of Android device

I want some unique ID of the Android device.我想要一些 Android 设备的唯一 ID。 I've tried it with the following code我用下面的代码试过了

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

However I know that this works only for phones.但是我知道这仅适用于手机。

What if my app is running on some notebook, netbook or other type of device?如果我的应用程序在某些笔记本、上网本或其他类型的设备上运行怎么办? How do I get an unique ID in that case?在这种情况下如何获得唯一 ID?

There are three types of identifier on android phone. Android 手机上共有三种类型的标识符。

  1. IMEI IMEI
  2. IMSI IMSI

     String ts = Context.TELEPHONY_SERVICE; TelephonyManager mTelephonyMgr = (TelephonyManager) getSystemService(ts); String imsi = mTelephonyMgr.getSubscriberId(); String imei = mTelephonyMgr.getDeviceId();
  3. Android ID It is a 64-bit hex string which is generated on the device's first boot. Android ID 它是一个 64 位十六进制字符串,在设备第一次启动时生成。 Generally it won't be changed unless is factory reset.除非恢复出厂设置,否则一般不会更改。

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

Sorry to bump an old thread but this problem gives me headache, I found a good article for someone to read, and this really helps me a lot.很抱歉碰到旧线程,但这个问题让我头疼,我找到了一篇好文章供某人阅读,这确实对我有很大帮助。

Sometimes it is required during Android application development to get the unique id of the Android based smartphone device.有时在 Android 应用程序开发过程中需要获取基于 Android 的智能手机设备的唯一 ID。 This is necessary in cases when the user wants to track the unique device installations of the application.在用户想要跟踪应用程序的唯一设备安装的情况下,这是必要的。

This is also useful in cases where the Android developer wants to send Push messages to only few specific devices.这在 Android 开发人员只想向少数特定设备发送推送消息的情况下也很有用。 So over here it becomes necessary to have a UDID for every device.所以在这里有必要为每个设备都有一个 UDID。

In Android there are many alternatives to UDID of the device.在 Android 中,设备的 UDID 有很多替代方案。 Some of the methods to get the UDID in android application are listed below with its advantages and disadvantages and any necessary permissions for getting the device ID.下面列出了在 android 应用程序中获取 UDID 的一些方法及其优点和缺点以及获取设备 ID 的任何必要权限。

  • The IMEI: (International Mobile Equipment Identity) IMEI:(国际移动设备标识)
  • The Android ID安卓 ID
  • The WLAN MAC Address string WLAN MAC 地址字符串
  • The Bluetooth Address string蓝牙地址字符串

1) IMEI: (International Mobile Equipment Identity) 1)IMEI:(国际移动设备识别码)

The IMEI Number is a very good and primary source to get the device ID. IMEI 号码是获取设备 ID 的一个非常好的主要来源。 It is unique for each and every device and is dependent on the device Hardware.它对于每个设备都是唯一的,并且取决于设备硬件。 So it is also unique for each and every device and it is permanent till the lifetime of the device.因此,它对于每个设备也是唯一的,并且在设备的生命周期内都是永久的。

The code snippet to get the Device IMEI is as below,获取设备IMEI的代码片段如下,

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

For this your application will require the permission “android.permission.READ_PHONE_STATE” given in the manifest file.为此,您的应用程序将需要清单文件中给出的“android.permission.READ_PHONE_STATE”权限。

Advantages of using IMEI as Device ID:使用 IMEI 作为设备 ID 的优点:

The IMEI is unique for each and every device.每个设备的 IMEI 都是唯一的。 It remains unique for the device even if the application is re-installed or if the device is rooted or factory reset.即使重新安装了应用程序,或者如果设备已植根或恢复出厂设置,它对设备来说仍然是唯一的。

Disadvantages of using IMEI as Device ID:使用 IMEI 作为设备 ID 的缺点:

IMEI is dependent on the Simcard slot of the device, so it is not possible to get the IMEI for the devices that do not use Simcard. IMEI 依赖于设备的 Simcard 插槽,因此不使用 Simcard 的设备无法获取 IMEI。 In Dual sim devices, we get 2 different IMEIs for the same device as it has 2 slots for simcard.在双卡设备中,我们为同一设备获得 2 个不同的 IMEI,因为它有 2 个卡槽。

2) The Android ID 2)安卓ID

The Android_ID is a unique 64 bit number that is generated and stored when the device is first booted. Android_ID 是一个唯一的 64 位数字,在设备首次启动时生成并存储。 The Android_ID is wiped out when the device is Factory reset and new one gets generated.当设备恢复出厂设置并生成新设备时,Android_ID 将被清除。

The code to get the Android_ID is shown below,获取Android_ID的代码如下所示,

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

Advantages of using Android_ID as Device ID:使用 Android_ID 作为设备 ID 的优点:

It is unique identifier for all type of devices (smart phones and tablets).它是所有类型设备(智能手机和平板电脑)的唯一标识符。 No need of any permission.不需要任何许可。

It will remain unique in all the devices and it works on phones without Simcard slot.它将在所有设备中保持独特,并且可以在没有 Simcard 插槽的手机上使用。

Disadvantages of using Android_ID as Device ID:使用 Android_ID 作为设备 ID 的缺点:

If Android OS version is upgraded by the user then this may get changed.如果用户升级了 Android 操作系统版本,则这可能会发生变化。 The ID gets changed if device is rooted or factory reset is done on the device.如果设备已植根或在设备上完成出厂重置,则 ID 会更改。 Also there is a known problem with a Chinese manufacturer of android device that some devices have same Android_ID.中国的 Android 设备制造商也存在一个已知问题,即某些设备具有相同的 Android_ID。

3) The WLAN MAC Address string 3) WLAN MAC 地址字符串

We can get the Unique ID for android phones using the WLAN MAC address also.我们也可以使用 WLAN MAC 地址获取安卓手机的唯一 ID。 The MAC address is unique for all devices and it works for all kinds of devices. MAC 地址对所有设备都是唯一的,它适用于所有类型的设备。

The code snippet to get the WLAN MAC address for a device is as shown below,获取设备的 WLAN MAC 地址的代码片段如下所示,

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

Your application will require the permission “android.permission.ACCESS_WIFI_STATE” given in the manifest file.您的应用程序将需要清单文件中给出的权限“android.permission.ACCESS_WIFI_STATE”。

Advantages of using WLAN MAC address as Device ID:使用 WLAN MAC 地址作为 Device ID 的优点:

It is unique identifier for all type of devices (smart phones and tablets).它是所有类型设备(智能手机和平板电脑)的唯一标识符。 It remains unique if the application is reinstalled.如果重新安装应用程序,它仍然是唯一的。

Disadvantages of using WLAN MAC address as Device ID:使用 WLAN MAC 地址作为 Device ID 的缺点:

If device doesn't have wifi hardware then you get null MAC address, but generally it is seen that most of the Android devices have wifi hardware and there are hardly few devices in the market with no wifi hardware.如果设备没有wifi硬件,那么你会得到空的MAC地址,但通常可以看到大多数Android设备都有wifi硬件,市场上几乎没有没有wifi硬件的设备。

4) The Bluetooth Address string 4) 蓝牙地址串

We can get the Unique ID for android phones using the Bluetooth device also.我们也可以使用蓝牙设备获取安卓手机的唯一 ID。 The Bluetooth device address is unique for each device having Bluetooth hardware.每个具有蓝牙硬件的设备的蓝牙设备地址都是唯一的。

The code snippet to get the Bluetooth device address is as given below,获取蓝牙设备地址的代码片段如下所示,

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

To get the above code, your application needs the permission “android.permission.BLUETOOTH” given in the manifest file.要获得上述代码,您的应用程序需要清单文件中给出的“android.permission.BLUETOOTH”权限。

Advantages of using Bluetooth device address as Device ID: It is unique identifier for all type of devices (smart phones and tablets).使用蓝牙设备地址作为设备 ID 的优点: 它是所有类型设备(智能手机和平板电脑)的唯一标识符。 There is generally a single Bluetooth hardware in all devices and it doesn't gets changed.所有设备中通常只有一个蓝牙硬件,并且不会改变。

Disadvantages of using Bluetooth device address as Device ID: If device hasn't bluetooth hardware then you get null.使用蓝牙设备地址作为设备 ID 的缺点:如果设备没有蓝牙硬件,那么你会得到 null。

As per me these are few of the best possible ways to get the Unique Device ID for Android smartphone device and their pros and cons of using it.在我看来,这些是获取 Android 智能手机设备的唯一设备 ID 及其使用优缺点的最佳方法中的几种。 Now it is upto you to decide which method to use based on the Android application development requirements.现在由您根据 Android 应用程序开发要求决定使用哪种方法。

If there are any other methods to get UDID and that covers up the disadvantages of above methods, then I would love to explore those in my Android application.如果有任何其他方法可以获取 UDID 并且弥补了上述方法的缺点,那么我很乐意在我的 Android 应用程序中探索这些方法。 Pl. Pl。 share those in comment box and also if any suggestions or queries.在评论框中分享这些内容以及任何建议或疑问。

Here's the article 这是文章

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

This will not work for all the devices.这不适用于所有设备。

Some of the android devices has a problem Some devices returns null when we try to get the Device ID.The only way to solve this issue is to make a pseudodeviceID which should be generated by ourself.This function will generation a unique device ID for you.You can make changes to this function as you needed.Me too struggled a lot for solving this issue.一些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;

}

Look at the constant ANDROID_ID in android.provider.Secure.Settings to see if that helps.查看android.provider.Secure.Settings中的常量ANDROID_ID看看是否有帮助。

I am adding a few useful links from official docs;我正在添加一些来自官方文档的有用链接;

For detailed instructions on how to get a Unique Identifier for each Android device your application is installed from, see this official Android Developers Blog posting:有关如何为安装应用程序的每个 Android 设备获取唯一标识符的详细说明,请参阅此官方 Android 开发人员博客帖子:

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

It seems the best way is for you to generate one your self upon installation and subsequently read it when the application is re-launched.似乎最好的方法是在安装时自己生成一个,然后在重新启动应用程序时阅读它。

I personally find this acceptable but not ideal.我个人认为这可以接受但并不理想。 No one identifier provided by Android works in all instances as most are dependent on the phone's radio states (wifi on/off, cellular on/off, bluetooth on/off). Android 提供的任何标识符都不能在所有情况下都有效,因为大多数标识符取决于手机的无线电状态(wifi 开/关、蜂窝网络开/关、蓝牙开/关)。 The others like Settings.Secure.ANDROID_ID must be implemented by the manufacturer and are not guaranteed to be unique.其他如 Settings.Secure.ANDROID_ID 必须由制造商实施,并且不保证是唯一的。

The following is an example of writing data to an INSTALLATION file that would be stored along with any other data the application saves locally.以下是将数据写入 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();
    }
}

Use a MAC address :使用MAC 地址

A Media Access Control address (MAC address) is a unique identifier assigned to network interfaces媒体访问控制地址(MAC 地址)是分配给网络接口的唯一标识符

Any device connected to a network is guaranteed to have a MAC address, and you can find it on the Android by going to Settings > About Phone > Status.任何连接到网络的设备都保证有一个 MAC 地址,您可以通过转到设置 > 关于手机 > 状态在 Android 上找到它。

You should be able to get the bluetooth Mac address using the Bluetooth API .您应该能够使用蓝牙 API获取蓝牙 Mac 地址。

You can try this:你可以试试这个:

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

Settings.Secure#ANDROID_ID returns the Android ID as an unique 64-bit hex string. Settings.Secure#ANDROID_ID将 Android ID 作为唯一的 64 位十六进制字符串返回。

import android.provider.Settings.Secure;

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

You can get MAC address if network-device (Bluetooth etc.) is enabled in the system (turned on).如果系统中启用了网络设备(蓝牙等)(打开),您可以获得 MAC 地址。 But device may have Bluetooth, WiFi, etc. or nothing.但设备可能有蓝牙、WiFi 等或什么都没有。

You may write your own unique ID generator (with 20 numbers or symbols randomly for example)您可以编写自己的唯一 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);

Since new restrictions have been applied to the MAC address and other telephony-related API's and one can only access those hardware-related Unique identifiers if they are part of the system app and has the required privileges.由于对 MAC 地址和其他与电话相关的 API 应用了新的限制,并且只有当它们是系统应用程序的一部分并具有所需的权限时,才能访问这些与硬件相关的唯一标识符。

from 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.

The best case is we use the FID or GUID to identify the uniqueness of the app per installation, here is how you can do it.最好的情况是我们使用 FID 或 GUID 来识别每次安装的应用程序的唯一性,这是您可以这样做的方法。

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

You can check permission and can evaluate the value it will give you the device id:您可以检查权限并评估它会给您设备 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);
    }

Output: 358240051111110输出:358240051111110

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM