53

I want some unique ID of the Android device. 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?

Octavian Helm
  • 39,405
  • 19
  • 98
  • 102
Mudassir
  • 13,031
  • 8
  • 59
  • 87
  • 2
    @Mudassir: So basically you want something that is 'set in stone', 'hard-coded' which will never change and is 100% reliable??? Intel tried it...read this schneier.com/essay-187.html – Squonk Dec 17 '10 at 08:00
  • @MisterSquonk I want something of that sort. I like 'set in stone'. :-) – Mudassir Dec 17 '10 at 08:43
  • @Mudassir: Well good luck in finding that but I'd be surprised if you can find it. At the most I'd work on the principle of the thing that's least likely to be changed/hacked or whatever to use as a basis for something that's as 'unique' as can be. After that, try to write code to compensate for any problems along the way. – Squonk Dec 17 '10 at 09:00
  • Already asked http://stackoverflow.com/questions/2322234/how-to-find-serial-number-of-android-device – rds Dec 17 '10 at 13:31
  • 2
    @rds: I know its already asked, and I've also tried the solutions given in previous post as I mentioned in my question. My criteria is different. – Mudassir Dec 17 '10 at 13:46
  • @rds: The question you linked to is specific about retrieving the Android serial number. This question is specific about getting an ID that is also available on non-Android devices. – Greg Sansom Dec 18 '10 at 00:56

13 Answers13

46

There are three types of identifier on android phone.

  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 It is a 64-bit hex string which is generated on the device's first boot. Generally it won't be changed unless is factory reset.

    Secure.getString(getContentResolver(), Secure.ANDROID_ID);
    
hungr
  • 2,086
  • 1
  • 20
  • 33
  • 3
    Updated 3 : String unique_id = android.provider.Settings.Secure.getString(getContentResolver(), android.provider.Settings.Secure.ANDROID_ID); Ref : http://developer.android.com/reference/android/provider/Settings.Secure.html#ANDROID_ID – Pankaj Kumar Aug 04 '11 at 06:56
39

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. 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. So over here it becomes necessary to have a UDID for every device.

In Android there are many alternatives to UDID of the device. 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.

  • The IMEI: (International Mobile Equipment Identity)
  • The Android ID
  • The WLAN MAC Address string
  • The Bluetooth Address string

1) IMEI: (International Mobile Equipment Identity)

The IMEI Number is a very good and primary source to get the device 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,

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.

Advantages of using IMEI as Device ID:

The IMEI is unique for each and every device. 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 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. In Dual sim devices, we get 2 different IMEIs for the same device as it has 2 slots for simcard.

2) The Android ID

The Android_ID is a unique 64 bit number that is generated and stored when the device is first booted. The Android_ID is wiped out when the device is Factory reset and new one gets generated.

The code to get the Android_ID is shown below,

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

Advantages of using Android_ID as Device 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.

Disadvantages of using Android_ID as Device ID:

If Android OS version is upgraded by the user then this may get changed. The ID gets changed if device is rooted or factory reset is done on the device. Also there is a known problem with a Chinese manufacturer of android device that some devices have same Android_ID.

3) The WLAN MAC Address string

We can get the Unique ID for android phones using the WLAN MAC address also. The MAC address is unique for all devices and it works for all kinds of devices.

The code snippet to get the WLAN MAC address for a device is as shown below,

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.

Advantages of using WLAN MAC address as 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:

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.

4) The Bluetooth Address string

We can get the Unique ID for android phones using the Bluetooth device also. 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.

Advantages of using Bluetooth device address as Device ID: It is unique identifier for all type of devices (smart phones and tablets). 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.

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. Now it is upto you to decide which method to use based on the Android application development requirements.

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. Pl. share those in comment box and also if any suggestions or queries.

Here's the article

eliasRuizHz
  • 356
  • 4
  • 15
Samoka
  • 1,283
  • 2
  • 12
  • 23
24
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.

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;

}
Sreedev
  • 6,563
  • 5
  • 43
  • 66
  • if you got it correct Accept the answer...happy to help you:-) – Sreedev Apr 24 '12 at 08:49
  • this generated ID is always same even after device is reboot? – user7176550 Feb 04 '19 at 10:49
  • The problem with this is that the device ID will not persist app re-installation and won't ever be unique because the device is generating it. In my case, all I want is to have a reliable ID that I can use for troubleshooting issues with my app and that Id needs to be hardware-dependent. – TheRealChx101 Jul 05 '23 at 11:08
21

Look at the constant ANDROID_ID in android.provider.Secure.Settings to see if that helps.

I am adding a few useful links from official docs;

Mudassir
  • 13,031
  • 8
  • 59
  • 87
