SoFunction
Updated on 2025-04-10

A brief discussion on the perfect solution for obtaining unique device identification on Android

This article introduces a brief discussion on the perfect solution to obtain unique identification of Android devices. We will share it with you, as follows:

/**
  * The deviceID is composed of: channel flag + identifier source flag + terminal identifier after hash
  *
  * The channel logo is:
  * 1, andriod(a)
  *
  * Identifier source flag:
  * 1, wifi mac address (wifi);
  * 2, IMEI (imei);
  * 3, serial number (sn);
  * 4, id: random code.  If all the previous ones cannot be retrieved, a random code will be generated randomly and needs to be cached. 
  *
  * @param context
  * @return
  */ 
public static String getDeviceId(Context context) { 
 StringBuilder deviceId = new StringBuilder(); 
 // Channel logo ("a"); 
 try { 
  //wifi mac address  WifiManager wifi = (WifiManager) (Context.WIFI_SERVICE); 
  WifiInfo info = (); 
  String wifiMac = (); 
  if(!isEmpty(wifiMac)){ 
   ("wifi"); 
   (wifiMac); 
   ("getDeviceId : ", ()); 
   return (); 
  } 
  //IMEI(imei) 
  TelephonyManager tm = (TelephonyManager) (Context.TELEPHONY_SERVICE); 
  String imei = (); 
  if(!isEmpty(imei)){ 
   ("imei"); 
   (imei); 
   ("getDeviceId : ", ()); 
   return (); 
  } 
  //Serial number (sn)  String sn = (); 
  if(!isEmpty(sn)){ 
   ("sn"); 
   (sn); 
   ("getDeviceId : ", ()); 
   return (); 
  } 
  //If none of the above is generated, an id: random code  String uuid = getUUID(context); 
  if(!isEmpty(uuid)){ 
   ("id"); 
   (uuid); 
   ("getDeviceId : ", ()); 
   return (); 
  } 
 } catch (Exception e) { 
  (); 
  ("id").append(getUUID(context)); 
 } 
 ("getDeviceId : ", ()); 
 return (); 
} 
/**
  * Get globally unique UUID
  */ 
public static String getUUID(Context context){ 
 SharedPreferences mShare = getSysShare(context, "sysCacheMap"); 
 if(mShare != null){ 
  uuid = ("uuid", ""); 
 } 
 if(isEmpty(uuid)){ 
  uuid = ().toString(); 
  saveSysMap(context, "sysCacheMap", "uuid", uuid); 
 } 
 (tag, "getUUID : " + uuid); 
return uuid; 
} 

Sometimes it is necessary to identify the user equipment, so it is hoped that a stable, reliable and unique identification code can be obtained. Although such device identification code is provided in the Android system, stability and uniqueness are not ideal due to limitations such as Android system version and bugs in the manufacturer's customized system. The identification of other hardware information also has different degrees of problems due to system version, mobile phone hardware, etc.

Below are collected some string codes for "capable" or "certain ability" as device identification.

DEVICE_ID

This is the serial number provided by the Android system to developers for identifying mobile phone devices. It is also the most universal among various methods. It can be said that almost all devices can return this serial number and have good uniqueness.

This DEVICE_ID can be obtained by the following method:

TelephonyManager tm = (TelephonyManager)getSystemService(Context.TELEPHONY_SERVICE); 
String DEVICE_ID = ();  

Assuming we really need to use the real device identification, we may need to use DEVICE_ID. In the past, our Android device was a mobile phone. This DEVICE_ID could be obtained through (). It returns IMEI, MEID or ESN codes according to different mobile phone devices, but it will encounter many problems during use:

  • Non-mobile device: If a device with only Wifi or a music player does not have the hardware function of calling, there is no DEVICE_ID
  • Permissions: READ_PHONE_STATE permission is required to obtain DEVICE_ID, but if we only want to obtain it and do not use other call functions, then this permission is a bit too big and is useless
  • Bug: On a few mobile devices, this implementation has loopholes and will return garbage, such as zeros or asterisks products.

MAC ADDRESS

You can use the MAC address of your mobile phone Wifi or Bluetooth as your device identifier, but it is not recommended to do so for the following two reasons:

  • Hardware limitations: Not all devices have Wifi and Bluetooth hardware, and if the hardware does not exist, this information will naturally not be obtained.
  • Restrictions on obtaining: If Wifi has not been turned on, it cannot obtain its Mac address; while Bluetooth can only obtain its Mac address when it is turned on.

Get Wifi Mac address:

Get Bluetooth Mac address:

Sim Serial Number

For Android 2.3 devices with SIM cards, you can obtain the Sim Serial Number through the following methods:

TelephonyManager tm = (TelephonyManager)getSystemService(Context.TELEPHONY_SERVICE);  
String SimSerialNumber = ();  

Note: For CDMA devices, a null value is returned!

ANDROID_ID

When the device is first started, the system will randomly generate a 64-bit number and save the number in the form of a hexadecimal string. This hexadecimal string is ANDROID_ID. This value will be reset when the device is wiped. It can be obtained by:

import ; 
String ANDROID_ID = (getContentResolver(), .ANDROID_ID); 

ANDROID_ID can be used as device identifier, but please note:

  • Bugs to the manufacturer's customized system: Different devices may produce the same ANDROID_ID: 9774d56d682e549c.
  • Bugs to the manufacturer's customized system: Some devices return a value of null.
  • Device Difference: For CDMA devices, ANDROID_ID and () return the same value.
  • It is reliable and stable in Android <=2.1 or Android >=2.3, but it is not 100% reliable in Android version 2.2.

Serial Number

