60

I'm looking for help to get the UUID of my Android phone. I have searched the net and found one potential solution but it is not working in the emulator.

Here is the code:

Class<?> c;
try {
    c = Class.forName("android.os.SystemProperties");
    Method get = c.getMethod("get", String.class);
    serial = (String) get.invoke(c, "ro.serialno");
    Log.d("ANDROID UUID",serial);
} catch (Exception e) {
    e.printStackTrace();
}

Does anybody know why it isn't working, or have a better solution?

Cody Gray - on strike
  • 239,200
  • 50
  • 490
  • 574
bHaRaTh
  • 3,464
  • 4
  • 34
  • 32
  • See this post http://stackoverflow.com/questions/4468248/unique-id-of-android-device – Mudassir Feb 23 '11 at 08:24
  • 1
    @Mudassir Thaks. i looked at it, so there are lots of answers fpr ur question there, but which is optimistic. and i also found a solution to generate unique UUID based on hostname, MAC address, OS name and version. but how to get the inbuilt UUID. – bHaRaTh Feb 23 '11 at 08:32
  • There is no inbuilt UUID. You have Android ID generated at first boot, as suggested by Mudassir, or you have IMEI which is unique ID of your GSM device provided by manufacturer. – Zelimir Feb 23 '11 at 08:44
  • Thank u Zelimir, that cleared my Doubt. so using UUID generation algorithms i will generate one.so that is more than enough right? – bHaRaTh Feb 23 '11 at 08:56
  • Yes, you can be sure it is unique. – Zelimir Feb 23 '11 at 09:03
  • Yes Zelimir it is unique because it is generating based in hostname, MAC address, OS name and version. i got that fron CLING Api. – bHaRaTh Feb 23 '11 at 09:29
  • 1
    I noted that `ro.serialno` and `android.os.Build.SERIAL` are identical on a Nexus-One with Gingerbread. – Martin Jun 23 '11 at 08:43

8 Answers8

104

As Dave Webb mentions, the Android Developer Blog has an article that covers this. Their preferred solution is to track app installs rather than devices, and that will work well for most use cases. The blog post will show you the necessary code to make that work, and I recommend you check it out.

However, the blog post goes on to discuss solutions if you need a device identifier rather than an app installation identifier. I spoke with someone at Google to get some additional clarification on a few items in the event that you need to do so. Here's what I discovered about device identifiers that's NOT mentioned in the aforementioned blog post:

  • ANDROID_ID is the preferred device identifier. ANDROID_ID is perfectly reliable on versions of Android <=2.1 or >=2.3. Only 2.2 has the problems mentioned in the post.
  • Several devices by several manufacturers are affected by the ANDROID_ID bug in 2.2.
  • As far as I've been able to determine, all affected devices have the same ANDROID_ID, which is 9774d56d682e549c. Which is also the same device id reported by the emulator, btw.
  • Google believes that OEMs have patched the issue for many or most of their devices, but I was able to verify that as of the beginning of April 2011, at least, it's still quite easy to find devices that have the broken ANDROID_ID.
  • When a device has multiple users (available on certain devices running Android 4.2 or higher), each user appears as a completely separate device, so the ANDROID_ID value is unique to each user.

Based on Google's recommendations, I implemented a class that will generate a unique UUID for each device, using ANDROID_ID as the seed where appropriate, falling back on TelephonyManager.getDeviceId() as necessary, and if that fails, resorting to a randomly generated unique UUID that is persisted across app restarts (but not app re-installations).

Note that for devices that have to fallback on the device ID, the unique ID WILL persist across factory resets. This is something to be aware of. If you need to ensure that a factory reset will reset your unique ID, you may want to consider falling back directly to the random UUID instead of the device ID.

Again, this code is for a device ID, not an app installation ID. For most situations, an app installation ID is probably what you're looking for. But if you do need a device ID, then the following code will probably work for you.

import android.content.Context;
import android.content.SharedPreferences;
import android.provider.Settings.Secure;
import android.telephony.TelephonyManager;

import java.io.UnsupportedEncodingException;
import java.util.UUID;

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 (DeviceUuidFactory.class) {
                if( uuid == null) {
                    final SharedPreferences prefs = context.getSharedPreferences( PREFS_FILE, 0);
                    final String id = prefs.getString(PREFS_DEVICE_ID, null );

                    if (id != null) {
                        // Use the ids previously computed and stored in the prefs file
                        uuid = UUID.fromString(id);

                    } else {

                        final String androidId = Secure.getString(context.getContentResolver(), 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 = UUID.nameUUIDFromBytes(androidId.getBytes("utf8"));
                            } else {
                                final String deviceId = ((TelephonyManager) context.getSystemService( Context.TELEPHONY_SERVICE )).getDeviceId();
                                uuid = deviceId!=null ? UUID.nameUUIDFromBytes(deviceId.getBytes("utf8")) : UUID.randomUUID();
                            }
                        } catch (UnsupportedEncodingException e) {
                            throw new RuntimeException(e);
                        }

                        // Write the value out to the prefs file
                        prefs.edit().putString(PREFS_DEVICE_ID, uuid.toString() ).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
     * TelephonyManager.getDeviceID() 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 TelephonyManager.getDeviceId(), 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 http://code.google.com/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;
    }
}
alkber
  • 1,426
  • 2
  • 20
  • 26