Squonk
  • 48,735
  • 19
  • 103
  • 135
  • http://developer.android.com/reference/android/provider/Settings.Secure.html#ANDROID_ID – Mudassir Dec 17 '10 at 07:23
  • It can be changed when the phone is reset to factory defaults. See the link in previous comment. – Mudassir Dec 17 '10 at 07:23
  • 1
    @Mudassir: The question does say "What if my app is running on some Notebook, Netbook or other type of device? How do I get an unique id in this case?" – Greg Sansom Dec 17 '10 at 07:25
  • 2
    @Mudassir: Yes...but pretty much anything can change under different circumstances. It depends on how 'unique' and how 'permanent' you want things to be. If the UID is changed during a factory reset then 'invalidate' the device next time whatever app you're writing is used. Besides, after a factory reset your app will have to be re-installed. – Squonk Dec 17 '10 at 07:29
  • @Greg: Thats what I want to know? – Mudassir Dec 17 '10 at 07:30
  • 4
    ANDROID_ID is rumored to not be unique on some phones/firmware versions – Chris Stratton Dec 17 '10 at 07:31
  • @Chris Stratton: Interesting to know. – Squonk Dec 17 '10 at 07:41
  • 1
    +1 Chris. The docs say that its a random number so you cannot expect it to be a unique one for sure... +1 for the remaining good answers too – DeRagan Dec 17 '10 at 07:48
  • @Rahul: For a 64-bit random number you'd expect it to be quite rare for a duplicate unless they forgot to change the seed on the RNG. – Squonk Dec 17 '10 at 07:56
  • @MisterSquonk: I didn't thought about reinstalling the app after factory reset. Thanks. I will think about it. – Mudassir Dec 17 '10 at 08:46
  • Be aware there are huge limitations with this solution: http://android-developers.blogspot.com/2011/03/identifying-app-installations.html – emmby Apr 07 '11 at 20:07
8

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:

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). The others like Settings.Secure.ANDROID_ID must be implemented by the manufacturer and are not guaranteed to be unique.

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.

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();
    }
}
Kevin Parker
  • 16,975
  • 20
  • 76
  • 105
  • The blog says "For the vast majority of applications, the requirement is to identify a particular installation, not a physical device" but the id created by above code isn't reliable as if user clear app data , the device id removed & it creates new devices id. Tested 10 times & each time it creates new id. :( – Mudassar Mar 11 '12 at 18:16
  • @Mudassar Exactly. Not very ideal. It doesn't really matter if a user can spoof a hardware Id. I just want an Id to be there that is "permanent" to where I know that first time that device connects to my service and associate it with an account for troubleshooting purposes, forever – TheRealChx101 Jul 05 '23 at 11:11
7

You can try this:

String deviceId = Secure.getString(this.getContentResolver(),
                Secure.ANDROID_ID);
Dr.jacky
  • 3,341
  • 6
  • 53
  • 91
ashishsingh
  • 71
  • 1
  • 2
6

Use a MAC address:

A Media Access Control address (MAC address) is a unique identifier assigned to network interfaces

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.

You should be able to get the bluetooth Mac address using the Bluetooth API.

Greg Sansom
  • 20,442
  • 6
  • 58
  • 76
  • I don't know if Android is immune but MAC addresses can be faked on many systems. – Squonk Dec 17 '10 at 07:23
  • Is it available on Netbooks or tablet kind of devices? How can I get it programmatically? – Mudassir Dec 17 '10 at 07:28
  • 2
    Yes MAC (or at least local reporting thereof) can be overridden on any device that is rooted. – Chris Stratton Dec 17 '10 at 07:29
  • @Mudassir: Yes, MAC is available on any device which has network access. How to get it programmaticaly depends on the language you are using - you might need to hit Google or open another question. – Greg Sansom Dec 17 '10 at 07:52
  • @MisterSquonk: You are right but I'm not sure if this is really a bit deal - it should be treated as an ID but is not sufficient for authentication. – Greg Sansom Dec 17 '10 at 07:53
3

Settings.Secure#ANDROID_ID returns the Android ID as an unique 64-bit hex string.

import android.provider.Settings.Secure;

private String android_id = Secure.getString(getContext().getContentResolver(),
                                                        Secure.ANDROID_ID);
Zar E Ahmer
  • 33,936
  • 20
  • 234
  • 300
2
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();
kiran
  • 31
  • 2
2

You can get MAC address if network-device (Bluetooth etc.) is enabled in the system (turned on). But device may have Bluetooth, WiFi, etc. or nothing.

You may write your own unique ID generator (with 20 numbers or symbols randomly for example)

Andrew T.
  • 4,701
  • 8
  • 43
  • 62
mysuperass
  • 1,199
  • 1
  • 9
  • 10
  • I want to identify a device uniquely. How can I use a random number generator? – Mudassir Dec 17 '10 at 08:50
  • It's big problem because UID should be implemented by the device developers. Generate ID, save in SharedPrefference and use it for identificate device – mysuperass Dec 17 '10 at 09:04
0
TextView textAndroidId = (TextView)findViewById(R.id.androidid);
String AndroidId = Settings.Secure.getString(getContentResolver(), Settings.Secure.ANDROID_ID);
textAndroidId.setText("My ID is: " + AndroidId);
Lamorak
  • 10,957
  • 9
  • 43
  • 57
guest
  • 1
0

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.

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.

 fun getDeviceId(): String {
    return FirebaseInstallations.getInstance().id.result ?: UUID.randomUUID().toString()
}
vikas kumar
  • 10,447
  • 2
  • 46
  • 52
0

You can check permission and can evaluate the value it will give you the device 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

Tanvir Ahmed
  • 564
  • 6
  • 13