android billing:4.0.0 - queryPurchases(INAPP) 和 purchase.getSku()

Ric*_*Joe 26 java android in-app-purchase in-app-billing

我刷新到 android billing 版本 4 和 2 的东西不再工作了。

首先我有这个:

else if (billingResult.getResponseCode() == BillingClient.BillingResponseCode.ITEM_ALREADY_OWNED) {
            Purchase.PurchasesResult queryAlreadyPurchasesResult = billingClient.queryPurchases(INAPP); // deprecated
            List<Purchase> alreadyPurchases = queryAlreadyPurchasesResult.getPurchasesList();
            if(alreadyPurchases!=null){
                handlePurchases(alreadyPurchases);
            }
        }
Run Code Online (Sandbox Code Playgroud)

不推荐使用 queryPurchases。

其次我有这个:

void handlePurchases(List<Purchase>  purchases) {
    for(Purchase purchase:purchases) {
        //if item is purchased
        if (PRODUCT_ID.equals(purchase.getSku()) && purchase.getPurchaseState() == Purchase.PurchaseState.PURCHASED)
        {
            if (!verifyValidSignature(purchase.getOriginalJson(), purchase.getSignature())) {
                // Invalid purchase
                // show error to user
                Toast.makeText(getApplicationContext(), R.string.plus_error, Toast.LENGTH_SHORT).show();
                return;
            }
Run Code Online (Sandbox Code Playgroud)

getSku() 正在工作,但现在它被标记为 Cannot resolve method getSku() in Purchase

任何想法如何解决这个问题?


从文档:

Summary of changes
Added BillingClient.queryPurchasesAsync() to replace BillingClient.queryPurchases() which will be removed in a future release.

Added Purchase#getSkus() and PurchaseHistoryRecord#getSkus(). These replace Purchase#getSku and PurchaseHistoryRecord#getSku which have been removed.
Run Code Online (Sandbox Code Playgroud)

但我不知道如何在我上面的代码中应用这个新命令。

如果我将 getSku 更改为 getSkus,我的 ifif (PRODUCT_ID.equals(purchase.getSkus()) && purchase.getPurchaseState() == Purchase.PurchaseState.PURCHASED)会说它总是错误的。而且我不知道如何使用 queryPurchasesAsync(),现在需要 2 个参数。

谢谢。

Van*_*den 19

正如我之前在评论中提到的,您正在将 String 与 List 对象进行比较,但正如 chitgoks 所说的那样,ArrayList<String>而不是List<String>我假设的那样。我不确定您是否会得到不止一个 sku 字符串(因为您可能不会同时订购多个东西?)但是要么仔细查看它们以确保或抓住机会将 PRODUCT_ID 与仅进行比较购买.getSkus().get(0)。

新的异步购买调用似乎只需要很小的更改。

旧方法的示例:

Purchase.PurchasesResult result = billingClient.queryPurchases(BillingClient.SkuType.SUBS);
doSomethingWithPurchaseList(result.getPurchasesList());
Run Code Online (Sandbox Code Playgroud)

这将是做同样事情的新方法:

billingClient.queryPurchasesAsync(BillingClient.SkuType.SUBS, new PurchasesResponseListener() {
        @Override
        public void onQueryPurchasesResponse(@NonNull BillingResult billingResult, @NonNull List<Purchase> list) {
            doSomethingWithPurchaseList(list);
        }
    });
Run Code Online (Sandbox Code Playgroud)

  • 随着开发人员尝试将计费升级到新版本 4.0.0,我预计这篇文章会引起更多关注。新文档像往常一样不完整,因此我们需要自行更新缺失的详细信息。 (13认同)
  • 当然是@Androidcoder!我认为所有的开发者都面临着同样的情况。 (2认同)
  • 由于 Android Studio 似乎没有将上述 Java 代码片段转换为 Kotlin 代码,因此在 Kotlin 中,新方式将类似于 `billingClient.queryPurchasesAsync(BillingClient.SkuType.SUBS, PurchasingResponseListener { billingResult, list -&gt; doSomethingWithPurchaseList(list) })` (2认同)

And*_*der 16

与 billing 4.0.0 一样,自 billing 5.0.0 起,文档“将 Google Play Billing Library 集成到您的应用程序中”存在错误且不完整,尽管可能不像一年前那么糟糕。现在我们正在处理 ProductDetails 而不是 SkuDetails 对象。另请注意文档中的以下更正:

QueryProductDetailsParams queryProductDetailsParams =
QueryProductDetailsParams.newBuilder()
    .setProductList(
        ImmutableList.of(
      
Run Code Online (Sandbox Code Playgroud)

应该:

QueryProductDetailsParams queryProductDetailsParams =
QueryProductDetailsParams.newBuilder()
    .setProductList(
        ImmutableList.from,(//'from' instead of 'of'      
Run Code Online (Sandbox Code Playgroud)

...

BillingFlowParams billingFlowParams =
BillingFlowParams.newBuilder()
    .setProductDetailsParamsList(
        ImmuableList.of(
          
Run Code Online (Sandbox Code Playgroud)

应该:

BillingFlowParams billingFlowParams =
BillingFlowParams.newBuilder()
    .setProductDetailsParamsList(
        ImmutableList.from(//'ImmutableList.from' instead of 'ImmuableList.of'
           
Run Code Online (Sandbox Code Playgroud)

...

billingClient.queryProductDetailsAsync(
queryProductDetailsParams,
new ProductDetailsResponseListener() {
    public void onProductDetailsResponse(BillingResult billingResult,
            List<ProductDetails> productDetailsList) () {
       
Run Code Online (Sandbox Code Playgroud)

应该:

billingClient.queryProductDetailsAsync(
queryProductDetailsParams,
new ProductDetailsResponseListener() {
    public void onProductDetailsResponse(BillingResult billingResult,
            List<ProductDetails> productDetailsList) {//no extra parens
       
Run Code Online (Sandbox Code Playgroud)

...

//Incomplete
billingClient.queryPurchasesAsync(
    QueryPurchasesParams.newBuilder()
        .setProductType(ProductType.SUBS)
        .build(),
    /* purchaseResponseListener= */ this
);

// PurchaseResponseListener implementation.
public void onQueryPurchasesResponse(BillingResult billingResult, List<Purchase> purchases) {
    // check BillingResult
    // process returned purchase list, e.g. display the plans user owns
}
Run Code Online (Sandbox Code Playgroud)

恕我直言,文档中最令人失望的部分。它只是提供线索,而“this”具有误导性,您将收到一条错误消息,建议将purchaseResponseListener 转换为它。实际的实现是:

billingClient.queryPurchasesAsync(
                QueryPurchasesParams.newBuilder()
                        .setProductType(BillingClient.ProductType.INAPP)//or SUBS
                        .build(),
                new PurchasesResponseListener() {
                    @Override
                    public void onQueryPurchasesResponse(BillingResult billingResult, List<Purchase> purchases) {
                         if (billingResult.getResponseCode() == BillingClient.BillingResponseCode.OK&&purchases != null) {
                            for (Purchase purchase : purchases) {
                                handlePurchase(purchase);
                            }
                             }
                    }
                }
        );
Run Code Online (Sandbox Code Playgroud)

在您的代码中,“purchase.getSku”不会被识别,因为该方法是“purchase.getSkus()”。无论如何,现在它已经贬值了,您可以使用以下方法来提取产品 ID (sku)。尽管用户现在可以通过一次购买购买多种产品,但您的购买对象可能只有一种产品:

purchase.getProducts().get(0)
Run Code Online (Sandbox Code Playgroud)

  • 这正是我从 V3 转换到 V5 所需要的。十分感谢你的帮助。 (2认同)
  • 您知道什么情况下一次购买多件商品吗? (2认同)

小智 15

getSkus 返回一个 ArrayList。请使用“包含”如下。

purchase.getSkus().contains(YOUR_PRODUCT_ID.toLowerCase())

  • 哦天哪...谷歌一如既往,一切都变得越来越复杂...... (6认同)
  • 为什么我们需要使用.toLowerCase()? (4认同)