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
Regarding Android 10:
In the interests of user privacy, Google has restricted APIs that retrieve non-resettable device identifiers such as the serial number and IMEI. This is documented in Google's Privacy changes in Android 10 guide. The only apps that can use
Build.getSerial
(which replacedBuild.SERIAL
in Android 9) are:If your target SDK is 28 or lower (Android 9/P), and you have the READ_PHONE_STATE permission, calling Build.getSerial will return Build.UNKNOWN. Otherwise (you don't have the permission, or your target SDK is 29 or higher) it throws a SecurityException.
Google state that you should use a different identifier, one that is resettable by the user. For example, use Settings.Secure.ANDROID_ID, which is persistent until the user factory resets the device. If you have more than one app, they will all see the same ID as long as you're using the same signing key to sign all the apps (from Android 8.0 onwards; before Android 8.0 all apps would see the same value).
Some of the other methods to get the serial number may still work, where the manufacturer provided a different method which hasn't been blocked by Google's change. But really, you should stop trying to do this. Google may restrict non-SDK interfaces in future: Restrictions on non-SDK interfaces. That said,
android.os.SystemProperties.get
is whitelisted in Android 10 and 11.