Skip to content

Instantly share code, notes, and snippets.

@flawyte
Last active March 8, 2024 06:05
Show Gist options
  • Star 46 You must be signed in to star a gist
  • Fork 18 You must be signed in to fork a gist
  • Save flawyte/efd23dd520fc2320f94ba003b9aabfce to your computer and use it in GitHub Desktop.
Save flawyte/efd23dd520fc2320f94ba003b9aabfce to your computer and use it in GitHub Desktop.
How to get an Android device's serial number, visible to the user in "Settings > About phone/tablet/device > Status > Serial number".

NOTE 2021/01/08: As of Android 10 (API level 29), there's no way for non-system and non-carrier apps to get the device's serial number, not even by calling the new Build.getSerial() method with the READ_PHONE_STATE permission, since per the docs it'll always either return Build.UNKNOWN (API < 29) or throw a SecurityException (API >= 29). This means that the code below might not work on some devices running Android 10+, due to changes in the Android OS itself and AFAIK there's no work around. See this official guide to migrate from using the device's serial number ; the Settings.Secure.ANDROID_ID might also be a good replacement. Also read the comments to see how other people are dealing with this problem, maybe someone has found a solution that will help you.

Devices tested

This code snippet has been successfully tested on the following devices and Android versions :

  • Archos 133 Oxygen : 6.0.1
  • Google Nexus 5 : 6.0.1
  • Hannspree HANNSPAD 13.3" TITAN 2 (HSG1351) : 5.1.1
  • Honor 5C (NEM-L51) : 7.0
  • Honor 5X (KIW-L21) : 6.0.1
  • Honor 9 Lite (LLD-L31) : 8.0
  • Huawei M2 (M2-801w) : 5.1.1
  • Samsung Galaxy S5 (SM-G900F) : 6.0.1
  • Samsung Galaxy S6 (SM-G920F) : 7.0
  • Samsung Galaxy Tab 4 (SM-T530) : 5.0.2
  • Xiaomi Mi 8 (M1803E1A) : 8.1.0
import android.os.Build;
import java.lang.reflect.Method;
public class Device {
/**
* @return The device's serial number, visible to the user in {@code Settings > About phone/tablet/device > Status
* > Serial number}, or {@code null} if the serial number couldn't be found
*/
public static String getSerialNumber() {
String serialNumber;
try {
Class<?> c = Class.forName("android.os.SystemProperties");
Method get = c.getMethod("get", String.class);
// (?) Lenovo Tab (https://stackoverflow.com/a/34819027/1276306)
serialNumber = (String) get.invoke(c, "gsm.sn1");
if (serialNumber.equals(""))
// Samsung Galaxy S5 (SM-G900F) : 6.0.1
// Samsung Galaxy S6 (SM-G920F) : 7.0
// Samsung Galaxy Tab 4 (SM-T530) : 5.0.2
// (?) Samsung Galaxy Tab 2 (https://gist.github.com/jgold6/f46b1c049a1ee94fdb52)
serialNumber = (String) get.invoke(c, "ril.serialnumber");
if (serialNumber.equals(""))
// Archos 133 Oxygen : 6.0.1
// Google Nexus 5 : 6.0.1
// Hannspree HANNSPAD 13.3" TITAN 2 (HSG1351) : 5.1.1
// Honor 5C (NEM-L51) : 7.0
// Honor 5X (KIW-L21) : 6.0.1
// Huawei M2 (M2-801w) : 5.1.1
// (?) HTC Nexus One : 2.3.4 (https://gist.github.com/tetsu-koba/992373)
serialNumber = (String) get.invoke(c, "ro.serialno");
if (serialNumber.equals(""))
// (?) Samsung Galaxy Tab 3 (https://stackoverflow.com/a/27274950/1276306)
serialNumber = (String) get.invoke(c, "sys.serialnumber");
if (serialNumber.equals(""))
// Archos 133 Oxygen : 6.0.1
// Hannspree HANNSPAD 13.3" TITAN 2 (HSG1351) : 5.1.1
// Honor 9 Lite (LLD-L31) : 8.0
// Xiaomi Mi 8 (M1803E1A) : 8.1.0
serialNumber = Build.SERIAL;
// If none of the methods above worked
if (serialNumber.equals(Build.UNKNOWN))
serialNumber = null;
} catch (Exception e) {
e.printStackTrace();
serialNumber = null;
}
return serialNumber;
}
}
@vmsJenni
Copy link

vmsJenni commented Jan 8, 2021

We still have a lot of different devices running OS 10 that continue to retrieve a valid id using this code - however, most are defaulting to:
deviceID= Build.SERIAL;

It seems that this starts to return 'UNKNOWN' once the Build.ID value is updated - our Galaxy Tab S5e continued to retrieve a valid ID while on OS 10, until recently the Build.ID was updated to: QP1A.190711.020

To handle the situations where the ID will change, or return 'UNKNOWN', we tiered our getID method to 1st try:
deviceID = Build.SERIAL;

If it returned empty or 'unknown', then we try:
deviceID= Settings.Secure.getString(getApplicationContext().getContentResolver(), Settings.Secure.ANDROID_ID);

If that returns empty or 'unknown', then we default to using MediaDrm to get an ID.

In our case, we are able to handle if the deviceID changes by always sending the current ID, and the 'last_used' ID to our validation check - if the new ID is not found, we then look for a record containing the old ID. If neither is found, no record exists...

In the end, we probably could have just resorted to creating a GUID initially, and use the same validation checking, since it handles changes, but I'm always concerned if ever these generated GUID's might duplicate somewhere... keeps it fun, right?

@SaketSharma11
Copy link

@vmsJenni ok .Thank you so much, I will try and see.

@NaagAlgates
Copy link

As @MikeDimmickMnetics explained, using the above method for retrieving the phone's serial number isn't reliable anymore.
I actually had added a paragraph explaining that too a few months ago but since people reported this code to be still working on Android 10 I eventually removed it. I'll add it back.

Please add the code which works on Android 10. I need it because the above code is not working on my device.

I don't think it is possible anymore.

NOTE 2021/01/08: As of Android 10 (API level 29), there's no way for non-system and non-carrier apps to get the device's serial number, not even by calling the new Build.getSerial() method with the READ_PHONE_STATE permission, since per the docs it'll always either return Build.UNKNOWN (API < 29) or throw a SecurityException (API >= 29). This means that the code below might not work on some devices running Android 10+, due to changes in the Android OS itself and AFAIK there's no workaround. See this official guide to migrate from using the device's serial number; the Settings.Secure.ANDROID_ID might also be a good replacement.

Also read the comments to see how other people are dealing with this problem, maybe someone has found a solution that will help you.

@mdinopol
Copy link

Testing on Xiaomi Redmi 9C (Android 10). always returns unknown.
Does this have resolution for android 10?

@flawyte
Copy link
Author

flawyte commented Sep 14, 2021

@ammdsoftdev
Testing on Xiaomi Redmi 9C (Android 10). always returns unknown.
Does this have resolution for android 10?

As written in the readme it's not possible anymore to get the device's serial number on devices running Android 10 or newer. AFAIK there's no workaround since it's a limitation enforced by the Android OS itself.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment