android - 如何在新的 Google 应用内购买中使用购买历史记录处理购买状态

标签 android in-app-purchase in-app-billing play-billing-library

我正在尝试创建一个恢复购买系统。我希望,用户无论登录哪个设备都可以访问其购买的产品。因此,我在应用程序启动时使用“queryPurchaseHistoryAsync()”方法。我的问题从这里开始。

随着 Google 的新实现,与文档相反,queryPurchaseHistoryAsync() 参数发生了变化。现在,它采用PurchaseHistoryRecord 对象列表作为参数,而不是Purchase 对象列表。

Android studio无法解析文档中所述的方法。使用新的 queryPurchaseHistoryAsync() ,我无论如何都找不到检查购买状态的方法。(如果已购买、取消或待处理)。我可以使用“purchase.getPurchaseState()”方法来处理购买对象。

queryPurchaseHistoryAsync() 的文档

billingClient.queryPurchaseHistoryAsync(SkuType.INAPP,
                                         new PurchaseHistoryResponseListener() {
    @Override
    public void onPurchaseHistoryResponse(BillingResult billingResult,
                                          List<Purchase> purchasesList) {
        if (billingResult.getResponseCode() == BillingResponse.OK
                && purchasesList != null) {
            for (Purchase purchase : purchasesList) {
                // Process the result.
            }
         }
    }
});

我的实现

implementation 'com.android.billingclient:billing:2.0.3'

我的应用程序中的 queryPurchaseHistoryAsync() 方法

billingClient.queryPurchaseHistoryAsync(BillingClient.SkuType.INAPP,
                new PurchaseHistoryResponseListener() {
                    @Override
                    public void onPurchaseHistoryResponse(BillingResult billingResult, List<PurchaseHistoryRecord> purchaseHistoryRecordList) {

                        if (billingResult.getResponseCode() == BillingClient.BillingResponseCode.OK
                                && purchaseHistoryRecordList != null) {

                            for (PurchaseHistoryRecord purchaseHistoryRecord : purchaseHistoryRecordList) {

                                HandleOldGetting(purchaseHistoryRecord.getSku());
                             }
                        }
                    }

Google 版本说明(05-2019):

“为了最大限度地减少困惑,queryPurchaseHistoryAsync() 现在返回一个 PurchaseHistoryRecord 对象而不是 Purchasing 对象。 PurchaseHistoryRecord 对象与Purchase 对象相同,只是它仅反射(reflect)queryPurchaseHistoryAsync() 返回的值,并且不包含autoRenewing、orderId 和packageName 字段。请注意,返回的数据没有任何变化 — queryPurchaseHistoryAsync() 返回与之前相同的数据。”

但是发行说明和文档都没有说明如何使用PurchaseHistoryRecord 检查购买状态。

感谢您阅读本文,如有任何帮助,我们将不胜感激。

最佳答案

到目前为止,我一直在使用 queryPurchases() 自动恢复购买,因为它不需要任何网络。

正在为所有设备更新与帐户相关的 Google Play 应用缓存。在许多情况下,您不需要调用 queryPurchaseHistoryAsync 来进行恢复。

正如@bospehre 评论中所述。它有一个缺点,因为它依赖于缓存。所以我们仍然需要检查购买情况并通过网络调用恢复。

对于queryPurchaseHistory异步调用,我们可以获得购买sku和 token 。如果您按照 Google 的建议使用服务器来保存订阅数据。您可以通过您的服务器查看该订阅的情况。

这里是恢复用户最新订阅的示例。

billingManager.billingClient.queryPurchaseHistoryAsync(BillingClient.SkuType.SUBS) { billingResult, purchaseHistoryRecords ->
      
           if (purchaseHistoryRecords != null) {
                var activePurchaseRecord : PurchaseHistoryRecord? = null
                if (purchaseHistoryRecords.size > 0) {
    
    // Get the latest subscription. It may differ for developer needs.
    
                    for (purchaseHistoryRecord in purchaseHistoryRecords) {
                        Log.d(billingLogs, "Purchase History Record : $purchaseHistoryRecord")
        
                        if (billingResult.responseCode == BillingClient.BillingResponseCode.OK) {
                            if (subSkuListHelper.getSkuList().contains(purchaseHistoryRecord.sku)
                            ) {
        
                                if (activePurchaseRecord == null) {
                                    activePurchaseRecord = purchaseHistoryRecord
                                } else {
                                    if (purchaseHistoryRecord.purchaseTime > activePurchaseRecord.purchaseTime) {
                                        activePurchaseRecord = purchaseHistoryRecord
                                    }
                                }
        
                            }
                        }
        
                    }
                    
        
                        Toast.makeText(
                            this,
                            "Subscription Purchases found, Checking validity...",
                            Toast.LENGTH_SHORT
                        ).show()
        
        
        // Make a network call with sku and purchaseToken to get subscription info
        
        //Subscription Data Fetch is a class that handling the networking
                        activePurchaseRecord?.let { SubscriptionDataFetch(
                            this,
                            billingManager.billingClient
                        )
                            .executeNetWorkCall(
                                getString(R.string.ubscription_check_endpoint),
                                it.sku,
                                it.purchaseToken
                            )
                        }
                    
                }
                else {
                    Log.d(billingLogs, "Purchase History Record not found size 0") }
        
            }
            else {
                Toast.makeText(
                    this,
                    "Purchase not found",
                    Toast.LENGTH_SHORT
                ).show()
        
                Log.d(billingLogs, "Purchase History Record not found null")
            }
}

关于android - 如何在新的 Google 应用内购买中使用购买历史记录处理购买状态,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/58038764/

相关文章:

android - 当我尝试创建图像 Assets 时,Android Studio 中不存在文件 Logo.png

iphone - 将免费应用升级为通过应用内购买付费?

Android应用内购买如何获取订阅的到期日期

java - 如何从 Google 电子钱包中删除测试交易?

java - 是否可以通过单个产品 ID 获取单个商品 SKU 详细信息? (Android、Iab 助手)

java - 如何修复 API 版本 23 的 androidx 中的 FloatingActionButton 膨胀错误?

java - 获取数组中选中的复选框数据

android - 将现有 fragment 置于最前面

iphone - 正在处理 iPhone 上的应用内购买(或恢复购买)时显示进度指示器

Android In app Billing V3 不工作