Unique Android Device ID after MarshMallow warning "get device identifiers is not recommended"?
Asked Answered
P

3

20

I saw one of my best question Is there a unique Android device ID?

Edited:

I need a solution for Android 10 too.

I used some following code to get Unique Id.

public static String getDeviceId(Activity context) {

    PermissionsChecker checker = new PermissionsChecker(context);

    if (checker.lacksPermissions(Manifest.permission.READ_PHONE_STATE))
        PermissionsActivity.startActivityForResult(context, 0, REQUIRED_PERMISSION);
    else {
        TelephonyManager tm = (TelephonyManager) context.getSystemService(Context.TELEPHONY_SERVICE);

        final String tmDevice = tm.getDeviceId();
        final String androidId = Settings.Secure.getString(context.getContentResolver(), Settings.Secure.ANDROID_ID);

        UUID deviceUuid = new UUID(androidId.hashCode(), ((long) tmDevice.hashCode() << 32));

        return deviceUuid.toString();
    }
    return null;
}

But I am getting some warning on hover on

tm.getDeviceId();

and

Settings.Secure.getString(context.getContentResolver(), Settings.Secure.ANDROID_ID); as following:

Using getString to get device identifiers is not recommended.

Using device identifiers is not recommended other than for high value fraud prevention and advanced telephony use-cases. For advertising use-cases, use AdvertisingIdClient$Info#getId and for analytics, use InstanceId#getId.

Is there any solution? Is it harmful or anything else?

Poff answered 27/10, 2016 at 11:25 Comment(8)
You can use IMEI number as unique identifier. And this is just warning as now a days hacker root phones and change the device id .Cargian
It will be change after restore factory. I dont want that.Poff
No, IMEI Will not change in any case.Cargian
as per my exp...it is always best to generate unique server key rather than depending on app (if you are using it)Regulate
look at here , may help you : developer.android.com/training/articles/…Semasiology
As I know, ANDROID_ID will changed after formatted & factory resetHerpes
@rushankshah IMEI no will not work for Tables which don't have sim cards.Poff
@PratikButani IMEI will also not work from android 10 and above. Alternatively you can check official doc for unique identifier https://developer.android.com/training/articles/user-data-idsCargian
C
1

The very easy answer is if you need to uniquily identify each user of your app create a random id at first use.

    UUID.randomUUID().toString()

You can save it in SharedPreferences and the easy work is done. No permissions needed

The problem is that it wont help you if user unninstall and reinstall the app.

One easy trick that is possible to do until android 10 (and wont be possible anymore on android 11 according to google) is save it in a hidden file in the external storage...

then on first use of app you look for such file, if it exists read the UUID, case not generate a new one and save the file.

The problem with this strategy is YOU NEED WRITE_EXTERNAL_STORAGE PERMISSION

in case this isnt a problem simple do...

new File(Environment.getExternalStorageDirectory().getAbsolutePath() + File.separator + ".my_hidden_folder").mkdir();

Any file saved inside this folder will be hidden to user, wont be removed on unninstall of your app

I personally use

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

This isn't harmful is just that google dont like you doing it

Colitis answered 16/3, 2020 at 13:21 Comment(0)
S
1

It's the limitation added in Andorid Q that getDeviceId will work for only system Apps.If you try to use this it will throw exception

SecurityException: getDeviceId: The user 10196 does not meet the requirements to access device identifiers.

You can read more Andorid Q Changes from this link

Anyhow after searching and seeing many solutions i found this one which is working for every Android for getting UUID works great.

//This method is fully compatible with Android 1 to Android 10
public static String getDeviceUUID(Context context) {
    String serial = null;
    String m_szDevIDShort = "35" +
            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 Bit
    try {
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O && ActivityCompat.checkSelfPermission(context, Manifest.permission.READ_PHONE_STATE) == PackageManager.PERMISSION_GRANTED) {
            serial = android.os.Build.getSerial();
        } else {
            serial = Build.SERIAL;
        }
        //API>=9 Use serial number
        return new UUID(m_szDevIDShort.hashCode(), serial.hashCode()).toString();
    } catch (Exception exception) {
        //serial Need an initialization
        serial = "serial"; // Random initialization
    }
    // 15-digit number cobbled together using hardware information
    return new UUID(m_szDevIDShort.hashCode(), serial.hashCode()).toString();
}
Sebiferous answered 22/3, 2020 at 1:42 Comment(0)
M
0

Quite some time ago I needed to have a persistant unique ID per device and I encountered the same problem. Here are the solutions I found:

  1. IMEI : Worst Solution: Android devices without SIM card such as lots of tablets are excluded and you need to ask for "making calls" permission to get it, which no one would be willing to grant.

  2. Device Serial Number : Good solution, unique value; but deprecated in API level 26 and the new method needs permission in Android 10.

  3. SSID (aka Android_ID) : I think despite the warning this is a good solution. No repetitive record.

Some semi-unique solutions include:

Build.FINGERPRINT : A unique record for the build. No warnings. it limits the devices to a much smaller range.

Build.TIME : the time in millisecond since device ROM was produced.

Hint: Making a mix of hardware properties will not work as they may be similar (a factory manufactures tons of a model) and in order to achieve a unique ID you may need permissions.

Hint 2: Saving records on device memory is a waste of time because it is always possible to change/remove them.

Medusa answered 22/3, 2020 at 2:58 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.