83

I am using this call:

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

To get a UID for the device. I think I am getting the same ID from multiple devices though. Should this be possible?

The ID in question is: 9774d56d682e549c and apparently there is an issue with several devices returning this ID http://code.google.com/p/android/issues/list?cursor=10603&updated=10603&ts=1295993403

Volker Stolz
  • 6,914
  • 29
  • 47
FoamyGuy
  • 45,328
  • 16
  • 118
  • 151
  • After looking up the ID in question and seeing a thread about it I am sure. At first I thought it could be possible that the device was returning null and I had put it in as a default somewhere. But this is not the case. I know for sure I am getting the same value on multiple devices. – FoamyGuy Jan 25 '11 at 22:12
  • 1
    I found perfect: http://stackoverflow.com/a/16929647/1318946 – Pratik Butani Apr 25 '14 at 04:58
  • For the cases where it's not unique, use [this library](https://github.com/delight-im/Android-BaseLib) which comes with [Identity.getDeviceId(context)](https://github.com/delight-im/Android-BaseLib/blob/master/Source/src/im/delight/android/baselib/Identity.java). – caw Mar 08 '15 at 22:36

7 Answers7

51

Check into this thread,. However you should be careful as it's documented as "can change upon factory reset". Use at your own risk, and it can be easily changed on a rooted phone. Also it appears as if some manufacturers have had issues with their phones having duplicate numbers thread. Depending on what your trying to do, I probably wouldnt use this as a UID.

Community
  • 1
  • 1
