monxas
monxas

Reputation: 2657

Generating unique id in android (UUID)

for months I've been using a class to generate a UUID that was solid between reintalls. My app is about discounts so I rely on this UUID to limit the number of coupons per device.

protected void getDeviceId(){
    try {
        Context context = cordova.getActivity().getApplicationContext();
        TelephonyManager tm = (TelephonyManager) context.getSystemService(Context.TELEPHONY_SERVICE);

        String uuid;
        String androidID = Secure.getString(context.getContentResolver(), Secure.ANDROID_ID);
        String deviceID = tm.getDeviceId();
        String simID = tm.getSimSerialNumber();

        if ("9774d56d682e549c".equals(androidID) || androidID == null) {
            androidID = "";
        }

        if (deviceID == null) {
            deviceID = "";
        }

        if (simID == null) {
            simID = "";
        }

        uuid = androidID + deviceID + simID;
        uuid = String.format("%32s", uuid).replace(' ', '0');
        uuid = uuid.substring(0, 32);
        uuid = uuid.replaceAll("(\\w{8})(\\w{4})(\\w{4})(\\w{4})(\\w{12})", "$1-$2-$3-$4-$5");

        this.callbackContext.success(uuid);
    }catch(Exception e ) {
        this.callbackContext.error("Exception occurred: ".concat(e.getMessage()));
    }
}

That's the core of how I generate my uuid. The thing is this weekend someone with an XT1032 and android 5.1 was able to regenerate different UUIDs after each installation of the app, getting free coupons. This method that I use can be tricked somehow? Maybe with a rooted phone? I'm shooting in the blind. I need to be able to create reliable UUIDs between installations.

Upvotes: 20

Views: 47506

Answers (4)

FrankKrumnow
FrankKrumnow

Reputation: 508

Beginning with Android 10 google restricts access to all hardware-identifying IDs to System apps or apps that act as a fully fledged mdm controller (afaik). Before you had to ask the user for permission and now you cannot even do that.

More often you want to the app to be paid per device not paid per google account which can be used on a multitude of devices) but it should apply for your coupons too.

Google only advises to use their firebase ID system for anything like that. They will always state security while assuring that you need to use google services for that.

The only way around that I can think of is your own webservice with user account + password (giving a session token or something) but that would be too inconvienient for a coupon app?

Upvotes: 1

Abbas
Abbas

Reputation: 3331

Your UUID depends on three of different IDs, all of which are easily changeable. There is no way to be sure whether this is the reason, but looking at the code here:

SSN (SIM serial number) getSimSerialNumber() gets you SSN for the sim card attached. A simple way to generate a different UUID for same device would be simply to insert a different sim card. Which I know is cumbersome, but doable nonetheless.

IMEI/MEID getDeviceId() returns IMEI or MEID. So another way would be to change the IMEI of the device. If you only google "change phone IMEI without root" you will get loads of doable results. Which might be an easier way (if automated).

Android Device ID ANDROID_ID according to docs changes with each time phone is restored. So again user can change UUID just by restoring phone.

Since your UUID is based on a chain of three unique ids fooling the system is as easy as the weakest link in your chain. ANDROID_ID being the strongest link in this chain I'd recommend you to only use it instead. Refer to this link as an alternative.


EDIT:

While ANDROID_ID is still the best way to recognize previous users there have been some updates to its use and uniqueness since Oreo. Visit the #ANDROID_ID page for more details.

A summary of the changes are:

Each ANDROID_ID on apps targeting Android Oreo or later and installed on Android Oreo or later are unique by the user who installed the app, the app's signature (essentially different for different apps but not necessarily) and the device. So while you will still get the same id in most cases, installing the app as a different user will still generate a different ANDROID_ID. These changes are made to protect user's privacy.

There have also been updates on permissions for ANDROID_ID.

Upvotes: 9

Tim
Tim

Reputation: 43354

I need to be able to create reliable UUIDs between installations.

If that is the only criteria, the proposal in this answer is your best bet. Do note that the ANDROID_ID may change after a factory reset of the device, so it will never be something that cannot trick your app.

Most other "UUIDs" may already change in between app installations as you have noticed.

For more info please read google's Best Practices for Unique Identifiers. It is a must read.

Upvotes: 2

vidulaJ
vidulaJ

Reputation: 1270

I've used this before and working fine for me.

public String createTransactionID() throws Exception{
    return UUID.randomUUID().toString().replaceAll("-", "").toUpperCase();
}

Upvotes: 33

Related Questions