Adding multiple products to productlist for queryProductDetailsAsync in android billing 5.0.0

Viewed 1385

In the old android billing implementation you would build an sku list to query products:

List<String> skuList = new ArrayList<>();
        skuList.add(SKU_POTION);
        skuList.add(SKU_SWORD);
        skuList.add(SKU_BOW);
        SkuDetailsParams.Builder params = SkuDetailsParams.newBuilder();
        params.setSkusList(skuList).setType(BillingClient.SkuType.INAPP);

The new billing implementation is more involved, and appears to limit you to adding just one product to a query list:

ImmutableList<QueryProductDetailsParams.Product> productList = ImmutableList.from(QueryProductDetailsParams.Product.newBuilder()
                    .setProductId(SKU_POTION)
                    .setProductType(BillingClient.ProductType.INAPP)
                    .build());
    
            QueryProductDetailsParams params = QueryProductDetailsParams.newBuilder()
                    .setProductList(productList)
                    .build();
    
            billingClient.queryProductDetailsAsync(
            params,
            new ProductDetailsResponseListener() {
                public void onProductDetailsResponse(BillingResult billingResult, List<ProductDetails> productDetailsList) {
                    if (billingResult.getResponseCode() == BillingClient.BillingResponseCode.OK && productDetailsList != null) {
                        for (ProductDetails skuDetails : productDetailsList) {                    
                            mProductDetailsMap.put(skuDetails.getProductId(), skuDetails);                           
                        }
                    }
                   
                }
            }
    );

It makes you build the productList for the productDetailsList for the mProductDetailsMap that's needed to start the purchase flow:

puchasestring=SKU_POTION;
initiatePurchaseFlow(mProductDetailsMap.get(puchasestring));

How would I add multiple products to the productList that begins the implementation? I don't want to have to repeat the entire code segment for each item to add to the mProductDetailsMap, which is the Primitive Pete method I'm using for now.

2 Answers

You don't actually have to use an ImmutableList. The official examples use an ImmutableList for some reason to build the query, but it isn't necessary. The setProductList method just takes List<Product> as its input, so you could just do something like this:

List<String> skuList = Arrays.asList(SKU_POTION, SKU_SWORD, SKU_BOW);

ArrayList<Product> productList = new ArrayList<>();
for(String sku : skuList) {
    productList.add(
        Product.newBuilder()
            .setProductId(sku)
            .setProductType(BillingClient.ProductType.SUBS)
            .build()
    );
}

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

billingClient.queryProductDetailsAsync(params, new ProductDetailsResponseListener() {
    public void onProductDetailsResponse(BillingResult billingResult, List<ProductDetails> productDetailsList) {
        // handle response
    }
}

Anything that implements the List interface will work - ArrayList, ImmutableList, etc...

For multiple products:

ImmutableList<QueryProductDetailsParams.Product> productList = ImmutableList.from(
QueryProductDetailsParams.Product.newBuilder()
                    .setProductId(SKU_POTION)
                    .setProductType(BillingClient.ProductType.INAPP)
                    .build(),
QueryProductDetailsParams.Product.newBuilder()
                    .setProductId(SKU_SWORD)
                    .setProductType(BillingClient.ProductType.INAPP)
                    .build(),
QueryProductDetailsParams.Product.newBuilder()
                    .setProductId(SKU_BOW)
                    .setProductType(BillingClient.ProductType.INAPP)
                    .build());
Related