ninjasense
  • 13,382
  • 17
  • 71
  • 91
  • 20
    it's a shame that ANDROID_ID's implementation is so ... lame ! Judging from Google's documentation, the intent was a longer lasting ID: `A 64-bit number (as a hex string) that is randomly generated on the device's first boot and should remain constant for the lifetime of the device` – Someone Somewhere Oct 16 '11 at 23:07
  • 3
    According to this thread [link](http://android-developers.blogspot.in/2011/03/identifying-app-installations.html) **"Also, there has been at least one widely-observed bug in a popular handset from a major manufacturer, where every instance has the same ANDROID_ID."** **Better not to use it** – Muhammad Riyaz Jul 11 '16 at 19:24
  • 2
    That was from 2011 during Froyo. It's irrelevant now. – Aubtin Samai Dec 28 '16 at 11:43
  • What about a device backup/restore or device cloning? any idea about the chance of having the same ANDROID_ID? assuming the device is not rooted of course. – FunkSoulBrother Jan 25 '18 at 12:53
40

With Android O the behaviour of the ANDROID_ID will change. The ANDROID_ID will be different per app per user on the phone.

Taken from: https://android-developers.googleblog.com/2017/04/changes-to-device-identifiers-in.html

Android ID

In O, Android ID (Settings.Secure.ANDROID_ID or SSAID) has a different value for each app and each user on the device. Developers requiring a device-scoped identifier, should instead use a resettable identifier, such as Advertising ID, giving users more control. Advertising ID also provides a user-facing setting to limit ad tracking.

Additionally in Android O:

  • The ANDROID_ID value won't change on package uninstall/reinstall, as long as the package name and signing key are the same. Apps can rely on this value to maintain state across reinstalls.
  • If an app was installed on a device running an earlier version of Android, the Android ID remains the same when the device is updated to Android O, unless the app is uninstalled and reinstalled.
  • The Android ID value only changes if the device is factory reset or if the signing key rotates between uninstall and
    reinstall events.
  • This change is only required for device manufacturers shipping with Google Play services and Advertising ID. Other device manufacturers may provide an alternative resettable ID or continue to provide ANDROID ID.
userM1433372
  • 4,925
  • 32
  • 37
  • Thanks. I was pulling my hairs out trying to figure out why I wasn't getting test ads in wife's phone using the (md5'ed) ID reported by Device ID and then why this wouldn't match the value reported through adb shell settings command... I thought I was going crazy. – ecv Sep 11 '19 at 19:12
15

So if you want something unique to the device itself, TM.getDeviceId() should be sufficient.

Here is the code which shows how to get Telephony manager ID. The android Device ID that you are using can change on factory settings and also some manufacturers have issue in giving unique id.

TelephonyManager tm = 
        (TelephonyManager) this.getSystemService(Context.TELEPHONY_SERVICE);
String androidId = Secure.getString(this.getContentResolver(), Secure.ANDROID_ID);
Log.d("ID", "Android ID: " + androidId);
Log.d("ID", "Device ID : " + tm.getDeviceId());

Be sure to take permissions for TelephonyManager by using

<uses-permission android:name="android.permission.READ_PHONE_STATE" />
Jon McClung
  • 1,438
  • 16
  • 25
Vincent Vettukal
  • 1,001
  • 11
  • 15
  • 3
    Yes, using the getDeviceId() also works. But you should be very careful as it may return null. (On devices without a 3g/phone modem) A solution I use is to fall back on the Wifi's mac-address (which of course could also be missing, but usually not on the same device) – vdstw Oct 09 '12 at 14:11
  • 20
    Requiring the `READ_PHONE_STATE` permission is awful. Use `ANDROID_ID` instead. – dolmen Nov 12 '12 at 00:11
  • yeah, it might return null on devices with no 3g (plenty of them on market), then you should use WiFi - its guid also might be null until you turn it on/off at least once after device reboot. And if no wifi... real nightmare, on windows ce there was GUID for each device and life was beautiful. – marcinj Nov 13 '12 at 16:58
  • it turns out after thousands of requests that the Device ID , which is the IMEI can be duplicated on fake devices, hence not a full proof solution. I am reverting to using getSimSerialNumber and ANDROID_ID as a fallback. – Ajibola Sep 16 '15 at 18:54
  • Android 10 (API level 29) adds restrictions for non-resettable identifiers, which include both IMEI and serial number. Before you implement the `TM.getDeviceId()` approach, first take a look at the [new permission requirements](https://source.android.com/devices/tech/config/device-identifiers) for device identifiers on Android >=10 devices. – Ezekiel Sebastine Nov 24 '20 at 09:20
8

There are multiple solution exist but none of them perfect. let's go one by one.

1. Unique Telephony Number (IMEI, MEID, ESN, IMSI)

  • This solution needs to request for android.permission.READ_PHONE_STATE to your user which can be hard to justify following the type of application you have made.

  • Furthermore, this solution is limited to smartphones because tablets don’t have telephony services. One advantage is that the value survives to factory resets on devices.

2. MAC Address

  • You can also try to get a MAC Address from a device having a Wi-Fi or Bluetooth hardware. But, this solution is not recommended because not all of the device have Wi-Fi connection. Even if the user have a Wi-Fi connection, it must be turned on to retrieve the data. Otherwise, the call doesn’t report the MAC Address.

3. Serial Number

  • Devices without telephony services like tablets must report a unique device ID that is available via android.os.Build.SERIAL since Android 2.3 Gingerbread. Some phones having telephony services can also define a serial number. Like not all Android devices have a Serial Number, this solution is not reliable.

4. Secure Android ID

  • On a device first boot, a randomly value is generated and stored. This value is available via Settings.Secure.ANDROID_ID . It’s a 64-bit number that should remain constant for the lifetime of a device. ANDROID_ID seems a good choice for a unique device identifier because it’s available for smartphones and tablets.

    String androidId = Settings.Secure.getString(getContentResolver(),Settings.Secure.ANDROID_ID);
    
  • However, the value may change if a factory reset is performed on the device. There is also a known bug with a popular handset from a manufacturer where every instance have the same ANDROID_ID. Clearly, the solution is not 100% reliable.

5. Use UUID

  • As the requirement for most of applications is to identify a particular installation and not a physical device, a good solution to get unique id for an user if to use UUID class. The following solution has been presented by Reto Meier from Google in a Google I/O presentation :

    private static String uniqueID = null;
    private static final String PREF_UNIQUE_ID = "PREF_UNIQUE_ID";
    public synchronized static String id(Context context) {
       if (uniqueID == null) {
           SharedPreferences sharedPrefs = context.getSharedPreferences(
                   PREF_UNIQUE_ID, Context.MODE_PRIVATE);
           uniqueID = sharedPrefs.getString(PREF_UNIQUE_ID, null);
           if (uniqueID == null) {
               uniqueID = UUID.randomUUID().toString();
               Editor editor = sharedPrefs.edit();
               editor.putString(PREF_UNIQUE_ID, uniqueID);
               editor.commit();
           }
       }    return uniqueID;
    }
    

Identify a particular device on Android is not an easy thing. There are many good reasons to avoid that. Best solution is probably to identify a particular installation by using UUID solution. credit : blog

Maveňツ
  • 8,899
  • 14
  • 49
  • 85
Radhey
  • 1,849
  • 1
  • 21
  • 38
6

I've read a few things about this and unfortunately the ANDROID_ID should not be relied on for uniquely identifying an individual device.

It doesn't seem to be enforced in Android compliance requirements and so manufacturers seem to implement it the way they choose including some using it more as a 'model' ID etc.

Also, be aware that even if a manufacturer has written a generator to make it a UUID (for example), it's not guaranteed to survive a factory reset.

Squonk
  • 47,603
  • 18
  • 99
  • 134
1

Just list an alternaitve solution here, the Advertising ID:

https://support.google.com/googleplay/android-developer/answer/6048248?hl=en

Copied from the link above:

The advertising ID is a unique, user-resettable ID for advertising, provided by Google Play services. It gives users better controls and provides developers with a simple, standard system to continue to monetize their apps. It enables users to reset their identifier or opt out of personalized ads (formerly known as interest-based ads) within Google Play apps.

The limitations are:

  1. Google Play enabled devices only.
  2. Privacy Policy: https://support.google.com/googleplay/android-developer/answer/113469?hl=en&rd=1#privacy
semicircle21
  • 642
  • 8
  • 10
0
//Fields
String myID;
int myversion = 0;


myversion = Integer.valueOf(android.os.Build.VERSION.SDK);
if (myversion < 23) {
        TelephonyManager mngr = (TelephonyManager) 
getSystemService(Context.TELEPHONY_SERVICE);
        myID= mngr.getDeviceId();
    }
    else
    {
        myID = 
Settings.Secure.getString(getApplicationContext().getContentResolver(), 
Settings.Secure.ANDROID_ID);
    }

Yes, Secure.ANDROID_ID is unique for each device.