How to get list of downloaded apps (paid/free) by a user from Google Play?

I recently came across this app Purchase Apps, which is somehow able to retrieve apps I've paid for in google play after I signed in using my google account.

I'm trying to find out how it is being done as I want to build a similar app, but for the free apps which were downloaded.

However, I can't find which OAuth API Scope was used for retrieving that information, even after going through the entire list of APIs.

Google Sign in asking for access to androidmarket


EDIT: I'm putting a new bounty on this question, as suggested by a similar question I've asked about here, and because here and there I don't see a real answer about how to do it, and what can be done with it.

I'd like to refine the questions into multiple pieces:

  1. What is the API that can be used to get information of purchased apps? Where can I read about it? Please show a full, working example of how to do it.

  2. Can it do more ? Maybe perform search? Maybe show free apps that were installed? Maybe the time they were installed and uninstalled? And the categories of those apps?

  3. Are there any special requirements for using this API ?


EDIT: I'm putting a max bounty on this, because no matter how much I've read and tried, I still failed to make a POC that can query the apps from the Play Store that the user has ever downloaded (name, package name, date installed and/or removed, icon URL, price...), including both paid and free apps.

If anyone finds a working sample, show how it's done, and also show how you've found about it (documentation or anything that has led you to the solution). I can't find it anywhere, and the current solutions here are too vague for me to start from.


Issue is resolved. The exploit has been closed.

We will be closing this bug due to being logged in a Preview version of Android. If the issue is still relevant and reproducible in the latest public release (Android Q), please capture a bugreport and log the bug in https://source.android.com/setup/contribute/report-bugs. If a reply is not received within the next 14 days, this issue will be closed. Thank you for your understanding.


Latest update:

This is a bug and Google will address it in the next update.

We've deferred this issue for consideration in a future release. Thank you for your time to make Android better


This answer has turned into a conglomeration of ideas and been edited to include information from discussion in the comments.

The androidmarket api, would be a customised api written by the developer. It's not available to the public.

To address your concerns in the comments. The developer would have utilised the current apis available through Android Developer and Google to create a project that manages all of these.

As for accessing Full Account Access, I'm not sure exactly how these developers have achieved this.

I'd recommend using the AccountManager, which is part of android.accounts, has access to credentials and a method getUserData. The account manager has access to passwords and is capable of creating and deleting accounts. This, possibly used with Content Provider

See Udinic/SyncAdapter Authentication.

To reply to your comment:

This blog should help you to get started. Write your own Android Authenticator.


