如何获取用户从Google Play下载的应用程序列表(收费/免费)?


121

我最近遇到了这个应用程序Purchasing Apps,使用我的Google帐户登录后,它可以以某种方式检索我在Google Play中付费的应用程序。

我想找出要完成的过程,因为我想构建一个类似的应用程序,但要下载免费的应用程序。

但是,即使遍历整个API列表,我也找不到用于检索该信息的OAuth API范围。

Google登录要求访问androidmarket


编辑:我在这个问题上给予了新的悬赏,正如我在这里问过的类似问题所建议的那样,因为在这里和那里我看不到有关如何做以及可以做什么的真正答案。用它。

我想将问题细分为多个部分:

  1. 可用于获取购买的应用程序信息的API是什么?我在哪里可以读到它?请显示一个完整的可行示例。

  2. 它还能做更多吗?也许执行搜索?也许会显示已安装的免费应用程序?也许是他们安装和卸载的时间?以及这些应用的类别?

  3. 使用此API是否有任何特殊要求?


编辑:我对此给予最大的赏赐,因为无论我阅读和尝试了多少,我仍然无法制作一个POC来查询用户曾经下载过的Play商店中的应用(名称,软件包名称,安装和/或删除的日期,图标URL,价格...),包括付费和免费应用。

如果有人找到了有效的示例,请说明如何完成,并说明如何找到它(文档或导致您找到解决方案的任何内容)。我在任何地方都找不到它,这里的当前解决方案对于我来说太模糊了。



我将看一下示例应用启动器。它知道手机上下载了哪些应用程序。
danny117 '18

@android开发人员:我已经Purchase Apps通过反编译分析了apk文件。它从未使用过任何API来获取购买的应用程序列表。它的方法与我们所知道的解析Play商店网页的html内容相同。这是这段代码的一部分:hastebin.com/uceyavurij.js
aminography

@aminography那么如何为用户获得它呢?毕竟,它需要获取用户的Google帐户的数据...仅访问Play商店应用程序还不够...赋予它的权限有什么用?
Android开发人员

@androiddeveloper:提供的所有信息Purchased Apps都可以从Playstore网站内容中检索。不幸的是,我无权从Google Play购买应用。如果您与我分享一个拥有已购买应用程序的帐户,那么我可以为您开发一个示例代码。
摄影自从

Answers:


51

问题已解决。该漏洞利用已被关闭。

由于已登录Android的预览版,我们将关闭此错误。如果该问题在最新的公共发行版(Android Q)中仍然相关并且可重现,请捕获错误报告,并将该错误记录在https://source.android.com/setup/contribute/report-bugs中。如果在接下来的14天内未收到答复,则将关闭此问题。感谢您的理解。


最新更新:

这是一个错误,Google会在下一个更新中解决。

我们已将此问题推迟到以后的版本中考虑。多谢您抽出宝贵时间改善Android


该答案已转变为各种想法,并进行了编辑,以将评论中的讨论内容包括在内。

androidmarketapi 是开发人员编写的自定义api。它不向公众开放。

在评论中解决您的担忧。开发人员将利用Android开发人员和Google提供的当前api来创建一个管理所有这些程序的项目。

至于访问Full Account Access,我不确定这些开发人员是如何实现的。

我建议使用AccountManager,它是android.accounts的一部分,可以访问凭据和方法getUserData。帐户管理员可以访问密码,并且能够创建和删除帐户。可能与Content Provider一起使用

请参阅Udinic / SyncAdapter身份验证

回复您的评论:

该博客应该可以帮助您入门。 编写自己的Android Authenticator


这些应用程序实际上是如何工作的,我无法告诉您。它们也可能具有不同的实现方式(除非它们是幕后的协作,否则它们肯定会有所不同)。

一个猜测。首先使用带有 com.google.android.gms.auth.api.signin的GoogleSignInAccount

有一个scope的定义,以确定授予应用程序权限的程度。

使用 requestScopes()

公共静态最终字符串PROFILE

