I am using LibGDX and for the Android version of my game I use the "Get Accounts" permission to identify a user by their Gmail address.
Is their a similar way to identify a user for iOS?
According to the App Store Guidelines, you shouldn't get user's personal data without obtaining the user's prior permission. The only identifier you can use anonymously is identifierForVendor:
UIDevice.currentDevice().identifierForVendor?.UUIDString
This identifier is common for all your apps on the user's device. If all the apps were deleted from the device, the identifier may change. More.
Your best bet is to use GameCenter on iOS for identifying the players. This link provides a little more info on handling users with GameCenter.
According to Apple, you shouldn't identify your users, unless you have a good reason to do so.
Like #Marat said, what you are looking for is the UUID,
but keep in mind that this value may change (for example, if the user delete your app and have none of your other apps).
A possible solution would be to keep the UUID value in the keychain, and that way you will always use the same value.
Edit:
Since your app is a game, you can use Apple's GameCenter.
This will identify the users for you.
Related
I would like to use the built-in Fingerprint scanner on Android devices, or most Android devices, to scan the actual fingerprint image or data into my Android app, then send the fingerprint image or data to an API over the internet backed by a database of fingerprints, to see if a given fingerprint (given on any or most Android devices that have fingerprint scanners) matches someone in the database and returns their name (most basic description of my app that focuses on my main question).
Now, I know how to do the API part over the internet with many different programming languages, I'd probably use NodeJS or Elixir for that part, and I know how to do the algorithm to compare a given fingerprint against a database of fingerprints.
The problem I have is that by default and as per guidelines, the Android operating system and Android devices specifically prohibit accessing the internal fingerprint data, and only allow you to authenticate a single or a few users WITHIN a phone and NOT against an outside database with possibly thousands of users and fingerprints or more, and with the given fingerprint to be checked never having been used on a given Android device before, but simply stored in a database or uploaded from a different Android device to that database (served up as an API over the internet).
Also, getting an Android app to communicate with an API with a database backend is trivial. I don't want to address that either, and I don't want any answers to address that.
Specifically, I'm after a hackish way to get at the underlying fingerprint data/scan/image that the hardware produces, or some fingerprint data that is identifiable to an individual, to send to an API database backend over the internet, and let that backend compare the fingerprint data/scan/image sent to it with the database (and I know how to do the comparison part and all that). However, Google guidelines prohibit accessing the underlying fingerprint data in this way that I need for my App.
Solutions
One proposed solution is to issue every user of my app a USB hardware dongle that fingerprint scans, and use the custom API for this hardware. However, my app's use-case scenario involves random people with random Android phones (that already have built-in fingerprint scanning hardware), potentially thousands of people, and they will have little incentive to buy a USB hardware dongle that fingerprint scans, but if I could make it work, they would surely use my app with their built in Android phone fingerprint scanner.
Another proposed solution is to take an actual picture of a person's, for instance, thumb. I don't know if the resolution would be high enough or if this would be practical enough for fingerprint scanning. So my first actual question is (Question #1:) Can a picture taken with most Android phones, in outside conditions, with flash on, be used for fingerprint comparison purposes against a database of maybe 1,000 users? And return the name of the given random user's fingerprint, which is stored in the database, or return that the user was not found in the database based on their fingerprint, using a picture of their thumb? Even if the answer is yes, this is not the ideal solution.
Another proposed solution is to use a picture of a person's face against a database of around 1,000 users with pictures of their faces, instead of using a fingerprint scanner at all. (Question #2a) Would this be accurate (taking a picture of a persons face and doing facial recognition) for 99%+ of cases, in outdoor conditions with the flash turned on? (Question #2b) If so, can you suggest some open-source software for this purpose to be used on the backend, compatible with say NodeJS or Elixir? Or any other programming language too if necessary... and again, this is not the ideal solution.
The ideal solution, if it would work:
Using Code Introspection in Java to interrogate the Android Fingerprint API to determine its hidden objects, methods, functions, variables, etc, and then using Reflection in Java (google it if you don't know what this is) and hack/steal the underlying fingerprint data/image/scan from the phone, then send THAT to the API with the database backend. (Question #3a) This is my primary question and the one I'm most interested in getting a good answer to. Do you know if this is possible, despite the restrictions built into Androids. (Question#3b) If it isn't possible with all Androids, is it possible with some?
(Question #3c) How would I go about this with Code Introspection and Reflection in Java? Which API and parts of the API should I focus on? I'm aware this is hackish and I'm fine with that.
I am aware of the following
As per Nexus FAQs
Your fingerprint data is stored securely and never leaves your Pixel or Nexus phone. Your fingerprint data isn't shared with Google or any apps on your device. Apps are notified only whether your fingerprint was verified.
which explains very well that you can use fingerprints for verification purpose only. Its just an alternative to any app lock available in marketplace.
and also:
FingeprintManager only has these 3 features:
authenticate : for authenticating user
hasEnrolledFingerprints : Determine if there is at least one fingerprint enrolled.
isHardwareDetected : Determine if fingerprint hardware is present and functional.
you can check FingerPrintManager docs here :
https://developer.android.com/reference/android/hardware/fingerprint/FingerprintManager.html
And I'm also aware:
"and capture the fingerprint data itself" Not possible, since that data simply isn't available. Google's fingerprint HAL implementation guidelines states that "Raw fingerprint data or derivatives (e.g. templates) must never be accessible from outside the sensor driver or TEE".
However, I have read it suggested that:
you can use android.hardware.fingerprint.Fingerprint.class
/**
* Container for fingerprint metadata.
* #hide
*/
public final class Fingerprint implements Parcelable {
private CharSequence mName;
private int mGroupId;
private int mFingerId;
private long mDeviceId; // physical device this is associated with
...
}
to compare against with enrolled one together with FingerprintManager inner class but visibility of api is hidden and you need use Java Reflection
/**
* Container for callback data from {#link FingerprintManager#authenticate(CryptoObject,
* CancellationSignal, int, AuthenticationCallback, Handler)}.
*/
public static class AuthenticationResult {
private Fingerprint mFingerprint;
...
}
This is suggested as an answer on the post: Fingerprint authetication of multiple users
But further information is needed to verify that this actually works in practice on all Android devices or at least some, and could work in my use case with a database backend.
Summary
I can have the users that are in the database scanned in / fingerprints registered, the first time with any method, I just need to know how to use an standard Android phone without a custom 3rd party USB fingerprint scanning dongle to scan fingerprints and send them to this database (and I already know how to send them to the database and compare them, I just don't know exactly how to get them from the Android device so I want to try a hackish-method of Code Introspection and Reflection.)
It may help to review the Android Open Source Project documentation on the Fingerprint HAL. In the Implementation Details section you'll see that no biometric information is to leave the trusted environment.
As discussed in the comments, while the use case may be be admirable, the desire to get Personally Identifiable Information (PII) such as the actual fingerprint image or hash is adversarial to the design of Fingerprint system in Android.
It behoves Google and the Original Device Manufacturers (ODM) to release a patch to remove such leakage, as HTC and Samsung had to do in 2015 as documented in this Ars Technica article about Severe Weakness in Android Handsets Could Leak User Fingerprints.
Ergo any valid answer here would become useless in a relatively short time, reported to bug bounty programs and/or by security researchers.
As pointed out by #halfer, while the application's end use case is benign, the side effects via a reduction in security for users and developers dependent on Android Fingerprint authentication mechanism is not.
Hopefully there is some other path to achieve your goal consistent with Android's architecture.
Is there any unique Id for android device that doesn't need permissions to access it?
I'm looking for something cannot be changed in normal cases (not ROOTED devices) so I can use it to check users who installed the application and lock the user to run only on the selected device.
The Id i'm looking for should NOT be changed when the user make "restore to factory state" or formatting the system.
Thank you.
Based on what you've said here, it sounds like you only need a unique identifier that persists within an installation (as opposed to staying consistent after uninstall and re-install).
If that's the case, then you could generate a UUID on first app launch (using UUID.randomUUID().toString()) and send it up to your server to store with that user account.
Then store it locally on the device in an encrypted manner (e.g. using RealmDB with encryption or even encrypting and storing in shared prefs) to make fraud via retrieval/modification more difficult.
I want to implement unlockable characters that can be purchased and I have a few questions about the best way to implement this in my game.
Currently I manage unlockables by storing them as preferences. However I'm now in the process of making them purchasable.
Is gdx-pay the best way to do this or create a native Android\iOS
implementation?
Once a method of purchasing characters has been implemented and the
user purchases one, what happens when the user uninstals my game?
i.e. should I reverify purchases on startup? This will require an
network connection, if the user doesn't have one it doesn't restore?
Should I be using preferences to store unlocked characters etc or
another method? My reason behind this method was to avoid having
ship a database with it and having to create separate sqLite
implementations for each platform.
Any advice would be much appreciated.
Point 1. Yes, for now if you want to go cross platform then gdx-pay is your choice. Recently they've also added support for IOS 9 which is great. You will be able to deploy on both Android and IOS with minimal change of code.
Point 2. You should always call requestPurchaseRestore in your splashScreen or somewhere on startUp to restore any purchases. This will ensure that even if the user uninstalls the game and installs it on another mobile device they will still have the purchases they've made. Of course, network connection is vital. If you don't have network access and you call requestPurchaseRestore you will get an error. That's why you should have a method to check if the user has access to the internet (wi-fi or mobile enabled) and only then call requestPurchaseRestore. If the user doesn't have internet they won't be able to restore Purchases. I don't see a problem with that. You can put a label somewhere that you need internet to restore purchases.
Point 3. Yes, having a local preferences file is a good idea. This is what I do myself. If an item is purchased you simply store it in the file. You may well use a db too but it's too much hassle for this kind of job.
I have received a requirement to develop a feature to check if 2 email id's, logins or identities are socially connected. I hope to ask 2 users their facebook id, linkedin id (and in future may be more social networks). I then hope to use their facebook id's connect to facebook api's and determine if
Are these two connected socially, are they friends ?
Are these 2 connected through mutual friends
Do they have n levels of mutually connected friends ? (like in linkedin)
Similarly I hope to use linkedin api's to identify if they are socially connected and if not, how far they are.
My question is
I have been in a social project before and understand that facebook and linked in provide a lot of restrictions on their api's. Do you know of any that stand out very obviously from I need them to do for me ?
Are there any privacy/legal issues that I need to be aware of, in these scenarios. Will there be a issue if I were to let each of the users know that they are x networks away from each other ?
Will I be able to use the api's free or is there a particular paid service that these social networks offer ? I would be worried about costs when i deploy right ?
Edited
I put some questions on linkedin forums. This is the response I got
There is no extended information available via the API for developers of business accounts. The visibility is based on the user who has authenticated and what they can see in their network. The API is not designed for you to learn information about two users other than the one who has authenticated.
Seems fair from their stand point. Even a business account would not provide private information about 2 random people's "socially connected" information.
I think I need to explore the option of having my users login/connect to linkedIn and provide me with that information. Crazy as it sounds, I will explore this.
No they should both be free. Linked in has a ton of token requirements for pulling deep information. Be sure to read the linked in Docs pretty indepth. LinkedIn hates if your exporting any user data and will throw you under the bus in a minute if you attempt this. Also linked in's very limiting tword the # of calls you can make per account in an hour. SO be prepared for rate limiting.
A few months back I had contacted facebook, linkedin and google+ for a similar requirement. Seems that they dont appreciate scraping at all. I dont know if you intended to do that. They also mentioned that this information relates to peoples privacy, so they need to login to allow you to do that. Infact you need to be in their network to achieve something even close. You will also need a plugin/app to work along side with you, which will have other restrictions like # of requests per day/hour.
In short, you are requesting information from deep within their databases, they are not going to like it.
With some more research, its clear that without both users providing my app the authority to query on their behalf about the other user, I cannot get this working. Not even with business accounts with both linkedin and facebooks. The reason is obvious, privacy.
Does anybody know if via the google api in java
I can create google accounts programmatically.
Yes
(ish)
The Admin SDK Directory API allows you to create accounts which work with Google tools (Gmail, Calendar, etc.) but are not #gmail.com / #googlemail.com accounts.
This is used by companies to automate creation of accounts for online google tools when new users are added to networks and similar scenarios.
User management is documented here.
This replaces the provisioning API which was deprecated in 2013.
NO
The only possible way to do this would be to use a web automation framework. Python is great for web automation using tools such as mechanize. I've never done it in Java, but you should do a google search for java programmatic web browser or java web automation.
On top of that you would have to incorporate an OCR package to beat the captcha.
There is a reason that google, nor anyone else, allows the programmatic creation of accounts. Spammers would have a field day. Within days there would be no valid accounts left for any new users to use. In short, it would be a disaster.
As others have pointed out, you cannot create Google consumer accounts (ie, #gmail accounts) via any sort of API. It would create a field day for Spammers. To make it difficult for Spammers, Google uses tactics such as CAPTCHAs to prevent abuse.
But, you can create Google Apps accounts via their Provisioning APIs. A Google Apps account is basically a white labeled version of Google Apps (Gmail, Calendar, Docs, etc) that is under your own domain name.
For the same Spam concerns, your Google Apps account would have to be either a Premier domain (where you pay for every account you provision) or an Educational institution (I assume some sort of verification process for that). So, since you have to pay for each account, it's not a huge risk for spammers (unless they want to pay big $$$ for each account.. very unlikely).
It depends on your definition of create account...
it is possible to create an account inside a google group, or domain. By using the code below you can create accounts for your google group/domain. For this scenario YES you CAN create a google account.
However, if you want to create a google account as in #gmail.com... I really have not found a way to do it programatically.
Here is the link of where to download the google api, and the Documentation.
https://developers.google.com/google-apps/provisioning/#creating_a_user_account
Good Luck.
import sample.appsforyourdomain.AppsForYourDomainClient;
AppsForYourDomainClient client = new AppsForYourDomainClient(email, password, domain);
client.createUser(String username, String givenName, String familyName, String password)
The real answer is YES.
The fact is that we don't know (yet) how.
The proof is that an account can be created from any android device without any captcha, without a phone number and without an email.
So the secret is inside android codebase.
MAYBE?
I am going to write an answer that has not been written so far, but which could actually break the EULA (if that's the case, can someone point out the specific paragraph of it that prevents this?).
The solution is: redirect Google's CAPTCHA to your user.
Assuming your software has a user, you could present them Google's captcha so the account is created by them, for your system, without them knowing.
Would this work for you?
You can do that theoretically, but Google's account creation - like other services - uses image recognition for confirmation that you're a user (aka CAPTCHA) and you need to be able to write image recognition program that can do that.
AFAIK there's no programmatic API from Google to create accounts, since doing so would open them up to spammers/scammers/etc... which the CAPTCA was meant to prevent.
Why would you do that? I am not sure Google allows that in the first place as far as EULA.
I am going to assume that you aren't telling us your use case which is really to have a convenient way to use google logins on your site (because that's the closest you'll get and be legit). I would check out using OpenID in the same way SO does.
Actually, you can create if by google account you mean your own domain (those business ones using google).
You can check it here
YES...
Actually you can do that. You can write CUrl scripts and can use different APIs available to break the captcha.
Breaking a captcha is key thing here.
The fact that Google's account creation UI requires a CAPTCHA is your first hint that the answer is NO.