How do you query a list of products from google play billing 5?
From https://developer.android.com/google/play/billing/integrate#java, we query the details of a single product by passing the name of the product to setProductId
,
QueryProductDetailsParams queryProductDetailsParams =
QueryProductDetailsParams.newBuilder()
.setProductList(
ImmutableList.of(
Product.newBuilder()
.setProductId("product_id_example")
.setProductType(ProductType.SUBS)
.build()))
.build();
billingClient.queryProductDetailsAsync(
queryProductDetailsParams,
new ProductDetailsResponseListener() {
public void onProductDetailsResponse(BillingResult billingResult,
List<ProductDetails> productDetailsList) {
// check billingResult
// process returned productDetailsList
}
}
)
But that only gets a single product, thus when you try to print out List<ProductDetails> productDetailsList
there is only one. So how do you pass in multiple products?
As far as I am aware .setProductId("product_id_example")
only takes a string and not a list.
CodePudding user response:
Looks like a good answer can be found here: Adding multiple products to productlist for queryProductDetailsAsync in android billing 5.0.0
But I'll provide some comments below:
To add additional products we need to have the products in the immutableList
, so without a for-loop we can just have:
QueryProductDetailsParams queryProductDetailsParams = QueryProductDetailsParams.newBuilder()
.setProductList(
ImmutableList.of(
QueryProductDetailsParams.Product.newBuilder()
.setProductId("Product1")
.setProductType(BillingClient.ProductType.INAPP)
.build(),
QueryProductDetailsParams.Product.newBuilder()
.setProductId("Product2")
.setProductType(BillingClient.ProductType.INAPP)
.build()
)).build();
However, that isn't suitable if your products need to be populated dynamically. This means we need to dynamically populate the items within the ImmutableList
. You'll notice that the add
method for ImmutableList
is deprecated so the add
method does nothing.
As a work around, I created an ArrayList
, populate the products into the ArrayList
and then cast it to an ImmutableList
ImmutableList<QueryProductDetailsParams.Product> productsList = ImmutableList.of();
ArrayList<QueryProductDetailsParams.Product> products = new ArrayList();
for (String productId : productIds ) {
products.add(QueryProductDetailsParams.Product.newBuilder()
.setProductId(productId)
.setProductType(BillingClient.ProductType.INAPP)
.build());
}
productsList = ImmutableList.copyOf(products);
QueryProductDetailsParams queryProductDetailsParams = QueryProductDetailsParams.newBuilder()
.setProductList(productsList).build();
CodePudding user response:
The official examples use an ImmutableList
for some reason to build the query, but you don't actually need to use that. The setProductList
method just takes List<Product>
as its input, it does not require ImmutableList
.
You could use something like this (API 24 to use stream()
):
List<String> ids = Arrays.asList("1","2","3"); // your product IDs
List<Product> productList = ids.stream().map( productId ->
Product.newBuilder()
.setProductId(productId)
.setProductType(BillingClient.ProductType.SUBS)
.build()
).collect(Collectors.toList());
QueryProductDetailsParams params = QueryProductDetailsParams.newBuilder()
.setProductList(productList)
.build();
If you have API < 24, you could just make an ArrayList instead.
List<String> ids = Arrays.asList("1","2","3"); // your product IDs
ArrayList<Product> productList = new ArrayList<>();
for(String productId : ids) {
productList.add(
Product.newBuilder()
.setProductId(productId)
.setProductType(BillingClient.ProductType.SUBS)
.build()
);
}
QueryProductDetailsParams params = QueryProductDetailsParams.newBuilder()
.setProductList(productList)
.build();
I suspect they wrote the example in Kotlin (using listOf
), and automatically converted it to Java (somehow giving us ImmutableList.of
)...