I am getting android device id from this code of snippet which is for my device is "3b3472d8998af818"
protected String getDeviceId() {
return Secure.getString(this.getContentResolver(), Secure.ANDROID_ID);
}
and android device token from this code of snippet which is for my device is APA91bGeA3xOsXocz-eNOklONNVYwHyjvzyVMPQtC54_GX5Npx5fjWjpDbw6XOGqFi-a0lz7gL4BQlZXN-opPyHwJxxo3-1jyqjc1df6y8KwdVj7tUHVObcE3sF0XSpSngUkq6UfCEUTwgmsv-sjGuK863Y4R1kmHA
GCMRegistrar.register(this.context, CommonUtilities.SENDER_ID);
I don't know what is the difference between two ids?
Both are completely different.
Secure.ANDROID_ID
A 64-bit number (as a hex string) that is randomly generated on the
device's first boot and should remain constant for the lifetime of the
device. (The value may change if a factory reset is performed on the
device.)
And GCMRegistrar.register(this.context, CommonUtilities.SENDER_ID); Gives you the registartion id of device from GCM. By which, GCM uniquely identifies the device.
Another difference is Secure.ANDROID_ID may change when factory reset is performed on the device. And Registration id gets changes periodically.
And if you are asking about CommonUtilities.SENDER_ID then This is your project number, and it will be used later on as the GCM sender ID
Related
When app is default dialer I need a way of getting sim id (1 or 2) for incoming call (dual sim).
App is implementing InCallService.
It looks like you can run call.getDetails().getAccountHandle().getId(), which will return a string that is the identifier of that PhoneAccountHandle.
Note that PhoneAccountHandle is also returned from getSimCallManager
Here's the note from the PhoneAccountHandle doc's:
A string that uniquely distinguishes this particular
PhoneAccountHandle from all the others supported by the connection
service that created it.
A connection service must select identifiers that are stable for the
lifetime of their users' relationship with their service, across many
Android devices. For example, a good set of identifiers might be the
email addresses with which with users registered for their accounts
with a particular service. Depending on how a service chooses to
operate, a bad set of identifiers might be an increasing series of
integers (0, 1, 2, ...) that are generated locally on each phone and
could collide with values generated on other phones or after a data
wipe of a given phone. Important: A non-unique identifier could cause
non-deterministic call-log backup/restore behavior.
You can also run getPhoneAccount(phoneAccountHandlerFromAbove) to get the address() i.e. phone number of the account.
If you want to compare it to the order of things in the system, you can retrieve the list of all PhoneAccountHandle's with getCallCapablePhoneAccounts
I need to register user devices on server with an unique identifier that be a constant value and doesn't change in the future.
I can't find a good solution to get unique id from all devices (with/without simcard).
Secure.ANDROID_ID: Secure.ANDROID_ID is not unique and can be null or change on factory reset.
String m_androidId = Secure.getString(getContentResolver(), Secure.ANDROID_ID);
IMEI: IMEI is dependent on the Simcard slot of the device, so it is not possible to get the IMEI for the devices that do not use Simcard.
TelephonyManager tManager = (TelephonyManager)getSystemService(Context.TELEPHONY_SERVICE);
String uuid = tManager.getDeviceId();
WLAN MAC Address: If device doesn’t have wifi hardware then it returns null MAC address. and user can change the device mac address.
WifiManager m_wm = (WifiManager)getSystemService(Context.WIFI_SERVICE);
String m_wlanMacAdd = m_wm.getConnectionInfo().getMacAddress();
Bluetooth Address string:If device hasn’t bluetooth hardware then it returns null.
BluetoothAdapter m_BluetoothAdapter = BluetoothAdapter.getDefaultAdapter();
String m_bluetoothAdd = m_BluetoothAdapter.getAddress();
Instance id: instance_id will change when user uninstalls and reinstalls app. and it's not a constant value.
Do you have any idea to get a unique id from all Android devices (with/without simcard, Bluetooth, ...) that really be unique, cannot be null and doesn't change after uninstall/reinstall app?
I found that Secure.ANDROID_ID is the best choice. This is a 64-bit quantity that is generated and stored when the device first boots. But it resets on device factory reset.
there are some reports that shows some devices has same Secure.ANDROID_ID on all instances.
we can add extra items (like sim serial, GCM instance id or ...) to the Secure.ANDROID_ID and generate new unique fingerprint.
Mutiple users can be setup on Android device and Secure.ANDROID_ID is different for every user on same Android device. So using Secure.ANDROID_ID means single devices will be registered as a different device for each user setup on the device.
Secure.ANDROID_ID is your only friend. However it has some problems (empty results) on older (<2.3) devices. All other ID's do not work on all type of devices.
Please also read Is there a unique Android device ID?
Objective:
I am looking for a way to find out a unique_id for android device.
Background:
I will use the Id in login request payload and as my app is license based service app the Id should not change under normal circumstances.
Existing Approaches:
In iOS there are some unique id solutions for iOS such as CFUUID or identifierForVendor coupled with Keychain,Advertising Identifier etc.. that can do this job upto the expectation.
But in Android all the options that I know seems to have hole in it.
IMEI:
TelephonyManager TelephonyMgr = (TelephonyManager)getSystemService(TELEPHONY_SERVICE);
String m_deviceId = TelephonyMgr.getDeviceId();
Drawbacks
It is sim card dependent so
If there is no sim card then we're doomed
If there is dual sim then we're dommed
Android_ID:
String m_androidId = Secure.getString(getContentResolver(), Secure.ANDROID_ID);
Drawbacks
If OS version is upgraded then it may change
If device is rooted it gets changed
No guarantee that the device_id is unique there are some reports some manufacturers are having duplicate device_id
The WLAN MAC Address
WifiManager m_wm = (WifiManager)getSystemService(Context.WIFI_SERVICE);
String m_wlanMacAdd = m_wm.getConnectionInfo().getMacAddress();
Drawbacks
If there is no wifi hardware then we're doomed
In some new devices If wifi is off then we're doomed.
Bluetooth Address:
BluetoothAdapter m_BluetoothAdapter = BluetoothAdapter.getDefaultAdapter();
String m_bluetoothAdd = m_BluetoothAdapter.getAddress();
Drawbacks:
if there is no bluetooth hardware we're doomed.
In future in some new devices we mightn't able to read it if its off.
Possible solutions:
There are two approaches that I think to solve this problem
We generate a random id by hashing timestamp with unique ids that I have mentioned and store it so next time during login we’ll check if the the stored value of key is null if its so then we’ll generate and store it else we’ll use the value of the key.
If there is something equivalent to keychain of iOS then we’re good with this approach.
Find a global identifier something like advertisingIdentifier of iOS which is same for all the apps in the device.
Any help is appreciated !
I have chosen to use Android_ID since It's not dependent on any hardware.
Build.SERIAL also dependent on availability of telephony that is in wifi only devices this Build.SERIAL won't work.
I have explained how other approaches are dependent upon the hardware availability in the question itself.
There is no such ID available on Android. You can generate your own, for example a random UUID and connect it to the user's account. This is what Kindle, Audible and other applications do to identify devices in a non-privacy-intrusive way.
Consider Google Analytics Mobile if you want to "track your users", http://www.google.com/analytics/mobile/
If you want to get closer to tracking a device you can combine the IDs above together in a hash-function. Bluetooth + wifi + android serial, and if any of them are null, you put a 0 in the hash, e.g. if there is no wifi mac addr. As you point out, you aren't guaranteed the id won't change. Unless the user is running a custom ROM, I would expect this computed ID to stay constant, though.
I think, you could use device serial ID (hardware serial number, not android id). You could seen it in device settings. In your code, you could get it by Build.SERIAL.
I know, that android.Build.SERIAL is generated at first device boot, but I can't locate where and when exactly. I'm building AOSP Jelly Bean, Android tablet, nosdcard.
2nd question: is this serial number really unique for all Android devices?
According to this thread, it clearly says that it's unique, but added since API 9 and may be not present on all devices.
If you're writing your app for a specific device's model, you could direclty check if it has an IMEI. Otherwise, as you said, I recommend you to write a custom ID generator module. You will be sure that your ID will be unique and available for all devices.
IMEI represents the serial number of the device. It's sure it's unique. Two different devices can't have the same serial number.
To get the serial number of the device you just have to call :
String serial = Build.SERIAL;
It exists another approach. You can get the id by calling Secure.ANDROID_ID.
A 64-bit number (as a hex string) that is randomly generated on the
device's first boot and should remain constant for the lifetime of the
device. (The value may change if a factory reset is performed on the
device.)
private final String ANDROID_ID = Secure.getString(getContext().getContentResolver(),
Secure.ANDROID_ID);
Take care because it says that the value MAY change if a factory reset is performed.
I am trying to use GCM and everything is working fine except for the GCMRegistrar.getRegistrationId call on difference devices. I've run this code on an emulator and 2 different phones and GCMRegistrar.getRegistrationId always returns the same string. I expected it to differ on each device but it does not. Am I doing something wrong? Here's the code I'm using (taken from the docs).
GCMRegistrar.checkDevice(context);
final String regId = GCMRegistrar.getRegistrationId(context);
if (regId.equals("")) {
GCMRegistrar.register(activity, "123456789012"); //sender id/api project id
} else {
LogUtil.info("Already registered");
}
When I first ran this on the emulator GCMRegistrar.getRegistrationId returned "" but on subsequent calls it returns the big id. That makes sense. The strange thing was that when running the same code on the 2 phones, they both returned that same id (the one the emulator returned), having never run this app before.
From what I know, the registration ID is used to match a user+device. On emulators, you don't have any user account, and the device is virtual so my guess is that the registration thinks both virtual devices are the same.
I don't know what they use to create the registration ID, but if they use the ANDROID_ID, it's a known problem that all virtual devices have the same ID.
Also it's a known problem that some manufacturers use the same device ID for all their devices although it is supposed to be unique. But maybe they are using something else. Maybe you should try to ask GCM support for this particular issue.
This actually turned out to be a mistake on my part on how I was checking the id's. XGouchet, thanks for your response though.