I'm developing an android app which contains registration form also,
Here I want to make user can register only once in the device. and if register again (by clearing data or reinstall) with different mobile number and email id, app should give error message.
I think you need to check IMEI number of device
IMEI number will not be changed if sim card changed.
This alone cannot be achieved on mobile device itself. You also need to maintain server which keep the identity of device and user mobile number together. device identity can be combination of IMEI and device id
When you try to register, you do all local validation on client but ultimately 1 network call is must to register, for this send device_id and newly registered number.
Next time when some user tries to register with new number from same device, u'd already have this information on server, server can respond back telling, hey looks like this mobile device is already associated with an number do you wish to use the previous number instead.
In case, user denies, he must be allowed to delete the old relation between oldnumber-current device.
There after he can proceed with the way initially he started to register.
Also this is completely business requirement, whether u want to have 1device-> #numbers or #numbers -> 1device. But i would rather suggest to keep it safe simple and secure with 1device->1number.
For Android Version 6 And Above, WLAN MAC Address has been deprecated.
For uniquely Identification of devices, You can Use Secure.ANDROID_ID.
And we don't need any additional permission to retrieve Android ID.
you can get Android Id like:
public String getDeviceUniqueID(Activity activity){
String device_unique_id = Secure.getString(activity.getContentResolver(),
Secure.ANDROID_ID);
return device_unique_id;
}
You can do this by below approach.
On sign up, get user device IMEI number as well and store on server database as well.(In this step make sure that user that IMEI number does not exist)
Related
I am making an app where the user has to register their device first and I can block user if they use device that are not registered, and therefore I need some unique ID from their device. I used device_info_plus and unique_identifier packages and got some unique information from the device. The problem is the user have no way of obtaining the information needed for registration like the one gotten from unique_identifier(ANDROID_ID).
Is there a way to obtain hardware serial number programmatically? Because that seems to be the only one usable for this case, or is there any other unique ID to identify a device that is obtainable both from user and programmatically?
You can use the package uuid.
Than call this method to obtain an unique id based on the device (it does not contain device's hardware data but:
String uuid = const Uuid().v1();
Imagine an application that consists of loads of clients and one server. The clients should be able to use the application without the need to register a username for e.g. (Therefore getting the feeling of anonymously using the app)
What unique data in a smartphone could be use to identify "anonymous" users and seperate them uniquely, so that each user would have its own personal data.
Could one use the IMEI id?
Is this possible?
At I/O 15 Google announced the 'instance ID' which uniquely identifies an app installation, and can be used for a veriety of other purposes as well.
I give more detail in an answer to an existing, similar question here:
https://stackoverflow.com/a/30948111/150016
Yes You can use the IMEI, but then you need a permission...or you could give every User a Unique ID on the server side
I think a long type variable is enough so the first one that connects you give him the ID 1 the app gets the ID and so on and so forth
You can use a built in feature here:
import android.provider.Settings.Secure;
private String uniqueIdentifier = Secure.getString(getContext().getContentResolver(),
Secure.ANDROID_ID);
where Secure.ANDROID_ID is presented as "A 64-bit number (as a hex string) that is randomly generated when the user first sets up the device and should remain constant for the lifetime of the user's device."
This is exactly the use case for the new Instance ID: getting a unique ID that you can use to identify even a not logged in user to your server.
This works on both phones and tablets (something IMEI does not) and avoid issues with ANDROID_ID (such as a few manufacturers always using the same ANDROID_ID on all devices).
You don't want to use the IMEI, as it will only apply to devices that have cell phones in them. There are plenty of wifi only devices out there in the wild.
Also, to get the IMEI, you need to ask for extra permission in your manifest.
<uses-permission android:name="android.permission.READ_PHONE_STATE" />
You'd be better off either generating your own random GUID and storing it in your app's SQLite database, or use the Android ID field.
Android ID will give you extra benefits like providing a different identifier for different user profiles within a device.
Another answer here mentioned using Instance ID, but the big caveat there is it requires Google Play Services, so your app wouldn't work on AOSP / forked devices (i.e. Amazon's tablets). I'd have just inserted this as a comment to that answer, but my rep won't let me comment yet.
I see that most of the applications (SnapChat, WhhatsApp) do the phone number verification through a OTP/verification code.
I was just wondering why not avoid this if public String getLine1Number () gives you a valid phone number and only do verfication code based auth if the above method returns null or empty string.
I don't know how reliable is this way of doing things. Any advice is much appreciated.
Thanks
Somebody could implement a fake client and can then send whatever he likes. The server should never trust information it gets sent from the client.
No it isn't advised to do so. Phone numbers are not available in SIM for all operators, for eg in INDIA Tata teleservices you can not retrieve this number. However in some countries the operators have stored phone numbers on SIM, and we can get those.
However if present it can be used to prepopulate on the Edittext and let user change it and only later SMS should be sent, if user accepts.
Most mobile operators does not store MSISDN(phone number) in the SIM.
Even if getLine1Number() returns a String, the String might not be reliable. (due to porting/MSISDN change etc.)
Programmatically obtain the phone number of the Android phone
It will be best to ask the user for the MSISDN for verification SMS.
Alternatively, you can consider to use other identifier.
Is there a unique Android device ID?
Yes, and in fact not all android devices + SIM card combinations will pour the phone number in that method. Plus, what happens if someone is using a Dual SIM card, or attempting to use their personal phone number on their second phone? You should rely on the user input when it comes to the phone number they want to be identified with.
In one of my App, I would like to give a feature as a trial for only 20 attempts. Once the user wants to access the feature for the 21st attempt, he/she will be prompted for in-App purchase.
My question is how can I make this variable persistent so that even if the user uninstalls the app and re-installs, the counter does not reset and takes the last value before the uninstall.
Please help.
The easiest way is to use Backup API and backup your data online. It is very easy to use and here is tutorial:
http://developer.android.com/training/cloudsync/backupapi.html
The disadvantage of this method is that user can disable backups in phone's settings.
Another method requires you to send data to server. I would suggest to use parse.com since it does not require you to write any server code, they have very easy-to-use library for Android and their free plan is very generous. Here is a little tutorial:
https://parse.com/tutorials/get-started-with-android
You can send some sort of unique id (device or account specific) and counter to the cloud every time user triggers your trial feature. Also you can query your counter from the cloud when application launches the first time.
To create that unique id you can approach with few methods:
Try to obtain 64-bit unique number, which is generated when device first boots:
String androidID = Secure.getString(getContext().getContentResolver(), Secure.ANDROID_ID);
Note that it was reported that for some device this value might be null. You can verify your androidID variable and if it is null, you can try another method that will allow you to access user's primary e-mail (you probably want to hash it prior to sending it your server).
Also make sure to add android.permission.GET_ACCOUNTS permissions to your manifest file:
final Account[] accounts = AccountManager.get(context).getAccounts();
for (final Account account : accounts) {
if (Patterns.EMAIL_ADDRESS.matcher(account.name).matches()) {
final String email = account.name;
// hash email and use it
}
}
if email cannot be obtained - you might also want to try to get device id from telephony manager:
// For CDMA phone getDeviceId() is equal to value request for Secure.ANDROID_ID
final TelephonyManager telMgr = (TelephonyManager)getBaseContext().getSystemService(Context.TELEPHONY_SERVICE);
final String deviceId = telMgr.getDeviceId();
(don't forget to add android.permission.READ_PHONE_STATE permission to your manifest)
Hope that it gave you enough information to add trial functionality into your code.
Also if your in-app purchase is actually a subscription, then Google already implemented trial functionality for you:
http://developer.android.com/google/play/billing/billing_subscriptions.html
(search for free trial)
You have no way of maintaining anything locally for the user if they uninstall or reinstall the application.
If you need the uninstall/re-install requirement, this is counter that will need to be logged on your back-end rather than on the device. You can do this by storing the device's id on your server and incrementing your ticker when appropriate.
I simply define a serializable Expiration object that I store to SD with a dot in front of it to make it hidden.
The object contains time of creation and other metadata.
When the app starts, it checks whether Expiration exists, if not it is create. This way I always know the exact time when the app was installed, despite uninstall/reinstalls.
The downside to this method is that it requires some sort of external storage as we want to go outside of the standard app folder of the internal storage, which is wiped upon uninstall.
To circumvent this, you could look for some way of getting/giving a device a unique id, that remains the same after reinstall, and upload the data to a server. This has the benefit that the user cannot reset the expiration by wiping the SD either.
Following scenario:
I want to create an wifi hotspot on a public place (e.g. train station). Therefore i want to write an mobile application (iOS and/or Android) which works as a portal page. As I would be providing internet access via my wifi hotspot I need to make sure that people who want to log in verify their identity properly (responsibility). First I thought i could do something like a facebook login but I guess that would not be enough as people can create fake accounts.
Then I got the idea that I could maybe access their telephone number via their smartphones.
I googled alot and came to the conclusion that it is pretty tough on both platforms.
The iOS method seems to be deprecated and apps wont make it to the app store with that version. Android can read the phone number from the sim card, but not all providers store the number on the sim card.
Question
Is there any possibility to get the phone number? Or is there any other way to uniquely identify a person in a wifi network?
Of course I dont want to do any of that without asking for users permission etc...
Greetings and thanks in advance
Peter
Choosing the MAC address is a good choice, it is not the safest, but it is the more easy to do.
The IMEI is not always provided, and the SERIAL is not uniq.
But actually, I don't know how to do this with iOS.
What is about the MAC address of the phone? This should be unique enough and you can get is easily from android and from iOS.
Android: http://developer.android.com/reference/android/net/wifi/WifiInfo.html#getMacAddress%28%29
iOS: How can I programmatically get the MAC address of an iphone
Using IMEI number
Android Does provide functions/method to access device IMEI number
First Set <uses-permission android:name="android.permission.READ_PHONE_STATE" />
in android manifest
TelephonyManager tm = (TelephonyManager) getSystemService(Context.TELEPHONY_SERVICE);
// get IMEI
String imei = tm.getDeviceId();
Hope it helps
For NON CDMA or GSM devices like Tablet
Use
import android.provider.Settings.Secure;
private String android_id = Secure.getString(getContext().getContentResolver(),
Secure.ANDROID_ID);
This would generate a unique code for the device..how ever it would change on when user reset the device ie factory reset it .. and it works for device having os > 2.2(froyo)
This really depends on who you are trying to identify. That may seem like an odd response, but usually, we are trying to identify two, not one, sets of credential elements.
First, we want ot identify the device itself -- is this the deivce we expect to see and can we trust that this device has not been tampered with. Second, we usually want to know if the user of this device at the moment is one we expect to be using this, now validated, device. (If I take your phone, without step #2, I just became you.)
This is why we have things like 802.1x. It lets me validate the user of a network, not just the device. For your case, consider something like:
For device validation, the combination of hte MAC address and the IMEI. TUrn those into a unique hash with some data from the user. For example.
ID = SHA1(IMEI+MAC(Wifi)+user password)
Now that we're pretty sure the device and user are correct, if you need to, you can go one step further and use that hash a key to encrypt a user validation step in your app. Even if the user is correct, if they're on the wrong device, their key won't decrypt.