I have the need to detect a common factor between two apps, one written in Xamarin and one written in Java (Android Studio), running on a users phone.
In the good old days the IMEI did the job nicely. However now I am having to use the Device ID, which is fine for the current purpose, but not perfect.
Anyway, using the following statement in Xamarin gives one result, while using the statement that follows this in Android, gives a different result, both on the same phone.
Why would this be, why is the Device ID not reported as the same value, and is there a way to identify the DeviceID via both platforms that result in the same output ?
Thanks
Xamarin code - Result is "a70c996e74002942"
var Device_ID = Android.Provider.Settings.Secure.GetString(ContentResolver, Android.Provider.Settings.Secure.AndroidId);
Android Studio code - Result is "702669b2e9a6f7d1"
String Device_ID = Settings.Secure.getString(context.getContentResolver(), Settings.Secure.ANDROID_ID);
From the docs
unique to each combination of app-signing key, user, and device
For privacy reasons, two different apps on the same device will have different ids
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 am trying to make an app which allows only single account per device. Now what I am trying to know is a property of a phone which never changes. At first I thought I could save MAC address of a device in my database but I read in one of the question on SO that know in android when we try to access MAC address programatically we get a constant that is same for every device.
I would like to know what never changing property of an android device can I access programatically.
Also in future I would like to develop that app for iOS, is there same non changing property of iOS phone that I can access programatically ?
Thank you.
For this purpose, you have to differentiate between devices.
For Android, you can use Device ID
For IOS, You can use vendor ID link.
For IOS : When your app deleted and reinstalled then vendor ID changes so it is better to store your vendor id in keychain using below code.
-(NSString *)getUniqueDeviceIdentifier
{
NSString *yourAppName=[[[NSBundle mainBundle] infoDictionary] objectForKey:(NSString*)kCFBundleNameKey];
NSString *applicationUUIDStr = [SSKeychain passwordForService:appName account:#“Your_App_Name”];
if (applicationUUIDStr == nil)
{
applicationUUIDStr = [[[UIDevice currentDevice] identifierForVendor] UUIDString];
[SSKeychain setPassword:strApplicationUUID forService:appName account:#"Your_App_Name"];
}
return applicationUUIDStr;
}
Im pretty sure these days you can use mac addresses, however if not have you tried IMEI, i have no idea how this would be done.
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 working on an APP using Xamarin MonoTouch, this App requires custom licence key as provided by us. To identify each and every installation we have to store some kind of device information to control misuse of App.
After trying various ways, now the problems are:
Device Id or Android id : gets changed every time a device is factory reset or format.
Settings.System.GetString(this.ContentResolver, Settings.Secure.AndroidId);
IMEI Number: No SIM Tabs dont have. Double SIM phones have no fix slot wise imei and sends randomly chose one.
var telephonyManager = (TelephonyManager)GetSystemService(TelephonyService);
string imei = telephonyManager.DeviceId;
WIFI Mac Address: Good way but some sets like HTC and Chinese ones throwing exception while retrieving mac address, but works some time. SO not getting fix id everytime app starts.
WifiManager wm = (WifiManager)GetSystemService(WifiService);
string macid = wm.ConnectionInfo.MacAddress;
So everytime any of the above ID fails, user needs to re register app again and again. Do we have any fool proof way of doing this?
Ok, as per comment by Matt, since there is not fool-proof method of getting unique id from an android device. So I have made a provision of validating installations against WIFI Mac ID and Android ID both. If any one of these found matched then installation is genuine or spoofed.
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