调用queryProductDetailsAsync无法获取产品详情问题求助
原因分析与解决指导
核心原因及其他潜在问题
BillingClient未完成连接就执行查询
从日志时序可以明确看到:No product matches found先于MYAPP-TEST---SUCCESS打印,说明你在调用billingClient.startConnection后,立刻执行了queryProductDetailsAsync——此时BillingClient还未与Google Billing服务建立有效连接,查询请求直接失败。Product ID拼写错误
代码中所有产品ID写成了poroductidX(多了一个o),与Google Play控制台配置的真实ID必然不匹配,这是导致产品找不到的直接诱因之一。其他可能的隐藏问题
- 应用处于草稿状态:未发布到封闭测试/开放测试/正式轨道的应用,测试设备无法获取付费产品信息。
- 测试账号未配置:未将测试设备的Google账号添加到Play控制台的许可测试列表中。
- 产品类型不匹配:代码中使用
SUBS(订阅类型),若控制台配置的是一次性付费产品(INAPP),也会匹配失败。
分步解决指导
1. 将查询逻辑移至连接成功回调内
只有当BillingClient连接成功后,才能发起产品查询请求,修改代码如下:
myLog("MYAPP-TEST---1") val purchasesUpdatedListener = PurchasesUpdatedListener { billingResult, purchases -> if (billingResult.responseCode == BillingClient.BillingResponseCode.OK && purchases != null ) { for (purchase in purchases) { myLog("MYAPP-TEST---处理购买: ${purchase.products}") } } else if (billingResult.responseCode == BillingClient.BillingResponseCode.USER_CANCELED ) { myLog("MYAPP-TEST---用户取消购买") } else { myLog("MYAPP-TEST---购买错误: ${billingResult.debugMessage}") } } var billingClient = BillingClient.newBuilder(this) .setListener(purchasesUpdatedListener) .enablePendingPurchases() .build() billingClient.startConnection(object : BillingClientStateListener { override fun onBillingSetupFinished(billingResult: BillingResult) { if (billingResult.responseCode == BillingClient.BillingResponseCode.OK) { myLog("MYAPP-TEST---SUCCESS") // 连接成功后才执行产品查询 queryProductDetails() } else { myLog("MYAPP-TEST---连接失败: ${billingResult.debugMessage}") } } override fun onBillingServiceDisconnected() { myLog("MYAPP-TEST---DISCONNECTED") // 断开连接后尝试重连 billingClient.startConnection(this) } }) // 封装产品查询逻辑 private fun queryProductDetails() { val productList = arrayListOf( Product.newBuilder() .setProductId("productid1") // 修正拼写错误:poroduct → product .setProductType(BillingClient.ProductType.SUBS) .build(), Product.newBuilder() .setProductId("productid2") .setProductType(BillingClient.ProductType.SUBS) .build(), Product.newBuilder() .setProductId("productid3") .setProductType(BillingClient.ProductType.SUBS) .build(), Product.newBuilder() .setProductId("productid4") .setProductType(BillingClient.ProductType.SUBS) .build() ) val queryParams = QueryProductDetailsParams.newBuilder() .setProductList(productList) .build() billingClient.queryProductDetailsAsync(queryParams) { billingResult, skuDetailsList -> if (billingResult.responseCode == BillingClient.BillingResponseCode.OK) { if (skuDetailsList.isNotEmpty()) { skuDetailsList.forEach { productDet -> myLog("MYAPP-TEST----找到产品: ${productDet.name}") myLog("产品ID: ${productDet.productId}") } } else { myLog("MYAPP-TEST---No product matches found") } } else { myLog("MYAPP-TEST---查询失败: ${billingResult.debugMessage}") } } }
2. 修正Product ID拼写
确保代码中的productidX与Google Play控制台配置的产品ID完全一致(包括大小写、特殊字符)。
3. 验证应用与产品发布状态
- 应用必须发布到封闭测试/开放测试/正式轨道,草稿状态无法被测试设备访问。
- 控制台中的产品需设置为激活状态,并关联到对应应用版本。
4. 配置测试账号
- 在Play控制台的「测试 > 许可测试」中添加测试设备的Google账号。
- 测试设备登录该账号后,清除Play商店缓存或重启设备。
5. 确认产品类型匹配
若控制台配置的是一次性付费产品,需将代码中的BillingClient.ProductType.SUBS改为BillingClient.ProductType.INAPP。
内容的提问来源于stack exchange,提问作者Antoine Gallet
相关产品推荐
相关产品推荐

