Android ID — life can be hard

Massattack
2 min readApr 2, 2021

Recently we had a requirement in a project to generate and use unique Android ID. Sounds simple and straightforward but in Android world it isn’t.

Some prerequisites:

  • the ID should survive application uninstall and re-install

Let’s start digging:

  • using hardware IDs in Android…just forget about it. Now it requires special permission like READ_PRIVILEGED_PHONE_STATE. More info here: https://source.android.com/devices/tech/config/device-identifiers
  • well, let’s use UUID then — we’ll generate one, save it in the storage and use it. If you save it in the external storage — it will survive uninstall and re-install but you will leave some scrap after your app uninstall which is something I wouldn’t advice you to do. Other problem with this approach is that the file can be deleted by the user and this is going to be the end of the persistence. There is another option: save the ID in the local storage, enable application backup in the manifest and your ID will be saved and restored on app re-install. This sounds like a solution but it comes to a price: adding permissions, handle writing/reading processes, exposing data.
  • use Advertising ID. More info here: https://developer.android.com/training/articles/user-data-ids. Sounds like a good option but it is resettable and introduces third-party dependency.
  • Media DRM ID — well, this one sounds like a really good candidate: survives uninstall/re-install, no additional third-party dependencies introduced, no permissions requested. And it is simple like this:
private val widevineUuid = UUID(-0x121074568629b532L, -0x5c37d8232ae2de13L)

private fun getUniqueId(): String? {
val mediaDrm = MediaDrm(widevineUuid)
return try {
val uniqueId = mediaDrm.getPropertyByteArray(MediaDrm.PROPERTY_DEVICE_UNIQUE_ID)
android.util.Base64.encodeToString(uniqueId, android.util.Base64.NO_WRAP)
} catch (e: Exception) {
e.printStackTrace()
null
} finally {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.P) {
mediaDrm.close()
} else {
mediaDrm.release()
}
}
}

--

--