emmby
  • 99,783
  • 65
  • 191
  • 249
  • 1
    1. Why did you use Secure.getString(context.getContentResolver(), Secure.ANDROID_ID); when we can directly Access the constant from Secure.ANDROID_ID ? 2. Can't we use UUID.fromString(ANDROID_ID), instead of getBytes("utf8") ? – alkber May 14 '14 at 08:05
  • Why did you choose not to also post this code into GitHub or similar where it would be easier to share and maintain? – AWrightIV Jan 20 '17 at 17:55
  • @AWrightIV Answers are supposed to be self-contained; linking to Github is the opposite of what we're going for – Michael Mrozek Sep 27 '18 at 02:02
  • Android Studio 3.1.3 creates a warning telling NOT to use getString(). Post is still very helpful but somewhat out-dated I suppose? – JamisonMan111 Jul 28 '19 at 07:04
67

This works for me:

TelephonyManager tManager = (TelephonyManager)getSystemService(Context.TELEPHONY_SERVICE);
String uuid = tManager.getDeviceId();

EDIT :

You also need android.permission.READ_PHONE_STATE set in your Manifest. Since Android M, you need to ask this permission at runtime.

See this anwser : https://stackoverflow.com/a/38782876/1339179

Community
  • 1
  • 1
pedr0
  • 2,941
  • 6
  • 32
  • 46
9

Instead of getting IMEI from TelephonyManager use ANDROID_ID.

Settings.Secure.ANDROID_ID

This works for each android device irrespective of having telephony.

porwalankit
  • 431
  • 4
  • 8
9
 String id = UUID.randomUUID().toString();

See Android Developer blog article for using UUID class to get uuid

ahmed hamdy
  • 5,096
  • 1
  • 47
  • 58
Gopi cg
  • 169
  • 1
  • 2
7
<uses-permission android:name="android.permission.READ_PHONE_STATE"></uses-permission>
Looking Forward
  • 3,579
  • 8
  • 45
  • 65
4

As of API 26, getDeviceId() is deprecated. If you need to get the IMEI of the device, use the following:

 String deviceId = "";
    if (Build.VERSION.SDK_INT >= 26) {
        deviceId = getSystemService(TelephonyManager.class).getImei();
    }else{
        deviceId = getSystemService(TelephonyManager.class).getDeviceId();
    }
DummyData
  • 645
  • 9
  • 14
  • SThis requires permission "android.permission.READ_PRIVILEGED_PHONE_STATE". Starting from android 10, you can't put this permission in manifest. "The READ_PRIVILEGED_PHONE_STATE permission is only granted to apps signed with the platform key and privileged system apps." -> source.android.com/docs/core/connect/device-identifiers Hence this won't work from Android 10 onwards – Ajji May 01 '23 at 23:20
1

Add

  <uses-permission android:name="android.permission.READ_PHONE_STATE"/>

Method

String getUUID(){
    TelephonyManager teleManager = (TelephonyManager) getSystemService(TELEPHONY_SERVICE);
    String tmSerial = teleManager.getSimSerialNumber();
    String tmDeviceId = teleManager.getDeviceId();
    String androidId = android.provider.Settings.Secure.getString(getContentResolver(), android.provider.Settings.Secure.ANDROID_ID);
    if (tmSerial  == null) tmSerial   = "1";
    if (tmDeviceId== null) tmDeviceId = "1";
    if (androidId == null) androidId  = "1";
    UUID deviceUuid = new UUID(androidId.hashCode(), ((long)tmDeviceId.hashCode() << 32) | tmSerial.hashCode());
    String uniqueId = deviceUuid.toString();
    return uniqueId;
}
KongJing
  • 475
  • 5
  • 7
  • Worked great, nice fallbacks. Since I'm a n00b to Android programming, it wasn't working for me until I requested Manifest.permission.READ_PHONE_STATE on the page – deebs Oct 21 '16 at 14:27
  • Thanks your advice ,this is a supplement. – KongJing Oct 21 '16 at 16:03
0

I think you can technically generate a unique one using the ANDROID_ID, something like:

UUID.nameUUIDFromBytes(Settings.Secure.ANDROID_ID.encodeToByteArray()).toString()
  • As it’s currently written, your answer is unclear. Please [edit] to add additional details that will help others understand how this addresses the question asked. You can find more information on how to write good answers [in the help center](/help/how-to-answer). – Community Apr 22 '23 at 02:08