【问题标题】:What result codes can be returned from BillingClient.launchBillingFlow()?BillingClient.launchBillingFlow() 可以返回哪些结果代码?
【发布时间】:2021-10-19 19:36:28
【问题描述】:

我正在使用 Google 的帐单库 4。BillingClient.launchBillingFlow 的文档说:

启动应用内购买或订阅的计费流程。

它将显示 Google Play 购买屏幕。结果将通过BillingClient.Builder.setListener(PurchasesUpdatedListener)设置的PurchasesUpdatedListener接口实现传递。

PurchasesUpdatedListener 被传递了一个包含响应代码的 BillingResult 对象。但是,launchBillingFlow 方法也返回一个BillingResult 对象。我的问题是,我需要在每个地方处理哪些响应代码?

我们可以说,文档不够清晰,而且似乎也有误。对于launchBillingFlow,它表示如果用户取消购买流程,该方法将返回带有BillingResponseCode.BILLING_CANCELED 代码的BillingResult。但是,我的实验表明,代码实际上是通过调用 PurchasesUpdatedListener.onPurchasesUpdated 传递的。

不幸的是,BillingClient 的源代码不可用,但我确实反编译了库模块。据我所知,对launchBillingFlow 的调用可以返回以下结果代码:

  • OK - 当流程成功启动时(并且向用户显示 Google 的购买屏幕)。
  • SERVICE_DISCONNECTED - 当BillingClient 当前未连接到设备上的 Google Play 时。
  • SERVICE_TIMEOUT - 如果在尝试启动流程期间连接中断。 (我想我在某处读到过,如果在后台更新 Google Play,就会发生这种情况。)
  • FEATURE_NOT_SUPPORTED - 在BillingFlowParamsBillingClient 对象的当前配置不匹配的各种情况下。

在反编译的代码中似乎还有一个地方,来自 Google Play 计费服务的某些错误响应被捕获并返回到这里。有谁知道调用launchBillingFlow 可以返回哪些其他响应代码?

【问题讨论】:

  • 其实调用launchBillingFlow时可以忽略返回结果,这里的结果OK表示app开始购买成功。您应该关注传递给onPurchasesUpdated 方法的结果。这是用户购买或取消或已拥有该项目时的最终结果...
  • @CôngHải - 简单地忽略它似乎是不对的。从反编译的代码中可以清楚地看出,购买流程可能无法启动,我的代码应该知道何时发生这种情况,并根据失败的原因做出不同的反应。
  • 奇怪的是,launchBillingFlow 不是模态的。因此 CANCELED 返回值没有意义。用户可能会看到对话框并按下后退按钮,但在此之前已经从 launchBillingFlow() 返回。我很难理解如何将这个新版本的计费库合并到我的应用程序中——因为对话框不是模态的,你无法知道用户是按下后退按钮还是继续。您不能从 onPurchasesUpdated 执行 UI 更改(也不知道它是否被取消)。
  • 忽略我说的最后一部分。 USER_CANCELED 被发送到 onPurchasesUpdated() 并且您可以从那里处理 UI。
  • @cbn - 是的,这就是我的问题的重点。 launchBillingFlow返回时需要处理哪些结果代码,onPurchasesUpdated()中需要处理哪些代码?显然有一些重叠,但显然也有一些代码对每个上下文都是唯一的。文档只是列出了所有可能的返回码,没有区分哪些应该在哪里处理。

标签: android android-billing play-billing-library


【解决方案1】:

