This question already has answers here:
Is there a unique Android device ID?
(54 answers)
Closed 7 years ago.
I would like to be able to generate unique serial numbers for each Android device for use in unlocking an application. How could I do this?
EDIT:
The reason is I want to revamp a paid application and provide users who have paid for the old version, which will have a different package name, a way to obtain the full version by downloading an unlockable free version of the application. I would push an update to the old version that would generate and display the code that they could enter to turn the Free version into a fully functional version.
You can use the Android id. This id should be unique to devices, but how it is set depends on the implementation of the device manufacturer.
String deviceId = Secure.getString(context.getContentResolver(),Secure.ANDROID_ID);
The Android Id may change on factory reset of the phone and the user is also able to change it on rooted phones. But if you need an id to identify your user it should be fine.
why not using ther google account name? is easy to get and needs only a simple request on the manifest file. they will have purchased the license with gplay, so the g+ account name should be enough...
in the manifest:
<manifest ... >
<uses-permission android:name="android.permission.GET_ACCOUNTS" />
...
</manifest>
to retrieve the account name:
AccountManager am = AccountManager.get(this); // "this" references the current Context
Account[] accounts = am.getAccountsByType("com.google");
to retrieve the name:
accounts[0].name
i write a simple alert to make me sure i have found an account here the whole code:
Account[] accounts = am.getAccountsByType("com.google");
AlertDialog.Builder miaAlert = new AlertDialog.Builder(this);
miaAlert.setTitle("i found an account name!");
miaAlert.setMessage(accounts[0].name);
AlertDialog alert = miaAlert.create();
alert.show();
Android already provides a licensing service for use by paid apps. Is there a reason you don't want to use this? Bear in mind that trying to lock your app to a particular phone is going to really annoy users who switch devices (Eg, all of them, sooner or later).
From Google Developer's solution in solving issue with PRNG, getting unique device serial number via reflection:
http://android-developers.blogspot.com/2013/08/some-securerandom-thoughts.html
/**
* Gets the hardware serial number of this device.
*
* #return serial number or {#code null} if not available.
*/
private static String getDeviceSerialNumber() {
// We're using the Reflection API because Build.SERIAL is only available
// since API Level 9 (Gingerbread, Android 2.3).
try {
return (String) Build.class.getField("SERIAL").get(null);
} catch (Exception ignored) {
return null;
}
}
You can use Serial Number as a unique Identifier as they are availbalble in all devices.You should not use IMEI as a unique identifier as they are not abalibale in WIFI Tabs(tabs that do not have SIM Card Slot).
You can use
try {
Class<?> c = Class.forName("android.os.SystemProperties");
Method get = c.getMethod("get", String.class, String.class);
serial = (String) get.invoke(c, "ril.serialnumber", "unknown");
} catch (Exception ignored) {
}
You can use the IMEI no for this.
Related
Before Android 10, I was using the TelephonyManager API to retrieve that info, but it's no longer working in Android 10.
I'm facing the same problem, but, in my case, I have a kind of "backup" code that returns a UUID.
Here is a code that you could use:
String uniqueID = UUID.randomUUID().toString();
This code is usefull if you want a "instalation unique identifier" but, doesn't works as a device unique identifier because if the user unistall and re install your app, the UUID returned will be different than the last one.
In my case, I use the UUID.nameUUIDFromBytes to generated a UUID by a given "name" and I'm using the Settings.Secure.ANDROID_ID as the "name" for the UUID. Using this method you "grantee" the returned UUID will be the same, UNLESS the user do a factory reset.
Here is the code:
String androidId = Settings.Secure.getString(context.getContentResolver(),
Settings.Secure.ANDROID_ID);
UUID androidId_UUID = UUID
.nameUUIDFromBytes(androidId.getBytes("utf8"));
String unique_id = androidId_UUID.toString();
Until here, everything seens ok, but the problem is: since Android 10 was released, Google doesn't recommend the uses of any kind of "hardware indentifier" and this includes the Settings.Secure.ANDROID_ID. This actually is my concern, because in the company that I work for, we use the IMEI or this UUID to identify our customers users and define if an user is trying to log in more than one device, which is not allowed by our rules, and to build some statics. If the UUID isn't unique for the same device we'll have to review all of our user access control.
Here is the Android Developers link about unique identifiers good pratices.
https://developer.android.com/training/articles/user-data-ids
And here is the same link, but with an anchor where Google describes some use cases and the best option of unique identifier for each one.
https://developer.android.com/training/articles/user-data-ids#common-use-cases
None of use cases fit with mine, so I'm still loking for a better solution.
I hope this could help someone.
From the Android Developers Documentation Website
Starting in Android 10, apps must have the READ_PRIVILEGED_PHONE_STATE privileged permission in order to access the device's non-resettable identifiers, which include both IMEI and serial number.
Third-party apps installed from the Google Play Store cannot declare privileged permissions.
If your app doesn't have the permission and you try asking for information about non-resettable identifiers anyway, the platform's response varies based on target SDK version:
If your app targets Android 10 or higher, a SecurityException occurs.
If your app targets Android 9 (API level 28) or lower, the method returns null or placeholder data if the app has the READ_PHONE_STATE permission. Otherwise, a SecurityException occurs.
If you try to access it, it throws the below exception:
java.lang.SecurityException: getImeiForSlot: The user 10180 does not meet the requirements to access device identifiers.
I'm currently planning on creating an app. Unfortunately the need for usercreation is there. I know users don't like goind through a registration process with opt in by email activation link click.
So I thought maybe using the apple/google id as a replacement for email address would be cool since the verification step by email can be dropped. In addition when the user changes his or her mail address that's no problem since his or her id doesn't change in this case.
I'm not really into this particular topic so I have some questions, any help is highly appreciated:
Is there any numeric/alphanumeric id anyway or is the google/apple id (i.e. the "username") the email address itself?
Is this possible in Android and Apple SDK (and Cordova in addition since I use this one)?
Is this a good idea in general or am I missing something?
Thanks in advance!
You could use the below DeviceIDs solutions as primary key for your users registrations. Look:
1 - Android
1.1 - Android Phones (With SIM chip) - For Android I use the Cordova SIM plugin. It generates uniqueIDs for devices based on SIM chip informations. So, you can manipulate your data based on the plugins return;
Link: https://github.com/pbakondy/cordova-plugin-sim
1.2 - Adroid Tablets - The plugin above is fantastic, but it does not work for devices that does not have any SIM chip. In this case, I use the following code:
if(mContext == null){
mContext = this.cordova.getActivity();
if(dialog == null){
dialog = new ProgressDialog(mContext);
}
}
String tabletID = Secure.getString(mContext.getContentResolver(), Secure.ANDROID_ID);
Conclusion: If you are developing only for phones (App projected for Mobile Phone) you should use the plugin. If your App targets Tablets or devices without SIM card, than you can take a look at the other solution. The IDs generated are "Devices ID", unique for each device.
2 - iOS
For iOS, I use the following code to generate an unique ID for each device:
NSString *uniqueIdentifier = [[[UIDevice currentDevice] identifierForVendor] UUIDString];
The only problem: When user uninstalls all Apps of your iTunes vendor ID from the device and installs any of them again, the ID will be changed. Other easy ways to get Unique ID for iOS is deprecated since version 7.0 of the system.
See more here: Device Id from an iphone app
I am developing a android application for a exploratory project using client server architecture. I thought of using UDID but now its replaced by new "Advertising ID", but in my application, i need to store data about user on server with some unique ID per device.
so what should i use as alternative to UDID?
i checked open UDID but that is also outdated now.
Using "advertising ID" imposes problem of consistency when user clears/resets his advertising ID.
Request the community to help me out.
There is also identifierForVendor see more in apple docs
I don't have much idea about Android :
But Check these :
GeneratingDeviceSpecificSerialNo && HEre
In IOS :
-identifierForVendor
ID that is identical between apps from the same developer.
Erased with removal of the last app for that Team ID.
Backed up.
For more Info Here
You can register the device with the Google Cloud Messaging platform.
When you register the device correctly this gives you back a register id that´s unique for every device.
http://developer.android.com/google/gcm/client.html
UPDATE
You can also, if you haven't tried it out yet, to user the telephony manager to get the device identifier.
TelephonyManager tManager = (TelephonyManager)getSystemService(Context.TELEPHONY_SERVICE);
String uuid = tManager.getDeviceId();
On iOS you can try this
NSString *UUID = [[NSUUID UUID] UUIDString];
This will give you a unique id per app.
I am making some application that will be largely user driven and of course that means their will be trouble makers who probably will enter fake data into it using swear words or worse change valid data to bad data(ie changing to swear words)
Of course measures will be taken to try to curb this but in the end of the day I want to have the option to ban someone from my application.
My first thought is ban their account by email address. I was also thinking that maybe on top of that ban their devices.
My questions is is what unique id can I use from their phone if they use
Andriod
Iphone
Blackberry
Windows Phone 7/8
and how unique is it? Can it be easily changed?
For Windows Phone you should be able to use DeviceExtendedProperties. Specifically the DeviceUniqueId property.
Be aware though that, as they say in that article, if you use a device id to ban a user, then any future user of that same device will be banned from your app, even if they've done nothing wrong.
There are 2 identifiers that can be used together to identify a specific device and user.
The DeviceUniqueId and WindowsLiveAnonymousId
the first one is the device, and as noted, anyone who uses the device after the banned user will also be banned.
The WindowsLiveAnonymousId is unique to the user. I have seen this same identifier across 3 separate devices and it is always the same for the users LiveId.
I use the following 2 methods to get these ids for identifying game players for leader-boards:
//Note: to get a result requires ID_CAP_IDENTITY_DEVICE
// to be added to the capabilities of the WMAppManifest
// this will then warn users in marketplace
public static byte[] GetDeviceUniqueId()
{
byte[] result = null;
object uniqueId;
if (DeviceExtendedProperties.TryGetValue("DeviceUniqueId", out uniqueId))
result = (byte[])uniqueId;
return result;
}
// NOTE: to get a result requires ID_CAP_IDENTITY_USER
// to be added to the capabilities of the WMAppManifest
// this will then warn users in marketplace
public static string GetWindowsLiveAnonymousId()
{
string result = String.Empty;
object anid;
if (UserExtendedProperties.TryGetValue("ANID", out anid))
{
if (anid != null && anid.ToString().Length >= (AnidLength + AnidOffset))
{
result = anid.ToString().Substring(AnidOffset, AnidLength);
}
}
return result;
}
They are used as such:
string deviceUniqueId = String.Empty;
for (int i = 0; i < GetDeviceUniqueId().GetLength(0); i++)
{
deviceUniqueId += GetDeviceUniqueId().GetValue(i);
}
DeviceUniqueIDTextBlock.Text = deviceUniqueId;
WindowsLiveAnonymousIDTextBlock.Text = GetWindowsLiveAnonymousId().ToString(CultureInfo.InvariantCulture);
I did a post last May about getting system info on WP7. This code is found here: http://www.adambenoit.com/applications/system-info-windows-phone/
Hope this helps.
All these devices have network interfaces with unique MAC addresses which by definition are constant - the MAC address is burned into the hardware and cannot be [easily] spoofed, especially on a mobile device. I would hash the MAC address and use that as the key. Pretty common practice on iOS once apple banned the use of UDIDs.
I would use the guid method. Though this can be circumvented by uninstalling and re-installing the app. Nothings perfect though
How to create a GUID/UUID using the iPhone SDK
How to get GUID in android?
How to create a GUID on Windows Phone
http://msdn.microsoft.com/en-us/library/system.guid.newguid(v=vs.95).aspx
How to create a GUID on Blackberry http://supportforums.blackberry.com/t5/Java-Development/how-to-generate-GUID/td-p/289947
I want to make an application which has to be very secured. So f I install an apk in a phone it should only work in that phone. When apk is shared it should not work.Can any one help me in implementing this.
One idea from my side is using an algorithm to generate password using device mac address and so the password won't work for two different devices to log in.Is there any way to get the MAC address( or something unique to device) in android from java? .Expecting alternate solutions!!
If you are distributing the app through Google play store, you can make use of the Google Play Application licensing.
You may read Identifying App Installations on Android Developer's Blog for a discussion about how to uniquely identify a device.
I implemented with IMEI number. So my apk is designed based on IMEI number.So it will check whether IMEI given matches with the device IMEI then only it will launch the new Activity, else it will exit.
TextView tx = (TextView) findViewById(R.id.tx);
String ts = Context.TELEPHONY_SERVICE;
TelephonyManager mTelephonyMgr = (TelephonyManager) getSystemService(ts);
String imei = mTelephonyMgr.getDeviceId();
if (imei.equals("<what we given inthe source>")) {
// Launch the activity
} else {
// show an alert dialog and exit
}