... /它允许您的Web应用程序通过无线方式访问Android应用程序安装。

对于例如

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

如果可以获得完全访问权限,则可以找到帐户持有人使用的所有应用程序的列表,并将其与设备上的内容进行比较。

软件包管理器将检索设备上当前安装的所有应用程序的列表。
PackageInfo提供有关应用程序的详细信息。
INSTALL_REASON_USER还将过滤掉用户已主动安装的应用程序。

您可能需要查看com.google.firebase.appindexing日志用户操作。可以跟踪不同的动作

可以在https://myactivity.google.com/myactivity上找到用户帐户历史记录。

一个有用的链接是OAuth 2.0 Playground


这个使用node的github repo node-google-play是最新的,将调用Google Play API。与用作“非官方” API的档案库android-market-api一样,它可以查询市场。


应用程式1

应用程序声称使用以下权限:

2.1.8版可以访问:
$应用内购买

其他

  • 从互联网接收数据
  • 查看网络连接
  • 完全网络访问
  • 在设备上使用帐户
  • 防止设备进入睡眠状态
  • 阅读Google服务配置

值得注意的是,在进行基本安装时,该应用程序未设置任何权限。我没有任何付费应用程序,因此无法使用任何功能。因此,对于初始搜索-无需权限,这表明该应用无权访问我的帐户。

我检查了权限-没有设置。因此,唯一需要做的就是接受问题中显示的弹出窗口。


应用程式2

您引用的另一个执行相同功能的应用程序是关于正在访问的内容的更直接的信息。

我的付费应用

安全/隐私声明
首次运行此应用时,它将要求您的Google帐户获得完全许可。不幸的是,这是访问所需信息的唯一方法。不会存储任何个人信息,不会与该应用的开发者共享有关您应用的信息,也不会与任何第三方共享。一切都只保留在您的手机上。


这篇博客文章中,我已经详细介绍了这些应用程序,应用程序是用于大学的顶峰项目(没有金钱收益)。我倾向于认为这是对API的一种利用,而不是Google的设计状态,因为没有API调用可以获取开发者自己的应用程序以外的其他应用程序。我假设这是一个零日漏洞利用,在这种情况下,没有合法的方式访问此信息。


10

对于这些应用程序之一(“我的付费应用程序”),在检查网络流量后,很明显它确实使用“商店的帐户”页面来检索付费应用程序列表。现在,它使用的机制与Google Chrome当前使用的机制相同,而Pokemon GO可能在某个时间点使用。

概括地说,这样做的步骤如下:

  1. 登录:上述程序第一步要做的就是登录用户并获得对用户访问令牌的访问权限。为此,它使用android.accounts.AccountManager.getAuthToken()方法。(请参阅更多:AccountManager)但是,对于令牌范围,oauth2:https://www.google.com/accounts/OAuthLogin是必需的。请注意,根据Google 的OAth2文档,此范围无效;但是,这似乎是Google OAuth v1的有效范围。

  2. 将新检索的访问令牌转换为ubertoken:现在,实际ubertoken应该执行的操作是未知的,并且没有官方文档。但是,Chrome浏览器普遍使用它来登录用户。这是通过请求https://accounts.google.com/OAuthLogin?source=ChromiumBrowser&issueuberauth=1页面来完成的。

  3. 转换ubertoken为网站会话:之后,可以使用新创建ubertokenhttps://accounts.google.com/MergeSessionAPI端点来获取网站会话。完成此步骤后,该应用程序基本上可以加载您在登录时可以使用浏览器打开的所有个人页面。除了某些特殊页面,包括“付款”设置。

  4. 检索付费应用程序列表: 请求和解析https://play.google.com/store/account页面。

以下是由“ 数据包捕获 ” 捕获的应用程序流量

捕获的流量

如图所示,最终结果与我通常使用Chrome桌面在PC上打开商店的帐户页面时得到的结果相同: Chrome浏览器源

旁注