根据我的经验,您可以处理如下示例中提到的结果:-

 this.mBillingClient = BillingClient.newBuilder(this).setListener(new PurchasesUpdatedListener() {
    @Override
    public void onPurchasesUpdated(BillingResult billingResult, @Nullable List<Purchase> list) {
      if (billingResult.getResponseCode() == BillingClient.BillingResponseCode.OK && list != null) {
        for (Purchase purchase : list) {

          if (purchase.getPurchaseState() == Purchase.PurchaseState.PURCHASED) {
            addPurchaseDetails(purchase);
            handlePurchase(purchase);

          }
        }
      } else if (billingResult.getResponseCode() == BillingClient.BillingResponseCode.USER_CANCELED) {
        Log.v("purchase", billingResult.getDebugMessage());
      }

意味着您必须检查:- billingResult.getResponseCode() == BillingClient.BillingResponseCode.OK && list != null

并从列表中获取购买并根据您的需要处理购买。

    for (Purchase purchase : list) {
       }

Also find the errors below :-  

public @interface BillingResponseCode {
        int SERVICE_TIMEOUT = -3;
        int FEATURE_NOT_SUPPORTED = -2;
        int SERVICE_DISCONNECTED = -1;
        int OK = 0;
        int USER_CANCELED = 1;
        int SERVICE_UNAVAILABLE = 2;
        int BILLING_UNAVAILABLE = 3;
        int ITEM_UNAVAILABLE = 4;
        int DEVELOPER_ERROR = 5;
        int ERROR = 6;
        int ITEM_ALREADY_OWNED = 7;
        int ITEM_NOT_OWNED = 8;
    }

【讨论】:

  • 是的,我当然可以处理一个包罗万象的else 分支中的所有错误。但是,我的问题是在每种情况下会出现哪些错误(启动计费流程或处理计费流程的结果)。
  • 您可以检查错误,例如 (billingResult.getResponseCode() == BillingClient.BillingResponseCode.XXX)。 XXX 将是公开的 @interface BillingResponseCode { int SERVICE_TIMEOUT = -3; int FEATURE_NOT_SUPPORTED = -2; int SERVICE_DISCONNECTED = -1;整数OK = 0; int USER_CANCELED = 1; int SERVICE_UNAVAILABLE = 2; int BILLING_UNAVAILABLE = 3; int ITEM_UNAVAILABLE = 4; int DEVELOPER_ERROR = 5;整数错误 = 6; int ITEM_ALREADY_OWNED = 7; int ITEM_NOT_OWNED = 8; }
  • 请再次阅读我的问题。我知道所有可能的值。但是,并非所有值都可以在所有位置返回。例如,USER_CANCELED 逻辑上不能从launchBillingFlow() 返回,因为如果该调用失败,用户甚至没有看到计费屏幕有机会取消。问题不在于可能的错误代码是什么;而是,哪些错误可能会从哪些 API 调用返回?
【解决方案2】:

首先,感谢您提出的好问题。据我研究,下面列出的值是可用的。

BillingClient.BillingResponseCode // all codes

int BILLING_UNAVAILABLE 不支持 Billing API 版本 要求的类型。

int DEVELOPER_ERROR 提供给 API 的参数无效。

int ERROR API 操作期间出现致命错误。

int FEATURE_NOT_SUPPORTED Play 不支持请求的功能 存储在当前设备上。

int ITEM_ALREADY_OWNED 购买失败,因为项目已经 拥有。

int ITEM_NOT_OWNED 消费失败,因为项目不属于自己。

int ITEM_UNAVAILABLE 请求的产品无法购买。

int OK成功。

int SERVICE_DISCONNECTED Play 商店服务现在未连接 - 潜在的瞬态。

int SERVICE_TIMEOUT 请求之前已经达到最大超时 Google Play 做出回应。

int SERVICE_UNAVAILABLE网络连接中断。

int USER_CANCELED 用户按下或取消了一个对话框。

launchBillingFlow // return values for

启动计费流程操作的结果。 BillingClient.BillingResponseCode.ITEM_ALREADY_OWNED 如果用户已经拥有正在购买的物品, BillingClient.BillingResponseCode.ITEM_UNAVAILABLE 如果无法购买该物品,并且 BillingClient.BillingResponseCode.USER_CANCELED 如果用户关闭了购买流程。

更新答案

调用时可能的返回值是什么 launchBillingFlow() 失败

  • ITEM_ALREADY_OWNED
  • ITEM_UNAVAILABLE
  • USER_CANCELED

调用 onPurchasesUpdated() 时可能的值是什么(在 流程完成)。

  • 好的
  • ITEM_UNAVAILABLE
  • ITEM_ALREADY_OWNED
  • USER_CANCELED
  • 错误启动BillingFlow错误

【讨论】:

  • 您刚刚列出了BillingResponseCode 的所有可能值。然而,这不是我的问题。问题是:当调用launchBillingFlow() 失败时可能的返回值是什么,当调用onPurchasesUpdated() 时可能的值是什么(在流程完成时)。例如,从逻辑上讲,USER_CANCELED 不可能从 launchBillingFlow() 返回,因为如果调用失败,用户甚至没有机会取消购买。
  • 我更新了我的答案。我建议你专门检查 ERROR 状态,因为无论如何都会调用回调。
  • 请解释您修改后的答案的来源,我认为这是不对的。例如,USER_CANCELED 怎么可能从launchBillingFlow() 返回?如果呼叫失败,则计费流程尚未呈现给用户,用户没有机会取消。
猜你喜欢
  • 1970-01-01
  • 2019-04-20
  • 1970-01-01
  • 2014-11-01
  • 2017-07-16
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多