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

Android Billing 6:initiatePurchase函数执行后无后续响应求助

问题排查与修复方案

核心问题:商品类型不匹配

你开发的是消耗型商品,但代码里查询时误用了订阅类型BillingClient.ProductType.SUBS,这会导致系统查询不到对应的消耗型商品,后续购买流程完全无法触发。消耗型/非消耗型商品对应的正确类型是BillingClient.ProductType.INAPP,这是最关键的错误点。

其他潜在问题与修复建议

  • 修正商品类型
    将查询商品的类型替换为INAPP:

    QueryProductDetailsParams.Product.newBuilder()
        .setProductId(productId)
        .setProductType(BillingClient.ProductType.INAPP) // 替换SUBS为INAPP
        .build()
    
  • 确认BillingClient初始化状态
    确保调用initiatePurchase前,billingClient已经完成初始化并成功连接。检查是否调用了startConnection,且在onBillingSetupFinished回调确认连接成功后,才允许用户点击按钮触发购买。

  • 主线程更新UI
    queryProductDetailsAsync的回调运行在后台线程,直接更新TextView可能引发异常,需要切换到主线程操作:

    runOnUiThread {
        when (productId) {
            PRODUCT_ID_1 -> findViewById<TextView>(R.id.price1).text = price
            PRODUCT_ID_2 -> findViewById<TextView>(R.id.price2).text = price
            PRODUCT_ID_3 -> findViewById<TextView>(R.id.price3).text = price
            PRODUCT_ID_4 -> findViewById<TextView>(R.id.price4).text = price
        }
    }
    
  • 完善错误提示与日志
    后台线程中的Toast可能无法正常显示,建议将所有Toast操作放在主线程,同时添加日志方便调试:

    runOnUiThread {
        Toast.makeText(applicationContext, "查询失败: ${billingResult.debugMessage}", Toast.LENGTH_SHORT).show()
    }
    Log.e("BillingError", "响应码: ${billingResult.responseCode},错误信息: ${billingResult.debugMessage}")
    
  • 核对商品ID一致性
    确认代码中PRODUCT_ID_1等常量,与Google Play Console中配置的消耗型商品ID完全一致,大小写、拼写不能有任何差异。

修复后的核心代码片段

private fun initiatePurchase(productId: String) {
    Toast.makeText(applicationContext, "initiatePurchase(productId: String)", Toast.LENGTH_SHORT).show()

    val productList = listOf(
        QueryProductDetailsParams.Product.newBuilder()
            .setProductId(productId)
            .setProductType(BillingClient.ProductType.INAPP) // 修正为INAPP类型
            .build()
    )

    val params = QueryProductDetailsParams.newBuilder().setProductList(productList).build()

    billingClient.queryProductDetailsAsync(params) { billingResult, productDetailsList ->
        runOnUiThread { // 切换到主线程处理UI操作
            if (billingResult.responseCode == BillingClient.BillingResponseCode.OK) {
                if (productDetailsList.isNotEmpty()) {
                    val productDetails = productDetailsList[0]
                    val price = productDetails.oneTimePurchaseOfferDetails?.formattedPrice

                    when (productId) {
                        PRODUCT_ID_1 -> findViewById<TextView>(R.id.price1).text = price
                        PRODUCT_ID_2 -> findViewById<TextView>(R.id.price2).text = price
                        PRODUCT_ID_3 -> findViewById<TextView>(R.id.price3).text = price
                        PRODUCT_ID_4 -> findViewById<TextView>(R.id.price4).text = price
                    }

                    val productDetailsParamsList = listOf(
                        BillingFlowParams.ProductDetailsParams.newBuilder()
                            .setProductDetails(productDetails)
                            .build()
                    )

                    val billingFlowParams = BillingFlowParams.newBuilder()
                        .setProductDetailsParamsList(productDetailsParamsList)
                        .build()

                    billingClient.launchBillingFlow(this@Purchase, billingFlowParams)
                } else {
                    Toast.makeText(applicationContext, "未找到对应商品", Toast.LENGTH_SHORT).show()
                }
            } else {
                val errorMsg = "查询失败: ${billingResult.debugMessage}"
                Toast.makeText(applicationContext, errorMsg, Toast.LENGTH_SHORT).show()
                Log.e("BillingDebug", errorMsg)
            }
        }
    }
}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.11 11:38:11