← Back to list

android queryProductDetailsAsync 沒回傳

Reminder: By Aug 31, 2025, all new apps and updates to existing apps must use Billing Library version 7 or newer. If you need more time to…

海螺 · 2025-09-28 03:38 · 0 claps · 8.0 min read paywalled
#billing #google-play-services #android #java #client-billing
Open on Medium ↗
Wiki topics: 📚 · Books & Reading

android queryProductDetailsAsync 沒回傳

[embed]從 Google Play 帳款服務程式庫第 6 或第 7 版改用第 8 版 | Play Billing | Android Developers 本文說明如何從 Google Play 帳款服務程式庫 (PBL) 第 6 版或第 7 版遷移至第 8 版,以及如何整合新的選用訂閱功能。 如需第 8.0.0 版的完整異動清單,請參閱「 版本資訊 」。 PBL 8 改善了現有…developer.android.com

Reminder: By Aug 31, 2025, all new apps and updates to existing apps must use Billing Library version 7 or newer. If you need more time to update your app, you can request an extension until Nov 1, 2025. Learn about Play Billing Library version deprecation.

由於8/31前需要把google的內購版本升級到7.0.0以上(原本的是6.0.1),然後8.0.0也出來了,於是打算直接升到8.0.0就不用再顧慮之後還要升級的問題了

com.android.billingclient:billing:6.0.1 => com.android.billingclient:billing:8.0.0

因為專案是寫SDK給其他廠商做串接用的,會產出aar給對方串接,所以aar內的com.android.billingclient:billing版本有變動的話,串接的廠商也需要同一調整

這次發生SDK billing升級後串接的廠商內購拉不起來的問題(系統的付款彈窗沒出現),排查後發現BillingClient底下的方法queryProductDetailsAsync沒有任何回傳導致不會跳出系統的付款彈窗

流程是會先去查這個ID在GooglePlay後台是否有查到資訊才會進行付款流程

queryProductDetailsAsync 是查詢指定的產品productID資訊(內購品的名稱、金額等等)

預期結果是,就算給的ID不正確因該也要回傳空陣列,但實際結果是什麼都沒有,方法進去後沒有掏出任何錯誤訊息沒有任何回應

結論: 最後排查出來的問題是,因為串接廠商使用com.android.billingclient:billing的版本不一致導致SDK內queryProductDetailsAsync方法沒有回傳,廠商用到7.0.0版本的(本來預期就算版本錯誤再run時應該也要報錯)

在沒有任何錯誤訊息下,廠商也沒注意到版本不同的情況下很難排查到是版本問題,若以後遷移套件有發生沒報錯當方法都沒回傳時可以先檢查套件版本是否一致

相關程式碼

BillingClient初始化

import com.android.billingclient.api.BillingClient;
import com.android.billingclient.api.BillingClientStateListener;
import com.android.billingclient.api.BillingFlowParams;
import com.android.billingclient.api.BillingResult;
import com.android.billingclient.api.ConsumeParams;
import com.android.billingclient.api.ConsumeResponseListener;
import com.android.billingclient.api.PendingPurchasesParams;
import com.android.billingclient.api.ProductDetails;
import com.android.billingclient.api.Purchase;
import com.android.billingclient.api.PurchasesUpdatedListener;
import com.android.billingclient.api.QueryProductDetailsParams;
import com.android.billingclient.api.QueryPurchasesParams;
static BillingClient billingClient;
PurchasesUpdatedListener purchasesUpdatedListener = new PurchasesUpdatedListener() {
    @Override
    public void onPurchasesUpdated(@NonNull BillingResult billingResult, @Nullable List<Purchase> purchases){
        if (billingResult.getResponseCode() == BillingClient.BillingResponseCode.ITEM_ALREADY_OWNED) {
          //上次內購未消耗,檢查billingResult.getDebugMessage()、billingResult.getResponseCode()
        }
        else if (billingResult.getResponseCode() == BillingClient.BillingResponseCode.OK && purchases != null) {
          //支付成功
        } else if (billingResult.getResponseCode() == BillingClient.BillingResponseCode.USER_CANCELED) {
          //支付取消
        } else {
          //支付錯誤,可看billingResult.getResponseCode()
        }
    }
};
PendingPurchasesParams pendingParams = PendingPurchasesParams.newBuilder().enableOneTimeProducts().build();
billingClient = BillingClient.newBuilder(activety)
                .setListener(purchasesUpdatedListener)
                .enablePendingPurchases(pendingParams)
                .build();

GooglePlay連線確認(要做內購流程前要先確認連線正常,在查詢內購產品之前)

billingClient.startConnection(new BillingClientStateListener() {
    @Override
    public void onBillingSetupFinished(BillingResult billingResult) {
      if (billingResult.getResponseCode() ==  BillingClient.BillingResponseCode.OK) {
        //google play連線成功,進行內購查詢
      }else{
        //特殊狀況
      }
    }
    @Override
    public void onBillingServiceDisconnected() {
      //google play連線失敗
    }
});

查詢內購ID資訊

//productId=>要查詢的產品ID,skuType產品類型(inapp還是subs 一次型/訂閱型)
List<QueryProductDetailsParams.Product> list = new ArrayList<>();
QueryProductDetailsParams.Product product = QueryProductDetailsParams.Product.newBuilder()
                    .setProductId(productId)
                    .setProductType(skuType)
                    .build();
list.add(product);
QueryProductDetailsParams queryProductDetailsParams =
                    QueryProductDetailsParams.newBuilder()
                            .setProductList(list)
                            .build();
//串接方跟aar內使用的版本不正確的話這邊不會回傳任何資訊
billingClient.queryProductDetailsAsync(queryProductDetailsParams,(var1,var2)->{
    if (var1.getResponseCode() == BillingClient.BillingResponseCode.OK){
        if (var2.getProductDetailsList().isEmpty()){
          //未查詢到商品訊息
        }else{
          //查詢到商品訊息,var2.getProductDetailsList(),查詢到後就能做支付流程了
        }
    }else{
        //查詢商品訊息失敗
    }
});

詳細內購流程請參考文檔: https://developer.android.com/google/play/billing/integrate?hl=zh-tw

帳務服務異動摘要文檔: https://developer.android.com/google/play/billing/release-notes?hl=zh-tw


메타데이터
post_id
fbc55a86f8d5
slug
android-queryproductdetailsasync-沒回傳-fbc55a86f8d5
url
https://medium.com/@yojjoyy1/android-queryproductdetailsasync-%E6%B2%92%E5%9B%9E%E5%82%B3-fbc55a86f8d5
canonical_url
https://medium.com/@yojjoyy1/android-queryproductdetailsasync-%E6%B2%92%E5%9B%9E%E5%82%B3-fbc55a86f8d5
author_url
https://medium.com/@yojjoyy1
status
ok
fetched_at
2026-07-17 05:34:51