Android Tutorial Android Device Unique ID - Alternative to PhoneId

Status
Not open for further replies.
This is an old tutorial. It will not work on new versions of Android. You should either generate a random value when the app starts for the first time or use the advertising id: https://www.b4x.com/android/forum/threads/advertising-id.101050/#content

This tutorial is based on the following blog post: Identifying App Installations | Android Developers Blog

The standard way to get a unique id is using PhoneId.GetDeviceId. However this method has several disadvantages:
- It requires the "android.permission.READ_PHONE_STATE" permission which is quite a sensitive permission.
- It doesn't work on devices without phone functionality.
- Apparently there is a bug in some devices which return the same id.

Starting from Android 2.3 there is a new field that returns a unique id and should work on all devices (without requiring any permission).

A general solution is to use this field for modern devices and to use a "fake" id for older devices. The fake id is randomly created when the application first runs.

Here is the code (requires the Reflection library):
B4X:
Sub Activity_Create(FirstTime As Boolean)
   Log(GetDeviceId)
End Sub

Sub GetDeviceId As String
   Dim r As Reflector
   Dim Api As Int
   Api = r.GetStaticField("android.os.Build$VERSION", "SDK_INT")
   If Api < 9 Then
      'Old device
      If File.Exists(File.DirInternal, "__id") Then
         Return File.ReadString(File.DirInternal, "__id")
      Else
         Dim id As Int
         id = Rnd(0x10000000, 0x7FFFFFFF)
         File.WriteString(File.DirInternal, "__id", id)
         Return id
      End If
   Else
      'New device
      Return r.GetStaticField("android.os.Build", "SERIAL")
   End If
End Sub
 
Last edited:

joneden

Active Member
Licensed User
Longtime User
Yeah I was hoping that maybe something had come up since :)

I think what I may have to do is primarily use the IMEI falling back on the android_ID if no IMEI, that will apply to approx 70% of my units. Better than just using the android_ID :)

Thanks for the swift response Erel!
 

Informatix

Expert
Licensed User
Longtime User
Another unique ID on a device is the MAC address. To get it (with the Reflection library):
B4X:
Dim R As Reflector
R.Target = R.GetContext
R.Target = R.RunMethod2("getSystemService", "wifi", "java.lang.String")
R.Target = R.RunMethod("getConnectionInfo")
Log(R.RunMethod("getMacAddress"))
That needs the following permission in the manifest:
AddPermission(android.permission.ACCESS_WIFI_STATE)

Since this is the address of the network card, it won't change whatever you do on/with the device (except changing the card of course), contrary to Android_Id.
 
Last edited:

moster67

Expert
Licensed User
Longtime User
MAC Address is indeed a solution but not foolproof. There are customized ROMs where the MAC Address is hardcoded and all devices running the same ROMs will have the same MAC Address. This happened frequently with HTC HD2 which was converted from a Windows Mobile device into an Android.

But yes, I agree, 99% of times the MAC Address should be sufficient.
 

Informatix

Expert
Licensed User
Longtime User
I don't think there's anything foolproof. On a rooted device, you can change the MAC address and there's even a tutorial on the XDA-Dev forum explaining how to do MAC spoofing with Android! But for the honest user, with a license and an unhacked device, I want to guarantee that he/she will be properly identified whatever he/she does with the device. Recently, I reinstalled many times Android on one of my tablets because I was testing many advanced things on it and I saw that my Android_ID was different.
The problem with the MAC address is that you identify a device, not a specific user on the device (Android_id is tied to a profile on some devices like my Nexus 7).
 
Last edited:

krzyszp

Member
Licensed User
Longtime User
I have another question... Is MAC address same when user uses WiFi and Mobile connection? How to check this?
I'm currently work on app for customer who release 40+ tablets for staff and devices need to be synchronised independently (same user can use different tablets sometimes), so I need really unique number (string) for each tablet...
 

IslamQabel

Active Member
Licensed User
Longtime User
Hi Everybody i just copy that code and paste it into B4A, when the program run and installed i see black layout without displaying anything why???
 

nwhitfield

Active Member
Licensed User
Longtime User
I use a device ID in an app for a website I run; we have an authorisation mechanism where a user can authenticate a device in their browser, and if they lose the device, disable it from accessing the site. So, a unique ID is pretty important. The code from earlier works for most devices, but every so often, I come across some where it turns out that each, or at least more than one, example of a device is generating the same ID. So far, I've found that three devices that do this, so I figured it might be useful to list them here for other people to worry about:

Wiko Cink Five, popular in France; both examples returned the code 0123456789ABCDEF; so too did something identified as "ASP-4500Z"
Motorola XT615, both reported "MSM7627A"
Verizon VS910 4G, both examples reported "9774d56d682e549c"