Serial Number can be obtained by the following method for Android version 2.3 or above, and non-mobile devices can also be obtained through this interface.

String SerialNumber = ;  

The above methods have more or less certain limitations or bugs. If the hardware itself is not really bound, using the UUID you generate yourself is also a good choice, because this method does not require access to the device resources and has nothing to do with the device type.

Installtion ID

The principle of this method is to generate an ID when it is run for the first time after the program is installed. This method is different from the unique device ID. Different applications will generate different IDs, and the same program will be reinstalled differently. So this is not the unique ID of the device, but it can be guaranteed that the ID of each user is different. It can be said to be a unique ID used to identify each application (i.e. Installtion ID), which can be used to track the number of applications installed, etc.

Google Developer Blog provides a framework like this:

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((), INSTALLATION); 
      try { 
        if (!()) 
          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) ()]; 
    (bytes); 
    (); 
    return new String(bytes); 
  } 
 
  private static void writeInstallationFile(File installation) throws IOException { 
    FileOutputStream out = new FileOutputStream(installation); 
    String id = ().toString(); 
    (()); 
    (); 
  } 
} 

Unique device ID

As can be seen above, there is no way to reliably obtain the unique ID of all manufacturers' devices in the Android system. Each method has its own scope and limitations. This is also caused by too many popular Android system versions, and the devices are also from different manufacturers and there is no unified standard.

Judging from the current development, the coexistence of multiple versions of the Android system will last for a long time, and the Android system will not be monopolized by a certain device manufacturer. In the long run, the Android basic system will become stable, and the device identification will also be standardized as the basic part of the system. Only then will this problem be completely solved.

The current solution is more feasible to adapt one by one. On the premise of ensuring the convenience of most devices, if you cannot obtain it, use other alternative information as the identifier, that is, you can encapsulate a device ID by yourself, and use internal algorithms to ensure that it is as relevant to the device hardware information and the uniqueness of the identifier.

Summarize

Based on the above, in order to achieve a more general device-unique identification on the device, we can implement such a class to generate a unique UUID for each device, based on ANDROID_ID, and when the acquisition fails, use () as an alternative method. If it fails again, use the UUID generation strategy.

To reiterate, the following method is to generate a Device ID. In most cases, the Installtion ID can meet our needs, but if you really need to use the Device ID, it can be done in the following ways:

import ; 
import ; 
import ; 
import ; 
import ; 
import ; 
 
public class DeviceUuidFactory { 
  protected static final String PREFS_FILE = "device_id.xml"; 
  protected static final String PREFS_DEVICE_ID = "device_id"; 
  protected static UUID uuid; 
 
  public DeviceUuidFactory(Context context) { 
    if( uuid ==null ) { 
      synchronized () { 
        if( uuid == null) { 
          final SharedPreferences prefs = ( PREFS_FILE, 0); 
          final String id = (PREFS_DEVICE_ID, null ); 
          if (id != null) { 
            // Use the ids previously computed and stored in the prefs file 
            uuid = (id); 
          } else { 
            final String androidId = ((), Secure.ANDROID_ID); 
            // Use the Android ID unless it's broken, in which case fallback on deviceId, 
            // unless it's not available, then fallback on a random number which we store 
            // to a prefs file 
            try { 
              if (!"9774d56d682e549c".equals(androidId)) { 
                uuid = (("utf8")); 
              } else { 
                final String deviceId = ((TelephonyManager) ( Context.TELEPHONY_SERVICE )).getDeviceId(); 
                uuid = deviceId!=null ? (("utf8")) : (); 
              } 
            } catch (UnsupportedEncodingException e) { 
              throw new RuntimeException(e); 
            } 
            // Write the value out to the prefs file 
            ().putString(PREFS_DEVICE_ID, () ).commit(); 
          } 
        } 
      } 
    } 
  } 
  /** 
   * Returns a unique UUID for the current android device. As with all UUIDs, this unique ID is "very highly likely" 
   * to be unique across all Android devices. Much more so than ANDROID_ID is. 
   * 
   * The UUID is generated by using ANDROID_ID as the base key if appropriate, falling back on 
   * () if ANDROID_ID is known to be incorrect, and finally falling back 
   * on a random UUID that's persisted to SharedPreferences if getDeviceID() does not return a 
   * usable value. 
   * 
   * In some rare circumstances, this ID may change. In particular, if the device is factory reset a new device ID 
   * may be generated. In addition, if a user upgrades their phone from certain buggy implementations of Android 2.2 
   * to a newer, non-buggy version of Android, the device ID may change. Or, if a user uninstalls your app on 
   * a device that has neither a proper Android ID nor a Device ID, this ID may change on reinstallation. 
   * 
   * Note that if the code falls back on using (), the resulting ID will NOT 
   * change after a factory reset. Something to be aware of. 
   * 
   * Works around a bug in Android 2.2 for many devices when using ANDROID_ID directly. 
   * 
   * @see /p/android/issues/detail?id=10603 
   * 
   * @return a UUID that may be used to uniquely identify your device for most purposes. 
   */ 
  public UUID getDeviceUuid() { 
    return uuid; 
  } 
} 

How to get the unique ID of an Android phone?

Code: Here is how you read out the only IMSI-ID / IMEI-ID in Android.

Java:

String myIMSI = (.PROPERTY_IMSI);  
// within my emulator it returns: 310995000000000  
 
String myIMEI = (.PROPERTY_IMEI);  
// within my emulator it returns: 000000000000000  

Note: The tag is @hide, so it will not exist in SDK. If you need to use it, you need to have android source code support.

The above is all the content of this article. I hope it will be helpful to everyone's study and I hope everyone will support me more.