Android使用BillingClient库如何查询用户已购买的内购商品
Google Play Billing 3.0.1 购买记录查询为空问题解决
问题核心原因
你现有代码的核心问题是未等待BillingClient连接完成就直接发起查询请求,同时没有对返回的BillingResult状态做校验,直接操作可能为null的列表。
正确实现逻辑
首先明确场景适配:你需要检测用户是否已购买有效内购商品,优先使用queryPurchases()方法,该方法读取本地缓存,无需联网,返回当前用户名下所有未消费的有效内购/订阅记录,更适合启动时的校验场景。queryPurchaseHistoryAsync多用于拉取历史购买记录(含已消费/已过期的记录),需要联网,可用作后续对账补充。
完整实现步骤
- 第一步:初始化BillingClient并建立连接
- 第二步:连接成功后先查询本地有效购买记录
- 第三步:对返回结果做状态校验,避免空指针
// 1. 初始化BillingClient mBillingClient = BillingClient.newBuilder(getApplicationContext()) .enablePendingPurchases() .setListener(this) .build(); // 2. 先建立连接,连接成功后再执行查询 mBillingClient.startConnection(new BillingClientStateListener() { @Override public void onBillingSetupFinished(@NonNull BillingResult billingResult) { if (billingResult.getResponseCode() == BillingClient.BillingResponseCode.OK) { // 连接成功,先查询本地缓存的有效购买记录 Purchase.PurchasesResult purchasesResult = mBillingClient.queryPurchases(BillingClient.SkuType.INAPP); if (purchasesResult.getResponseCode() == BillingClient.BillingResponseCode.OK) { List<Purchase> purchaseList = purchasesResult.getPurchasesList(); if (purchaseList != null && !purchaseList.isEmpty()) { // 遍历purchaseList,匹配你要校验的商品SKU,确认购买状态 for (Purchase purchase : purchaseList) { if (purchase.getSku().equals("你的商品SKU") && purchase.getPurchaseState() == Purchase.PurchaseState.PURCHASED && !purchase.isAcknowledged()) { // 注意未确认的购买需要先调用acknowledgePurchase确认,再判定为已购买 // 用户已购买该商品,做对应逻辑处理 } } } } // 如果需要拉取完整历史购买记录,再调用queryPurchaseHistoryAsync mBillingClient.queryPurchaseHistoryAsync(BillingClient.SkuType.INAPP, new PurchaseHistoryResponseListener() { @Override public void onPurchaseHistoryResponse(@NonNull BillingResult billingResult, @Nullable List<PurchaseHistoryRecord> list) { // 先校验响应状态,再操作列表 if (billingResult.getResponseCode() == BillingClient.BillingResponseCode.OK && list != null) { // 处理历史记录逻辑 list.size(); } } }); } } @Override public void onBillingServiceDisconnected() { // 连接断开可触发重连逻辑 } });
其他可能导致返回null的排查点
- 设备已登录正常的谷歌Play账号,测试场景下账号已加入应用的测试白名单
- 应用签名、包名与谷歌Play后台提交的版本完全一致
- 谷歌Play服务版本已更新到支持BillingClient 3.0.1的最新版本
- SKU类型传参正确:内购商品传
BillingClient.SkuType.INAPP,订阅商品传BillingClient.SkuType.SUBS
内容的提问来源于stack exchange,提问作者Serkan Şeker
相关产品推荐
相关产品推荐

