You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Google Play Billing库PurchasesUpdatedListener返回空购买列表求助

恢复购买功能实现及ITEM_ALREADY_OWNED分支空列表问题修复

1. 核心:获取已购商品列表的方法

要实现恢复购买,直接调用BillingClient的queryPurchasesAsync方法即可,无需依赖PurchasesUpdatedListener回调。示例代码如下:

// 确保BillingClient已初始化并处于连接状态
val queryParams = QueryPurchasesParams.newBuilder()
    .setProductType(BillingClient.ProductType.INAPP) // 非消耗型/一次性商品用此参数,订阅商品用SUBS
    .build()

billingClient.queryPurchasesAsync(queryParams) { billingResult, purchases ->
    if (billingResult.responseCode == BillingClient.BillingResponseCode.OK && !purchases.isEmpty()) {
        purchases.forEach { purchase ->
            handlePurchase(purchase) // 调用你的处理逻辑
        }
    } else {
        Log.e("Billing", "恢复购买失败: ${billingResult.debugMessage ?: "未知错误"}")
    }
}

2. 修复ITEM_ALREADY_OWNED分支空列表问题

当收到ITEM_ALREADY_OWNED响应但purchases为空时,直接触发上述恢复购买查询,获取已购信息后再执行handlePurchase:

// PurchasesUpdatedListener回调逻辑
override fun onPurchasesUpdated(billingResult: BillingResult, purchases: MutableList<Purchase>?) {
    when (billingResult.responseCode) {
        BillingClient.BillingResponseCode.OK -> {
            purchases?.takeIf { it.isNotEmpty() }?.forEach { handlePurchase(it) }
        }
        BillingClient.BillingResponseCode.ITEM_ALREADY_OWNED -> {
            // 主动查询已购列表
            val queryParams = QueryPurchasesParams.newBuilder()
                .setProductType(BillingClient.ProductType.INAPP)
                .build()
            billingClient.queryPurchasesAsync(queryParams) { result, ownedPurchases ->
                if (result.responseCode == BillingClient.BillingResponseCode.OK && !ownedPurchases.isEmpty()) {
                    ownedPurchases.forEach { handlePurchase(it) }
                }
            }
        }
        BillingClient.BillingResponseCode.USER_CANCELED -> {
            // 保留你的取消提示逻辑
            Toast.makeText(context, "用户取消购买", Toast.LENGTH_SHORT).show()
        }
        else -> {
            val errorMsg = billingResult?.debugMessage ?: "未知错误"
            Log.e("Billing", "购买操作失败: $errorMsg")
        }
    }
}

3. 绑定恢复购买按钮点击事件

在恢复按钮的点击回调中,直接调用恢复购买逻辑:

restorePurchaseBtn.setOnClickListener {
    val queryParams = QueryPurchasesParams.newBuilder()
        .setProductType(BillingClient.ProductType.INAPP)
        .build()
    billingClient.queryPurchasesAsync(queryParams) { billingResult, purchases ->
        when (billingResult.responseCode) {
            BillingClient.BillingResponseCode.OK -> {
                if (purchases.isEmpty()) {
                    Toast.makeText(context, "暂无可恢复的购买记录", Toast.LENGTH_SHORT).show()
                } else {
                    purchases.forEach { handlePurchase(it) }
                    Toast.makeText(context, "购买记录已恢复", Toast.LENGTH_SHORT).show()
                }
            }
            else -> {
                Toast.makeText(context, "恢复失败: ${billingResult.debugMessage}", Toast.LENGTH_SHORT).show()
            }
        }
    }
}

关键注意点

  • 调用queryPurchasesAsync前,务必通过billingClient.isReady确认客户端已连接。
  • 若应用包含订阅商品,需单独调用setProductType(BillingClient.ProductType.SUBS)查询订阅列表。
  • handlePurchase中必须加入购买签名验证逻辑,防止非法数据篡改。

内容的提问来源于stack exchange,提问作者sagar raval

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.02 19:12:56