Device Identifiers on Zebra Devices Running Android 10 – The Complete Guide
There are a few sample apps and guides floating around detailing how to retrieve device identifiers on Zebra devices running Android 10 and it is a common area we get questions about so, I thought it made sense to bring everything together in a single place.
Briefly, Android 10 limits access to device identifiers for all apps running on the platform regardless of their target API level, as explained in the docs for Android 10 privacy changes. This includes the serial number, IMEI, Bluetooth MAC and some other identifiable information.
Zebra mobile computers expose a mechanism to bypass these restrictions on device identifiers by providing the information through a separate mechanism, “OEM Info”. Initially the device serial number and IMEI were supported with the BT MAC address being added in a subsequent LifeGuard update. For clarity, the existing Android APIs (for Build.getSerial() for example) have not been modified and continue with their standard Android behaviour, which is to not return device information on Android 10.
The “OEM Info” mechanism exposes device identifiers via a content provider and is documented on TechDocs. There is an additional step before device identifiers can be accessed however which is to grant permission to the application to access OEM Info.
So, obtaining device identifiers on Zebra devices running Android 10 is a 2-step process:
- Grant permission to the application for each identifer it needs to access.
- Access the device identifiers via content providers exposed by OEM Info.
You are able to grant permission to the application in a number of ways, either the administrator will grant access (e.g. via StageNow or EMM) or you are able to grant access within the app itself using the EMDK profile manager.
The following shows the sample apps & documentation available:
Official documentation: https://techdocs.zebra.com/oeminfo/consume/
Name: Device Identifiers Wrapper
Recommended for: Developers who just want to access the device identifiers without worrying about anything else
Author: Laurent Trudu
Description: App will grant itself permission. Wraps all the permission and content provider logic into a simple to use wrapper object so the interface your application calls is very simple.
Name: Device Identifiers Sample
Recommended for: Developers who need to understand the permission model in a bit more detail.
Author: Darryn Campbell
Description: App must be granted permission by the administrator, e.g. through StageNow. Displays device serial number and IMEI obtained through Content provider.
Name: OEM Identifiers Sample
Recommended for: Developers who want to output the device identifiers to a file for consumption elsewhere.
Author: James Swinton-Bland
Description: App will grant itself permission. Writes the device serial number and IMEI to an .ini file.
Name: OEM Identifiers Sample Xamarin
Recommended for: Xamarin Developers who just want to access the device identifiers without worrying about anything else.
Author: Darryn Campbell
Description: App exposes buttons to grant itself permission and retrieve the device identifiers.
How can we get or grant access to the device identifiers under Android 11 or 12 when "Service Access Action" of the EMDK "Access Manager" profile, used here for Android 10, will be deprecated or removed?
We call profileManager.processProfile (...), specifying "SerialPermission", type SET and XML, as in the example (but with our own data, replacing the data in the CallerPackageName and CallerSignature tags) and get SUCCESS. Next, we try to call contentResolver.query (...) with "content: //oem_info/oem.zebra.secure/build_serial", but we get an empty cursor.
We tried to take an example and substitute our application data in XML - the situation is similar. Is there any other way to get the serial number? Or maybe you need some additional settings for the current method?
Which device model are you testing on? Which OS build, which MX version is running on your device?
Maybe you can post all relevant parts of your source code - disguising all private information like your value for "callerSignature" ...
Thanks a lot, Richard.