0

From this thread, it can say that Settings.Secure#ANDROID_ID can be null sometimes. On the other hand, the telephony-based ID can be null too in tablet devices and can be changed if user change the SIM card or flight mode.

Thinking of getting mac address, from this thread, sometimes the mac address cannot be got too.

Is there any solution that I can get Android unique ID that won't change in any condition?

Community
  • 1
  • 1
Rendy
  • 5,572
  • 15
  • 52
  • 95

2 Answers2

0

Rendy, the code I used for that is the above (from emmby answer (with minimal modifications) of question Is there a unique Android device ID?):

public class DeviceUuidFactory {
    protected static final String PREFS_FILE = "device_id.xml";
    protected static final String PREFS_DEVICE_ID = "device_id";
    protected volatile 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;
    }
}

To use that in an Activity, do the following:

UUID identifier = new DeviceUuidFactory(this).getDeviceUuid();
Community
  • 1
  • 1
dgimenes
  • 892
  • 11
  • 23
0

The options you mentioned cover pretty much all the different scenarios to get a unique ID, there's also a unique ID value provided by the OS which has been proved was incorrectly implemented by some vendors and it returns the same value for all the devices of that specific vendor, so No, there's no 1 and only best way to do it, usually you need to combine and validate if one or another exist, for example in our project:

  • First we go for TelephonyManager and if it exist we take it from there

  • If not( as is the case in most tablets), then we go for MAC address

  • If not, then we use the Android unique ID provided in Settings.

Hope it helps!

Regards!

Martin Cazares
  • 13,637
  • 10
  • 47
  • 54
  • I was thinking of this solution too but I hope if there is one solution to get never changed unique ID :) Thanks anyway! – Rendy Mar 11 '14 at 19:09