We have a pretty small cohort of users - only around 350 - so I don't know how widespread this problem is, but clearly there are phones out there in the wild that just don't return a unique number.

So far, I've just put in a fix for each one, but I'm tempted to change the mechanism for all devices. At the moment if I detect one of the offenders mentioned above, I create a fake ID from the MAC address, or the timestamp, and append that to the device id (which allows me to keep track of repeat offenders), with code like this:

B4X:
Dim suffix As String   
        Dim wifi As ABWifi
        If wifi.ABLoadWifi = True Then
            Log("Checking wifi MAC")
            suffix = wifi.ABGetCurrentWifiInfo.MacAddress.Replace(":","")
        Else
            ' if we can't get a mac address, let's make a fake id, unless we did that already
            If StateManager.GetSetting2("fakeID","") = "" Then
                Log("Faking device id")
                suffix = "DevAPI" & Api & DateTime.Now
                StateManager.SetSetting("fakeID",suffix)
                StateManager.SaveSettings
            Else
                Log("Using stored fake id")
                suffix = StateManager.GetSetting("fakeID")
            End If
        End If
        'ToastMessageShow("Mac is " & id, False)
       
        id = id & "-" & suffix

Of course, this will still not be sufficient where a MAC address is shared between all examples. The code above runs only when one of the problematic IDs, or an empty value, has been returned.
 

manolis

Member
Licensed User
Longtime User
Using code as below I can get a nicely scrambled ID, unique to my set of devices at least. BUT if I have to redo a unit's ROM or do a factory reset on a unit then I get a new number.

Is it possible to change the android_id?

Dim objPhone As Phone
DeviceID = objPhone.GetSettings("android_id")
 

wmardian

Member
Licensed User
Longtime User
Hi all..
does someone finally find how to get the unique id for the android user?

Rgds
 

RomansUP

Member
Licensed User
Longtime User
For examp. using code ref.GetStaticField("android.os.Build", "SERIAL") on Prestigio PAP7600DUO it returns ID:0123456789ABCDEF
But program " Device ID " from PlayMarket returns ID:356EE72D2F934742
How comes?
 

danijel

Active Member
Licensed User
Longtime User
B4X:
If Api < 9 Then
      'Old device
      If File.Exists(File.DirInternal, "__id") Then
         Return File.ReadString(File.DirInternal, "__id")
      Else
         Dim id As Int
         id = Rnd(0x10000000, 0x7FFFFFFF)
         File.WriteString(File.DirInternal, "__id", id)
         Return id
      End If

2^31 is really large number but only 55,000 users is required for matching pair.
There is > 50% chance that 2 of 55,000 users will get the same number.
There is > 90% chance that 2 of 100,000 users will get the same number.
so you will not be able to distinguish them.

Better use much larger number or string with 8 chars. (char from DEC32 to DEC126 = total 95 "visible" chars)
You will get 95^8 combinations and then:
There is < 0.8% chance that 2 of 10,000,000 users will get the same number.

Interesting story about this math "paradox" you can find here:
http://en.wikipedia.org/wiki/Birthday_problem
 
Last edited:

danijel

Active Member
Licensed User
Longtime User
2^31 = 2,147,483,648 / 100,000 = 21,474.83648 - why 90%?
In that calculation you have nothing about possible matching.

You just calculated average distance between 2 neighbor numbers
from sorted list of 100,000 random generated intigers from interval [0, 2,147,483,648]

Lets say person X1 got one of 2,147,483,648 numbers.
Person X2 will get the same number with 1 / 2,147,483,648 chance = 0.0000000004656...
Person X2 will get different number with 2,147,483,647 / 2,147,483,648 chance = 0.9999999995343...

but we did't test all possible matching.
we tested only person X1 with person X2

we must test:

(X1 with X2) AND (X1 with X3) AND (X1 with X4) AND ... AND (X1 with X100,000)
AND
(X2 with X3) AND (X2 with X34 AND (X2 with X5) AND ... AND (X2 with X100,000)
AND
.
.
.
AND
(X99,999 with X100,000)

There is 4,999,950,000 possible matching (Binomial coefficient "100,000 choose 2")

So,
Probability that one pair have different numbers is:
2,147,483,647 / 2,147,483,648 chance = 0.9999999995343

Probability that all 4,999,950,000 pairs have different numbers is:
0.9999999995343^4,999,950,000=0.0974

If we take the complement of that:
Probability that there is at least one pair that have same numbers is:
1 - 0.0974 = 0.9026 = 90.26 % :eek:

Maybe contra intuitive but, like this,
similar "paradox" is that in group of just 23 people
greater chance is that there exist pair of two people that celebrates birthday
on same day than there doesn't exist such pair.
And here is 365 / 23 = 15.87 average days distance between 2 neighbor birthdays

Hope this helps! :)
 
Status
Not open for further replies.
Top