这些端点似乎均未记录,因为它们主要由Google自己的程序使用,应视为内部端点。因此,强烈建议不要在希望长时间运行或在生产环境中运行的任何程序或代码中使用它们。另外,这里也有一个坏消息,似乎Google Play的帐户页面仅列出付费应用程序或特殊的免费应用程序(尤其是OEM应用程序)。我将尝试寻找时间,并深入研究其他应用程序。

有趣的文章

宠物小精灵令牌

利用Google Chrome的OAuth2令牌


1
您能否显示完整的示例以查看其工作原理并回答我所提出的问题?如我所写,我想获取有关每个应用程序的各种信息:价格,购买时的价格等。是否还可以获得免费应用程序的列表?
Android开发人员

3

如果您具有root用户访问权限,则可以访问 /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

该数据库包含所有信息,已下载的应用程序,已购买的应用程序以及已完成的应用程序IAP

检查所有权表,它具有所有信息。

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))

1

处理非官方的Google API十分复杂。这将是可行的,但这就是我要说的。继续需要您自担风险。

您要做的第一件事就是获取Google Play身份验证令牌。可以通过多种方式完成此操作,但是以下是他们在“购买的应用程序”中的操作方式:

public static String getAuthToken(Activity activity, String userEmail) {

    AccountManager accountManager = AccountManager.get(activity);
    Account userAccount = new Account(userEmail, "com.google");

    Bundle options = new Bundle();
    options.putBoolean("suppressProgressScreen", true);

    String token;

    try {
      Bundle result = accountManager
        .getAuthToken(userAccount, "androidmarket", options, activity, null, null)
        .getResult();
      token = result.getString("authtoken");
    } catch (OperationCanceledException e) {
      Log.d(TAG, "Login canceled by user");
      return null;
    } catch (IOException | AuthenticatorException e) {
      Log.e(TAG, "Login failed", e);
      return null;
    }

    return token;
}

这里需要注意的几件事:

  • 上面的代码必须异步运行。我推荐RxJava,但是AsyncTask可以工作。
  • 您必须提供要使用的帐户的电子邮件。我将把细节留给您,但这使用起来很容易AccountManager

获得身份验证令牌后,您现在就可以访问任何Google Play商店终端节点了。购买的应用使用的主要工具是https://android.clients.google.com/fdfe/purchaseHistory。您可能感兴趣的另一个是https://android.clients.google.com/fdfe/details?doc=(package name)(来自APKfetch代码)。这是一个包含更多和一些分析的页面。 如果您对这些API提出请求,则需要提供几个标头:

  • Authorization -- "GoogleLogin auth=(your auth token)"
  • User-Agent -- "Android-Finsky/6.4.12.C-all%20%5B0%5D%202744941 (api=3,versionCode=80641200,sdk=" + VERSION.SDK_INT + ",isWideScreen=0)";
  • X-DFE-Device-Id-从AdvertisingIdClient获得的设备的Google服务框架ID 。
  • X-DFE-Client-Id -- "am-android-google"
  • Accept-Language-设备的语言代码,例如"en"

现在,您需要解析响应。这是棘手的地方。这些API会返回一条编码为Protobuf的消息,因此,除非您具有模式(当然只有Google具有),否则它基本上只是二进制数据。从理论上讲,解决此问题的一种方法是反编译Google Play商店应用程序,并使用JADX之类的工具重用其生成的protobuf模型。

不幸的是,我已经尝试过了,但实际上并没有用。对于标准的反编译器而言,Protobuf模型类太复杂了。您可以使用一个名为PBTK的工具。理想情况下,您将希望在Google Play商店6.1.12 APK上运行它,因为那是他们开始使用ProGuard之前的最新版本。注意,这计划在其脚本两个错误是需要运行它之前被固定:改变'extracto''extractor'gui.py和500行移除断言语句jar_extract.py

现在,应该将所有响应类输出为.proto文件。在src / main下创建一个名为的文件夹proto,并将整个生成的'com'目录拖到该文件夹中。您可以删除不在下的所有内容com/google/android/finsky/protos。遵循在线说明以使用Protobuf Lite插件设置Gradle。

