将多个产品添加到 android billing 5.0.0 中的 queryProductDetailsAsync 的产品列表中

And*_*der 12 java android play-billing-library

在旧的 Android 计费实现中,您将构建一个 sku 列表来查询产品:

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);
Run Code Online (Sandbox Code Playgroud)

新的计费实施更加复杂,并且似乎限制您只能将一种产品添加到查询列表中:

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);                           
                        }
                    }
                   
                }
            }
    );
Run Code Online (Sandbox Code Playgroud)

它使您可以为启动购买流程所需的 mProductDetailsMap 的productDetailsList 构建productList:

puchasestring=SKU_POTION;
initiatePurchaseFlow(mProductDetailsMap.get(puchasestring));
Run Code Online (Sandbox Code Playgroud)

如何将多个产品添加到开始实施的产品列表中?我不想为每个项目重复整个代码段以添加到 mProductDetailsMap,这是我现在使用的 Primitive Pete 方法。

Tyl*_*r V 20

您实际上不必使用ImmutableList. 出于某种原因,官方示例使用 anImmutableList来构建查询,但这不是必需的。该setProductList方法仅List<Product>作为其输入,因此您可以执行以下操作:

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
    }
}
Run Code Online (Sandbox Code Playgroud)

任何实现该List接口的东西都可以工作 - ArrayListImmutableList等等......

更新

如果您想查询 INAPP 和 SUBS 类型的混合,则无法通过一次调用来完成此操作。但是,您可以使用流来组合两个异步调用并同时运行它们(比一次运行它们更快,并且更容易处理结果)

首先,创建一个辅助函数,为每次调用返回一个流程(这需要gradle 中的queryProductDetails计费扩展)-ktx

private fun getDetailsFlow(productIds: List<String>, type: String) : Flow<List<ProductDetails>> {

    val productList = productIds.map { productId ->
        QueryProductDetailsParams.Product.newBuilder()
            .setProductId(productId)
            .setProductType(type)
            .build()
    }

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

    return flow {
        emit(billingClient?.queryProductDetails(params))
    }.map { result ->
        result?.productDetailsList ?: emptyList()
    }
}
Run Code Online (Sandbox Code Playgroud)

然后将两个流程压缩在一起以获得单个产品列表。

fun queryProductDetails() {

    val inAppFlow = getDetailsFlow(listOf(Product.GOLD, Product.SILVER), BillingClient.ProductType.INAPP)
    val subsFlow = getDetailsFlow(listOf(Product.UNLIMITED), BillingClient.ProductType.SUBS)

    val allDetailsFlow = inAppFlow.zip(subsFlow) { inAppResult, subsResult ->
        return@zip inAppResult + subsResult
    }

    scope.launch {
        allDetailsFlow.collect { productList ->
            // handle the unified list of all products, subscription and in-app
        }
    }
}
Run Code Online (Sandbox Code Playgroud)


And*_*der 7

对于多个产品:

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());
Run Code Online (Sandbox Code Playgroud)

  • 为什么产品类型需要相同?为什么我无法使用单个查询在应用程序和子程序中进行查询 (3认同)