According to the google documents about ANDROID_ID, its value is unique until factory reset has done. I have a question about new generated ANDROID_ID after factory reset .
Is this value unique as old value? Is it possible that the new value is not unique?
According to this:
However, the value may change if a factory reset is performed on the device. There is also a known bug with a popular handset from a manufacturer where every instance have the same ANDROID_ID. Clearly, the solution is not 100% reliable.
Related
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 would like to use a unique id for android device that works for phone and Tablet.
(IMEI doesn't work with no SIM card device and sometime MAC Address return null)
I'm not sure is android.os.Build.SERIAL unique or not.
Does anyone know about this?
Thanks,
Regards.
Yes, but note that it was only added in API level 9, and it may not be present on all devices. To get a unique ID on earlier platforms, you'll need to read something like the MAC address or IMEI.
Generally, try reading all the possible IDs, and use whichever are available. See this article for guidance.
You can use Build serial and android ID to make your own unique id.
String serial = Build.SERIAL;
String android_id =Secure.getString(context.getContentResolver(),
Secure.ANDROID_ID);
String myKey=serial +android_id ;
Serial was only exposed in API:9. but you can get it in older versions using reflection. However the docs mention "if available" so I guess don't rely on it.
String deviceSerial = (String) Build.class.getField("SERIAL").get(
null);
I think for unique Id you should used android Id.
following is code to get Android Id.
String android_id = Secure.getString(this.getContentResolver(),
Secure.ANDROID_ID);
Log.d("Android","Android ID : "+android_id);
If it is there, then it is expected to be unique. But there is no guarantee that this property is set. Also it is API 9. Unfortunately there's no easy way to uniquely identify the device. Some properties like said SERIAL can be present, others like ANDROID_ID as NOT unique, some other like MAC depends on presence of WIFI or its state (if wifi module is off, the you may not be able to read its MAC). Some like IMEI cannot be read even device got phone module. So the best approach is to gather as much data as you can, and try to build something you could most likely consider unique device ID
What about a combination of MAC, IMEI and SERIAL ?
You just have to deal with the fact that they all could be non existant esp. on older phones without SIM.
I just find it odd that MAC would return null. This should not be possible imho, as it makes no sense that a mobile device has no MAC.
There are 2 MAC addresses possible but they can be non accessible in some cases.
Right now my algorithm based only on IMEI. And here is the problem: some devices doesn't have radio module, so they also doesn't have IMEI
I need unique parameters ( CPU ID, flash ID, MAC etc) to generate ID without using IMEI.
And how to get them with Java. Preferably without Root
Thank you
Use Build.SERIAL to get the unique serial number of an android device. This will return a string value. In emulator this code may return the string "unknown". But try it with a device. It really works... :)
String id=Build.SERIAL;
ANDROID_ID
More specifically, Settings.Secure.ANDROID_ID. This is a 64-bit quantity that is generated and stored when the device first boots. It is reset when the device is wiped.
ANDROID_ID seems a good choice for a unique device identifier. There are downsides: First, it is not 100% reliable on releases of Android prior to 2.2 (“Froyo”). Also, there has been at least one widely-observed bug in a popular handset from a major manufacturer, where every instance has the same ANDROID_ID.
This could help you
You may use android.os.Build.getSerial() instead of android.os.Build.SERIAL
android.os.Build.SERIAL --> This field was deprecated in API level O. Use getSerial() instead.
Source:
https://developer.android.com/reference/android/os/Build.html
You can use the Setting.secure which is inbuilt to get the device id. this device ID is fixed till you reset the factory setting.
Settings.Secure.getString(getContentResolver(),Settings.Secure.ANDROID_ID);
This is the unique Id of your device which is stable till you reset to the factory setting.
below code can help you to get your device id
String ts = Context.TELEPHONY_SERVICE;
TelephonyManager mTelephonyMgr = (TelephonyManager) getSystemService(ts);
String imsi = mTelephonyMgr.getSubscriberId();
String imei = mTelephonyMgr.getDeviceId();
I'm trying (wondering if it's even possible) to write an app, that would change the network selection mode automatically, based on some criteria. E.g. change the network operator from Vodafone to T-Mobile (assuming that the SIM card registration will succeed, but I'm not worried about it atm)
Unfortunately, I can't seem to find any way in the API to do it. Anyone has any idea?
I assume, since it's not in the public APIs, there might still be a way to do it, if the phone is rooted. Is that true? If so, where should I look?
Thanks in advance
Sorry but you can't.
You can have a look into the TelephonyManager .
You can know the current operator: getSimOperator(Name) / getNetworkOperator(Name).
You can also check this thread saying "I learn that for the sake of security there aren't any public APIs to manage this so the only option is to send the user to the system PreferenceScreen within my app."
How about using android.telephony.CarrierConfigManager? I read about it on https://developer.android.com/reference/android/telephony/CarrierConfigManager.html and it seems to allow you to change alot of carrier-specific parameters, although the app must be signed with the certificate that has a matching signature to one on the SIM, so it can usually only be implemented by the carrier issuing the SIM. See also https://source.android.com/devices/tech/config/carrier.
I havent found an actual method to actively switch carrier, but if anywhere, I'd expect it to be there.