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
相关产品推荐
相关产品推荐

