Android: Get information about app purchase - android

Is there any android api to get information about the purchase of the app? I don't talk about in-app purchases. Just the Plain APP-Purchase.
I need any unique identifier like an transaction id or something like that.

As mentioned in other answers, it looks like there's no public API for it. (I believe, the reason for it is that by default - once user starts the app - he has already got if from Google Play. So in the ideal world, there should be no need for this check)
If I were you, I'd implement some tiny API endpoint on your server side and sends it hashed version of the user's accountId (see Accessing Google Account Id /username via Android ) and Timestamp-response(or any other reasonable data back) of initial call of this method for this particular user Id (i.e. once he changed his phone - you'll still track him).
To get current Account do this:
Account[] accounts = AccountManager.get(this).getAccountsByType("com.google");
if (accounts.length != 0) {
String myEmailid=accounts[0].toString();
}
(taken from here)
Tested on API 19 and API 23(In Android M it requires a bit extra work due to permission-check)

As per my understanding of question you want to get information of your app buyers or you want to check particular user's purchase status for your app.
AFAIK :
As of now I can't able to see any buyers info for your android application purchase.
Reference : https://support.google.com/googleplay/android-developer/answer/6056620?hl=en
But in past may be we were able to see such information.
Reference : Android Market (Google Play). Get buyer information

As far as I know there is no way to persist this information across app uninstall/reinstalls. You can get the installation timestamp but this will be reset when reinstalling.
However, a workable solution may be to set a flag in SharedPreferences and save the data using Android Backup (http://developer.android.com/guide/topics/data/backup.html#SharedPreferences)

The most reliable way would be to create your own (web-)service and have the app register itself with the google user name (How do I retrieve the logged in Google account on android phones?), and check the registration on later reinstall.

Related

In-app purchases with multiple accounts

I am facing a problem with in app purchases/subscriptions:
If there are multiple accounts on the device, I can't get the purchases, which were made with the second account.
This can sometimes be temporarily fixed, by installing the app from the Google Play web interface, but after a while, the purchases won't appear in the query, forcing the user to reinstall.
I am using the IabHelper classes from this sample.
Doing some Google searches, I found that this bug exists since a while, but unfortunately I couldn't find out if the error is in the IabHelper classes or on Google's side.
I'd like to draw attention to Google, so they provide a proper fix for this, either in the IabHelper classes or in the Play Services or to provide information, how this should be handled.
I am using the code in an app with (at the time of writing) 900.000 active user installs and I have to trigger quite a lot of refunds, due to this.
If there is a fix for this, which I missed, please let me know.
Edit:
Sometimes it's not possible at all to retrieve the purchases, even if there is only one account on the phone.
It seems like there isn't a one way road to solve this, but let's try do this.
When the user first install the app get his/her primary email or all accounts on the device
Ask the user what email will they be using for future payment/ or which account is active for google play.
you can use this code to get the account
Pattern emailPattern = Patterns.EMAIL_ADDRESS; // API level 8+
Account[] accounts = AccountManager.get(context).getAccounts();
for (Account account : accounts) {
if (emailPattern.matcher(account.name).matches()) {
String possibleEmail = account.name;
...
}
}
Don't forget to ask for permission
<uses-permission android:name="android.permission.GET_ACCOUNTS" />
After the user selects the email, you can send a link via email to confirm this email address
Lead all the payment to that specific email.
Method 2
Use the new "Send & Receive money using Gmail" future
Create a email intent and send specific data to the email intent and make payments.
Upon success, send a code to the user email
Use the code to activate whatever purchased they make.
Method 3
Use another payment library or gateway for your in app purchase instead of Google play.
As others have noted, this is a bug with the Google Play Billing Library. If it affects you, star this issue on https://issuetracker.google.com/issues/139597485 so Google can notice it (really?) and start working on a fix.
It is sure a bug in the in-app billing service apis. This is a similar question and as mentioned in one of the answers, may be you need to introduce login mechanism and store the purchases made from an account to your server or locally on the device in an encrypted file or something similar.
I had ran into same problem couple of months later.
After hours of finding solutions and all i came up with a work around something like this,
You can use OAuth 2.0.
But you also have to manage it from your backend.
I am not a backend developer so i didnt know how exactly it does in backend but at app side i have done something like this,
You can use the first Google account allowing authentication on your serve side. OAuth 2.0 is a tool that simplifies and get developers an easy way to allow users to access your application. The OAuthHmacSigner class does manages the authentication.
signer = new OAuthHmacSigner();
signer.clientSharedSecret = Constants.CONSUMER_SECRET;
Then the Android activity uses the following code to launch the OAuth flow :
launchOauth.setOnClickListener(new View.OnClickListener() {
public void onClick(View v) {
startActivity(new Intent().setClass(v.getContext(),
PrepareRequestTokenActivity.class));
}
});
In order to get an OAuth 2.0 access token, you simply need to call:
AccountManager.getAuthToken()
I Hope this might help :)
I have two accounts, but one does not work. What I did is I went into android's settings, and then went into account preferences. I changed my main account from the one that does not work to the working one. Then I assigned the new account to be the main one for all of my applications, including google play. That worked for me. Sometimes, if it does not work for some reason, you can also go online and access the Google Play store from the internet.
Try to get dup...duplicate dot with file signature ending in .apk or .xcode
I'm not sure if this is the answer you're searching for, but perhaps setting up a shared Google Play Family Library would suffice. It works for up to 5 users sharing the same purchases (app, music, movies, etc), if desired.
(See: https://support.google.com/googleplay/answer/7007852?hl=en)

cordova detect if app was downloaded from Google Play

I'm making a Cordova 4.0 Android app that will be sold in Google Play, and I would like to prevent illegal use of it (for example preventing someone to extract the APK from the system and re-distributing it).
One theoretical way of doing this would be by checking that when the app is launched by the user, he did actually download it from Google Play (versus being it sideloaded). I'm not even sure if this is possible or if there's an alternate way of doing something like this.
One way that works in other cases is to use require some sort of login when accessing the app, but in this case I can't do that. Any advice would be appreciated!
Google offers a way to implement validation / licensing:
http://developer.android.com/google/play/licensing/index.html
Take a look if this is what you need!
One suggestion would be for those apps which are get connected to a server to fetch some data.
App verification token
Generate an encoded 64-bit long token and store on both device & server as well. This will be a unique token per app
Whenever app tries to connect to server, it sends the device token details. Server needs to verify it before fulfilling its request.
On specific events, server can generate a new token for a device.
Same way, device token can be mapped to a user or an app on the server side.
Token could carry some app related information, for instance.
first 4 or 6 digits represent app size
second block of digits could represent user specific or device or some other details
Or another block could hold app contents modification date
In case of any change, server could verify the app size, last app contents modification dates, etc.
Generally it is recommended to uglify, obfuscate and minimize app resources before submission.
You can use the package manager class to determine the source of an app (only google or amazon currently detected)
You can similarly use google analytics which gives same information.
This is pretty neat since Android stores the source of every package, allowing apps to know where they came from, to prevent piracy and sideloading.
Great if you always publish to google or amazon. Useless if you sideload your app.

Check if a device google account is authenticated, only then allow access to my offline app

I have a private app which works totally offline (i.e. no server data sent/recieved), however I have a need to restrict it only to users with a valid Google account on their phone. I can get make sure there is a suitable account on the phone by iterating a list of phone accounts, but is it possible to check the account is valid/authenticated without me having to introduce the full OAuth process? I have no need to get a cookie or send any data to a server.
Ideally I'd like to do something like:
1. Check with the account manager for an auth token.
2. If token recieved then allow access to the app.
Currently without any checks via the account manager, anyone could create a fake account on the phone and then gain access even if they put in a email/password and they would never be authorised.
I hope I've explained this clearly. As my app has no network connectivity so I would like to avoid adding any of my own network/oauth checking.
What about this:
AccountManager manager = AccountManager.get(this);
Account[] accounts = manager.getAccountsByType("com.google");
final boolean connected = accounts != null && accounts.length > 0;
The connected boolean will indicate if there is a connected Google account in the phone.
Indeed there won't be any check on the token, but if the account is registered on the phone, then Google checked it before, server-side, to validate it...
How about implementing Google Plus login API? It's not really setting up a full OAuth process since G+ it's fairly simpler, even if it is actually built on top of OAuth.
I use that in an app I'm developing that also does not require online access (except for initial G+ login access).
What I do is the first time the app is run I present the G+ login button. After user clicks on it he can accept the permissions request from my app (to be able to retrieve user email and some basic profile info, i.e. minimum permission needed) and if the API client connects correctly then I present the user with the dashboard or home screen and also set up a flag in SharedPreferences about the user being already authorized.
In this way, the next time the user starts the app it will remember it was already authorized and just ask the API client to connect (only if the access was revoked from the account's Play Store website do we need to re-verify that the user auth is still valid), and everything should work. If the user revokes the access to his G+ profile from my app, I clear the flag so the next time the user runs it it asks for authorization again.
It's actually very simple and at least for my use case (Which sounds very similar to yours) it works for what I want it with minimum user intrusion.
I strongly suggest you try out something like this Google Plus login tutorial
Edit: You can also check this question I asked before, about working with multiple activities that need Google Plus functionality
Also, forgot to say that with this method you are always sure that the user account is always valid since you are checking directly with Google's servers about its validity.

List of Installed App From Google Play Against Google Account

Following are my problems:-
Is it possible to get the list of applications that a user has installed, against their google account through Google Play, programmatically through the use of any api?. Please note that I am not asking about the list of apps currently installed in the device, but ones that have at some point been installed.
I need a solution to the above as I am thinking of a scenario in my app, which is:
I want to give my app to the user for free during the first three months, after three months if user uninstalls the app and then installs it again I want to detect through any api (from Google Play) that the user has installed the app a second time (and should not get any free usage). Please note that I don't want to use any web service to store the account id & device id of the user at my side.
For option 2, you can create a file on the SD card. This will remain there when the user uninstalls/installs. But the user can always delete your special file. Unless you do something at your side, you are never sure if the user already used your app before.
To be completely sure, store it online:
You will need to have a very simple database which holds a list of device_id that installed your app.
Further more a webpage which fills this database.
In your app you download/open this webpage which the webpage will fill the DB.
App > WebClient (or other) which opens http://www.example.com/registerDevice.php?device_id=. The php site fills the db.
You app will need to check the database if the current device already has installed this app inorder to work/not work. You can do this via the same php and check the response. You could for example return 'ok' or 'not ok' or something else.
The simplest method is to get the account of the user the first time he/she runs the app, and send that detail over to you.
How this is can be done is well-documented over here: How to get the Android device's primary e-mail address
You will have to add another line of code to check back to the database at the first start of the app.
EDIT: For a non-web solution, simply add a timer to the start of your app:
schedule(TimerTask task, Date when)
the task should be adding a token AFTER the period of time you wish to give, to the phone's memory with the user's account details for authentication (see first solution on getting the account details)
Finally, as above, add a check-back to the phone's memory for that particular file to see if the user has used the app before.
The problem with any type of authentication that is based on the phone's memory is that people can easily remove the token, if they can find it, and reuse the app again.
Try this device specific implementation:
PackageManager packageManager = getContext().getPackageManager();
List<ApplicationInfo> applications = packageManager.getInstalledApplications(
PackageManger.GET_UNINSTALLED_PACKAGES);
// retrieves some information about all applications (even uninstalled ones)
// which have data directories
Of course this method won't work if user replaces the device. But you don't need to use any web service.
You can use this by keeping a database of hashed device id and users google id on a 3rd party server.
Also see http://android-developers.blogspot.de/2011/03/identifying-app-installations.html

Can a android device start giving null value for device id?

I have an app on the market. When you start playing your device id is linked to your account so you don't have to log in manually. For some time now a few people had a problem. They started logging in into different accounts. What seems to be the problem is that some devices give a null value when asked for device id. With a few accounts with a null device id, people were logging into different accounts.
I read that some devices will do that. But it seems that there was no problem during account creation and then playing for a while.
I know this is not the best method and google discourages using device ids since they can change on fabric reset.
Can a device for some reason stop giving its id(besides the fabric reset)?
Anyone know of a different way to identify the user with out him needing to put in a login or password?
Yes some phones have bugs in them where they will return NULL for Android ID. I think if you want to continue to use them you'll always need a way to tie that handset to an account, email, username. That way if the Android ID is unrecognized they could login using their email or username, and password to associate them again. You'll always have issues where someone buys a new phone and needs a way recover their account if you don't.
A better option is every Android phone is attached to a Google account. And using the AccountManager class you can use those credentials to authenticate to your software automatically and the user doesn't have to enter username/password. And you'e centralized their identity. Also with this method you don't require the extra permissions to read data that has potential security issues too.
You could create a random UUID after the user has installed your app.
Do not use hardware ids, because not every type of hardware is found in every type of Android device. Another reason not to use them is, if someone sells his phone, the user changes but the device id not! This has serious privacy and usability implications you do not want to have.
See the talk Android Protips (from google io 2011). Tune in at 15:00 to see more reasons and a detailed descriptions on how to use random UUIDs for your usecase.
I am facing the same problem In my case when first install the app it is giving null id . but after that it is giving me all three IMEI, ANDROID_ID and deviceID.
BTW, you can find the ways to identify the devices here
http://innovator.samsungmobile.com/cms/cnts/knowledge.detail.view.do?platformId=1&cntsId=9640
Also some research prototypes try to prevent phones from collecting this information.

Categories

Resources