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 returnBuild.UNKNOWN
(API < 29) or throw aSecurityException
(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.
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
Build.getSerial() calls to IDeviceIdentifiersPolicyService.getSerialForPackage(...) and returns SystemProperties.get("ro.serialno", Build.UNKNOWN);
So, it miss all the other vendor keys