How these apps actually work, I cannot tell you. They may also have different implementations (unless they're a collaborative effort behind the scenes, they most certainly will be different).

One guess. Firstly use GoogleSignInAccount with com.google.android.gms.auth.api.signin.

There a definition for scope, to determine the extent of the permissions the app is granted.

Using requestScopes(), the

public static final String PROFILE

.../ It lets your web app access over-the-air Android app installs.

For example:

GoogleSignInOptions gso =
        new GoogleSignInOptions.Builder(GoogleSignInOptions.DEFAULT_SIGN_IN)
            .requestEmail().
            .requestScopes(new Scope("https://www.googleapis.com/auth/contacts.readonly"))
            .build();

If full access can be gained a list of all apps used by the account holder can be found and compared to what's on the device.

Package Manager will retrieve a list of all apps currently installed on the device.
PackageInfo provides the details about the app.
INSTALL_REASON_USER will also filter out apps that have been actively installed by the user.

You might want to look at com.google.firebase.appindexing and Log User Actions. Different actions can be tracked.

The users account history is found at https://myactivity.google.com/myactivity.

A helpful link is the OAuth 2.0 Playground.


This github repo node-google-play, using node, is current and will call Google Play APIs. As did the archive that was used as an "unofficial" api, android-market-api, to query the market place.


App 1

The app claims to use the following permissions:

Version 2.1.8 can access:
$ In-app purchases

Other

  • receive data from Internet
  • view network connections
  • full network access
  • use accounts on the device
  • prevent device from sleeping
  • read Google service configuration

Noteworthy, the app doesn't set any permissions when there was a basic, install. I was unable to use any of the features, as I have no paid apps. So for the initial search - there were no permissions needed, which would indicate the app didn't have access to my account.

I checked the permissions - there were none set. So the only thing required was to accept the pop up, as displayed in your question.


App 2

The other app you refer to that does the same thing is more upfront about what is being accessed.

My Paid Apps

SECURITY/PRIVACY NOTICE
The first time you run this app, it will ask for full permission to your Google account. This is unfortunately the only way to access the required information. No personal information is stored, no information about your apps is shared with the developer of this app, nor shared with any third parties. Everything is kept on your phone only.


I've gone into detail over these apps in this blog post, which was for a university capstone project (no monetary gain). I'm inclined to think this is an exploit in the API and not status by design by Google, as there are no API calls to fetch purchases of apps other than the developer's own app. I hypothesize it's a zero day exploit, in which case there's no legitimate way to access this information.


In case of one of these applications (My Paid Apps), after checking the network traffic it is pretty obvious that it does use the Store's Account page to retrieve the list of paid applications. Now, the mechanism it uses is the same mechanism that Google Chrome currently, and Pokemon GO supposedly at a point in time used.

In a nutshell, steps to do so are as follow:

  1. Login: What the mentioned program do for the first step is to log the user in and get access to the user's access token. To do so, it uses the android.accounts.AccountManager.getAuthToken() method. (See more: AccountManager) However, as for the token scope, oauth2:https://www.google.com/accounts/OAuthLogin is requested. It might be important to note that based on the OAth2 documentation from Google, this scope is not valid; however, it seems like a valid scope for Google OAuth v1.

  2. Converting the newly retrieved access token to a ubertoken: Now, what actually ubertoken supposed to do, is unknown and there is no official documentation about it. However, it was seen in the wild to be used by chrome browser to login users. This is done by requesting the https://accounts.google.com/OAuthLogin?source=ChromiumBrowser&issueuberauth=1 page.

  3. Converting ubertoken to website session: Later on, using the newly created ubertoken it is possible to get a website session using the https://accounts.google.com/MergeSession API endpoint. After this step, the application is essentially capable of loading all personal pages that you can open using your browser while logged in; except some special pages including Payment settings.

  4. Retrieving the list of paid applications: Requesting and parsing the https://play.google.com/store/account page.

Following is the application's traffic as captured by 'Packet Capture':

Captured Traffic

As it is clearly visible in the picture, the end result is identical to what I get when I normally open the store's account page on my PC with Chrome Desktop: Chrome view source

Side note:

It seems none of these endpoints are documented as they are primarily used by Google's own programs and should be considered internal. Therefore I strongly recommend not using them in any program or code that you expect to run for a long time or in a production environment. Also, there is bad news here for you too, it seems that the Google Play's account page only lists paid applications or special free apps (more especially OEM apps). I will try to find some time and dig deeper into the other application.

Interesting articles:

Pokemon tokens

Exploiting Google Chrome's OAuth2 Tokens


If you have root access, You can access /data/data/com.android.vending/databases/library.db

OnePlus3T:/data/data/com.android.vending/databases
-rw-rw---- 1 u0_a2 u0_a2 229376 2018-12-26 18:01 library.db

This database has all information, which app you have downloaded, which apps you have purchased, and even in which app you have done IAP.

Check ownership table, It has all information.

ownership (account STRING, library_id STRING, backend INTEGER, doc_id STRING, doc_type INTEGER, offer_type INTEGER, document_hash INTEGER, subs_valid_until_time INTEGER, app_certificate_hash STRING, app_refund_pre_delivery_endtime_ms INTEGER, app_refund_post_delivery_window_ms INTEGER, subs_auto_renewing INTEGER, subs_initiation_time INTEGER, subs_trial_until_time INTEGER, inapp_purchase_data STRING, inapp_signature STRING, preordered INTEGER, owned_via_license INTEGER, shared_by_me INTEGER, sharer_gaia_id TEXT, shareability INTEGER, purchase_time INTEGER, PRIMARY KEY (account, library_id, backend, doc_id, doc_type, offer_type))