英文:
version 2.0 of the Google Play Billing Library - .setSkuDetails(skuDetails)
问题
如何在 Java 中调用时使用 .setSkuDetails(skuDetails):
```java
BillingFlowParams flowParams = BillingFlowParams.newBuilder()
.setSkuDetails(skuDetails)
.build();
int responseCode = billingClient.launchBillingFlow(flowParams);
我在整个 Google 上搜索了,但没有找到任何适当且完整的实现。请有人通过提供带有所有必要函数的完整过程来帮助我,因为我只找到了1.0
版本的示例、Kotlin示例或不完整的示例,我想使用 Java。请在这方面为我提供帮助。
<details>
<summary>英文:</summary>
How to .setSkuDetails(skuDetails) in java while calling
BillingFlowParams flowParams = BillingFlowParams.newBuilder()
.setSkuDetails(skuDetails)
.build();
int responseCode = billingClient.launchBillingFlow(flowParams);
I searched whole google but did not find any proper and complete implementation, please someone help me with this by providing full process with all necessary functions, because I found only library```1.0``` examples or Kotlin or incomplete,I want java
please help me in this
</details>
# 答案1
**得分**: 2
这是完整的实现。
有关详细信息,请参阅文档:https://developer.android.com/google/play/billing/billing_library_overview
```java
String ITEM_SKU_diamond_500 = "diamond_500";
BillingClient billingClient;
AcknowledgePurchaseResponseListener acknowledgePurchaseResponseListener;
String premiumUpgradePrice = "";
1: 必须使用BillingClient.Builder
创建一个计费客户端。
billingClient = BillingClient.newBuilder(this)
.enablePendingPurchases()
.setListener(this).build();
2: 在创建billingClient
之后,启动billingClient
连接。
billingClient.startConnection(new BillingClientStateListener() {
@Override
public void onBillingSetupFinished(BillingResult billingResult) {
if (billingResult.getResponseCode() == BillingClient.BillingResponseCode.OK) {
List<String> skuList = new ArrayList<>();
skuList.add(ITEM_SKU_diamond_500);
final SkuDetailsParams.Builder params = SkuDetailsParams.newBuilder();
params.setSkusList(skuList).setType(BillingClient.SkuType.INAPP);
3: 在成功建立连接后,使用billingClient
的querySkuDetailsAsync
方法异步获取SKU
详细信息。
billingClient.querySkuDetailsAsync(params.build(), new SkuDetailsResponseListener() {
@Override
public void onSkuDetailsResponse(BillingResult billingResult, List<SkuDetails> skuDetailsList) {
if (skuDetailsList != null && billingResult.getResponseCode() == BillingClient.BillingResponseCode.OK) {
for (SkuDetails skuDetails : skuDetailsList) {
String sku = skuDetails.getSku();
String price = skuDetails.getPrice();
final BillingFlowParams params = BillingFlowParams.newBuilder()
.setSkuDetails(skuDetails)
.build();
if (ITEM_SKU_diamond_500.equals(sku)) {
premiumUpgradePrice = price;
firstBtn500(params);
}
}
} else if (billingResult.getResponseCode() == BillingClient.BillingResponseCode.ERROR) {
Toast.makeText(DiamondsActivity.this, "Error", Toast.LENGTH_SHORT).show();
}
}
});
} else if (billingResult.getResponseCode() == BillingClient.BillingResponseCode.SERVICE_TIMEOUT) {
Toast.makeText(DiamondsActivity.this, "Service timeout", Toast.LENGTH_SHORT).show();
} else {
Toast.makeText(DiamondsActivity.this, "Failed to connect to the billing client", Toast.LENGTH_SHORT).show();
}
}
@Override
public void onBillingServiceDisconnected() {
Toast.makeText(DiamondsActivity.this, "Disconnected from the client", Toast.LENGTH_SHORT).show();
}
});
acknowledgePurchaseResponseListener = new AcknowledgePurchaseResponseListener() {
@Override
public void onAcknowledgePurchaseResponse(BillingResult billingResult) {
Toast.makeText(DiamondsActivity.this, "Purchase acknowledged", Toast.LENGTH_SHORT).show();
}
};
4: 当用户尝试进行应用内购买或订阅产品订阅时,使用billngClient
检查产品是否受支持。
isFeatureSupported(BillingClient.FeatureType/* SUBSCRIPTIONS or other */)
然后调用billingClient的launchBillingFlow
方法
private void firstBtn500(final BillingFlowParams params) {
firstPurchaseBtn.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
billingClient.launchBillingFlow(DiamondsActivity.this, params);
}
});
}
更新
在这里,您可以检查项目是否已购买
@Override
public void onPurchasesUpdated(BillingResult billingResult, @Nullable List<Purchase> purchases) {
if (purchases != null && billingResult.getResponseCode() == BillingClient.BillingResponseCode.OK) {
for (Purchase purchase : purchases) {
handlePurchases(purchase);
}
} else if (billingResult.getResponseCode() == BillingClient.BillingResponseCode.USER_CANCELED) {
Toast.makeText(this, "Purchased Canceled", Toast.LENGTH_SHORT).show();
}
else if (billingResult.getResponseCode() == BillingClient.BillingResponseCode.ITEM_ALREADY_OWNED) {
Toast.makeText(this, "Already Purchased", Toast.LENGTH_SHORT).show();
}
}
如果要购买一次性项目,需要对购买进行Acknowledge
处理
private void handlePurchases(final Purchase purchase) {
if (purchase.getPurchaseState() == Purchase.PurchaseState.PURCHASED) {
//如果尚未确认购买,请确认购买。
if (!purchase.isAcknowledged()) {
AcknowledgePurchaseParams acknowledgePurchaseParams =
AcknowledgePurchaseParams.newBuilder()
.setPurchaseToken(purchase.getPurchaseToken())
.build();
billingClient.acknowledgePurchase(acknowledgePurchaseParams, acknowledgePurchaseResponseListener);
}
如果要多次购买同一项目(例如应用内购买/游戏中的货币或积分等),需要消耗购买,以下是消耗购买的代码。
// Todo: 异步消耗购买
ConsumeParams consumeParams = ConsumeParams.newBuilder()
.setPurchaseToken(purchase.getPurchaseToken())
.build();
ConsumeResponseListener consumeResponseListener = new ConsumeResponseListener() {
@Override
public void onConsumeResponse(BillingResult billingResult, String purchaseToken) {
Toast.makeText(DiamondsActivity.this, "Purchase successful", Toast.LENGTH_SHORT).show();
if (billingResult.getResponseCode() == BillingClient.BillingResponseCode.OK) {
if (purchase.getSku().equalsIgnoreCase(ITEM_SKU_diamond_500)) {
Toast.makeText(DiamondsActivity.this, "Thank you for purchasing!", Toast.LENGTH_SHORT).show();
}
}
}
};
billingClient.consumeAsync(consumeParams, consumeResponseListener);
} else if (purchase.getPurchaseState() == Purchase.PurchaseState.PENDING) {
Toast.makeText(this, "Purchase pending", Toast.LENGTH_SHORT).show();
}
}
英文:
Here is the full implementation.
For further reference, refer to the documentation: https://developer.android.com/google/play/billing/billing_library_overview
String ITEM_SKU_diamond_500 = "diamond_500";
BillingClient billingClient;
AcknowledgePurchaseResponseListener acknowledgePurchaseResponseListener;
String premiumUpgradePrice = "";
1: A billing client has to be created using BillingClient.Builder
.
billingClient = BillingClient.newBuilder(this)
.enablePendingPurchases()
.setListener(this).build();
2: After creating a billingClient
start the billingClient
connection
billingClient.startConnection(new BillingClientStateListener() {
@Override
public void onBillingSetupFinished(BillingResult billingResult) {
if (billingResult.getResponseCode() == BillingClient.BillingResponseCode.OK) {
List<String> skuList = new ArrayList<>();
skuList.add(ITEM_SKU_diamond_500);
final SkuDetailsParams.Builder params = SkuDetailsParams.newBuilder();
params.setSkusList(skuList).setType(BillingClient.SkuType.INAPP);
3: After establishing a successful connection, make a call with billingClient
's querySkuDetailsAsync
method to fetch SKU
details asynchronously.
billingClient.querySkuDetailsAsync(params.build(), new SkuDetailsResponseListener() {
@Override
public void onSkuDetailsResponse(BillingResult billingResult, List<SkuDetails> skuDetailsList) {
if (skuDetailsList != null && billingResult.getResponseCode() == BillingClient.BillingResponseCode.OK) {
for (SkuDetails skuDetails : skuDetailsList) {
String sku = skuDetails.getSku();
String price = skuDetails.getPrice();
final BillingFlowParams params = BillingFlowParams.newBuilder()
.setSkuDetails(skuDetails)
.build();
if (ITEM_SKU_diamond_500.equals(sku)) {
premiumUpgradePrice = price;
firstBtn500(params);
}
}
} else if (billingResult.getResponseCode() == BillingClient.BillingResponseCode.ERROR) {
Toast.makeText(DiamondsActivity.this, "Error", Toast.LENGTH_SHORT).show();
}
}
});
} else if (billingResult.getResponseCode() == BillingClient.BillingResponseCode.SERVICE_TIMEOUT) {
Toast.makeText(DiamondsActivity.this, "Service timeout", Toast.LENGTH_SHORT).show();
} else {
Toast.makeText(DiamondsActivity.this, "Failed to connect to the billing client", Toast.LENGTH_SHORT).show();
}
}
@Override
public void onBillingServiceDisconnected() {
Toast.makeText(DiamondsActivity.this, "Disconnected from the client", Toast.LENGTH_SHORT).show();
}
});
acknowledgePurchaseResponseListener = new AcknowledgePurchaseResponseListener() {
@Override
public void onAcknowledgePurchaseResponse(BillingResult billingResult) {
Toast.makeText(DiamondsActivity.this, "Purchase acknowledged", Toast.LENGTH_SHORT).show();
}
};
4: When a user tries to make an in-app purchase or subscribe to the product subscription, check if the product is supported using billngClient
isFeatureSupported(BillingClient.FeatureType```./* SUBSCRIPTIONS or other */)
method and make a call to billingClient's launchBillingFlow
method
private void firstBtn500(final BillingFlowParams params) {
firstPurchaseBtn.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
billingClient.launchBillingFlow(DiamondsActivity.this, params);
}
});
}
UPDATE
Here you can check if the item is already purchased or not
@Override
public void onPurchasesUpdated(BillingResult billingResult, @Nullable List<Purchase> purchases) {
if (purchases != null && billingResult.getResponseCode() == BillingClient.BillingResponseCode.OK) {
for (Purchase purchase : purchases) {
handlePurchases(purchase);
}
} else if (billingResult.getResponseCode() == BillingClient.BillingResponseCode.USER_CANCELED) {
Toast.makeText(this, "Purchased Canceled", Toast.LENGTH_SHORT).show();
}
else if (billingResult.getResponseCode() == BillingClient.BillingResponseCode.ITEM_ALREADY_OWNED) {
Toast.makeText(this, "Already Purchased", Toast.LENGTH_SHORT).show();
}
}
If you want to purchase an item once, you need to Acknowledge
the purchase
private void handlePurchases(final Purchase purchase) {
if (purchase.getPurchaseState() == Purchase.PurchaseState.PURCHASED) {
//Acknowledge the purchase if it hasn't already been acknowledged.
if (!purchase.isAcknowledged()) {
AcknowledgePurchaseParams acknowledgePurchaseParams =
AcknowledgePurchaseParams.newBuilder()
.setPurchaseToken(purchase.getPurchaseToken())
.build();
billingClient.acknowledgePurchase(acknowledgePurchaseParams, acknowledgePurchaseResponseListener);
}
If you want to purchase the same item again and again (Like in-app/game in coins or credit or something like this). You need to consume purchase below is the code to consume purchase.
// Todo: Consume the purchase async
ConsumeParams consumeParams = ConsumeParams.newBuilder()
.setPurchaseToken(purchase.getPurchaseToken())
.build();
ConsumeResponseListener consumeResponseListener = new ConsumeResponseListener() {
@Override
public void onConsumeResponse(BillingResult billingResult, String purchaseToken) {
Toast.makeText(DiamondsActivity.this, "Purchase successful", Toast.LENGTH_SHORT).show();
if (billingResult.getResponseCode() == BillingClient.BillingResponseCode.OK) {
if (purchase.getSku().equalsIgnoreCase(ITEM_SKU_diamond_500)) {
Toast.makeText(DiamondsActivity.this, "Thank you for purchasing!", Toast.LENGTH_SHORT).show();
}
}
}
};
billingClient.consumeAsync(consumeParams, consumeResponseListener);
} else if (purchase.getPurchaseState() == Purchase.PurchaseState.PENDING) {
Toast.makeText(this, "Purchase pending", Toast.LENGTH_SHORT).show();
}
}
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论