当您想解析响应时,可以使用ResponseWrapper类,因为它们似乎都包含在该类中。

那是我所能带给您的。我很有可能会误解其中的一部分。JADX是您最好的朋友,因为了解应用程序运行状况的最佳方法是查看其代码。希望这会有所帮助,并乐于发展!


关于AccountManager,您确定它仍然可用吗?我认为当今Google仅提供使用选项AccountPicker(如此处:stackoverflow.com/a/26888259/878126)。但是我该如何执行其余的工作?你测试过了吗?它对您有用吗?请分享它的代码。这就是为什么我设置了赏金,以便看到它发挥作用的原因...
android开发人员

是的,AccountPicker实际上是一个更好的主意。是的,我确实尝试了获取令牌的代码,并且效果很好。我没有尝试其余的,因为如果一切顺利的话,那至少要花5个小时。即使是500英镑的赏金也不值得。
qualverse

1
这是获取身份验证令牌的完整代码(它的工作原理与屏幕截图中购买的应用程序相同):github.com/ethanblake4/PlayStoreDemo
qualverse 18'Dec 30'18

获取身份验证令牌似乎很好。但是我认为最困难的部分是应用本身的获取:(
android开发人员

是的,不幸的是,这是需要大量工作的部分。但是,我反编译了“购买的应用程序”的代码,这就是在此完成的。如果您需要上述步骤的帮助,请随时告诉我。
qualverse

-2

您可以获取设备上所有已安装应用的软件包名称,然后从Google Play获取设备中找到的每个已安装软件包的信息,而无需获取用户帐户。有一些第三方或非官方的api可以通过获取应用程序包名称来将Google Play应用程序详细信息作为json获取。例如:https//42matters.com/, 然后使用接收到的信息获取每个软件包以查找免费软件包。


不,我悬赏的问题是用户曾经安装的应用程序,而不仅仅是现在安装的应用程序。另外,如果有正式的方法,为什么还要使用非官方的方法呢?
android开发人员

@androiddeveloper我想没有官方的api可以通过在Google Play中获取包名来获取应用程序的详细信息。有官方的api吗?
巴赫曼

Google是否为每个用户保留@androiddeveloper的名称?
巴赫曼

是。如果您打开Play商店应用,请转到导航抽屉,然后转到“我的应用和游戏”。您将在此处看到曾经从那里安装的所有应用程序,而不仅仅是当前已安装的那些应用程序。根据Google的说法,它(或至少看起来好像他们说的)被允许使用以下API:issuetracker.google.com/issues/79195087。或者,与我交谈的人都不知道那里发生了什么...
android开发人员

-2

我有两个资源供您考虑,但首先,总之,不。GOOGLE没有api可以让您做自己想做的事,因为这些指标没有存储在手机中,它们在google play store伺服器上,并且google没有用于play store的官方api。但是,您可以从以下两个站点收集一些信息:

https://www.quora.com/Is-there-an-API-for-the-Google-Play-Store 在此处输入链接描述

/android/162146/how-to-see-all-the-apps-i-have-downloaded-from-google-play-store

这足以了解如何完成此任务。

首先,该帐户仅可引用一个帐户已下载哪些应用程序的列表。这可以通过Play商店完成。由于您的应用程序将安装在该用户的电话上,因此这无关紧要...您正在使用。

其次,您需要为GOOGLE PLAY STORE构建的第三方API,那里有一些API,请检查第一个链接。

使用您选择的api,您将向Play商店发送一个get请求,作为回报,在大多数情况下,您应该收到一个要反序列化的json对象。

反序列化对象,您将获得列表。您将获得哪个列表将取决于您使用的端点,但这应该由API本身解释。

祝好运!


在该处的所有链接中,我没有看到一个能获取当前用户已安装应用程序列表的列表。他们甚至没有登录阶段。它们都收集有关应用程序的常规信息,无论用户是否已安装它们。
android开发人员
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.