- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
我正在使用 Google Play 计费库 2.0.3 ( implementation 'com.android.billingclient:billing:2.0.3'
) 并且它在大多数情况下都可以正常工作,但对于某些用户来说,原因不明,querySkuDetailsAsync() method occasionally fails with BillingResponseCode.ERROR (6) error code...
有人知道吗?这个错误的原因没有在任何地方解释,除了它是“API操作期间的 fatal error ”。谁能告诉它为什么会发生?
编辑:
我正在使用文档中的方法(https://developer.android.com/google/play/billing/billing_library_overview):
public interface QuerySkuDetailsListener {
void onSuccess(List<SkuDetails> skuDetailsList);
void onErrorProductsHaveDifferentTypes();
void onBillingClientError(int error_code);
}
public void querySkuDetails(final QuerySkuDetailsListener querySkuDetailsListener, final Product... products) {
if (products.length < 1) {
//ERROR_NO_PRODUCTS_TO_QUERY
throw new NullPointerException();
}
String querySkuType = products[0].getSkuType();
SkuDetailsParams.Builder params = SkuDetailsParams.newBuilder();
List<String> skuList = new ArrayList<>();
for (Product product : products) {
skuList.add(product.getSku());
if (!product.getSkuType().equals(querySkuType)) {
//ERROR_SKU_TYPE_CANT_BE_DIFFERENT
querySkuDetailsListener.onErrorProductsHaveDifferentTypes();
return;
}
}
params.setSkusList(skuList).setType(querySkuType);
billingClient.querySkuDetailsAsync(params.build(), new SkuDetailsResponseListener() {
@Override
public void onSkuDetailsResponse(BillingResult billingResult, List<SkuDetails> skuDetailsList) {
if (billingResult.getResponseCode() == BillingClient.BillingResponseCode.OK && skuDetailsList != null) {
querySkuDetailsListener.onSuccess(skuDetailsList);
}
else {
//ERROR QUERYING SKU DETAILS
querySkuDetailsListener.onBillingClientError(billingResult.getResponseCode());
}
}
});
}
private void initiatePurchaseFlow(final Activity activity, @Nullable final Product oldProduct, final Product product, final JsonObject metadata, final InitiatePurchaseListener initiatePurchaseListener) {
//Check if billingClient is ready
if (billingClient.isReady()) {
querySkuDetails(new QuerySkuDetailsListener() {
@Override
public void onSuccess(List<SkuDetails> skuDetailsList) {
// Process the result.
BillingFlowParams.Builder flowParamsBuilder = BillingFlowParams.newBuilder();
flowParamsBuilder.setSkuDetails(skuDetailsList.get(0));
if (null != oldProduct) {
flowParamsBuilder.setOldSku(oldProduct.getSku());
flowParamsBuilder.setReplaceSkusProrationMode(BillingFlowParams.ProrationMode.IMMEDIATE_WITH_TIME_PRORATION);
}
BillingFlowParams flowParams = flowParamsBuilder.build();
int responseCode = billingClient.launchBillingFlow(activity, flowParams).getResponseCode();
if (responseCode == BillingClient.BillingResponseCode.OK) {
//SUCCESS, OK
...Rest of the irrelevant code...
}
else {
//ERROR_IN_LAUNCHING_BILLING_FLOW
dispenseInitiatePurchaseFlowError(activity, initiatePurchaseListener, InitiatePurchaseErrorCodes.ERROR_IN_LAUNCHING_BILLING_FLOW, getBillingClientErrorDescription(responseCode));
}
}
@Override
public void onErrorProductsHaveDifferentTypes() {
//ERROR_IN_QUERYING_SKU_DETAILS_PRODUCTS_HAVE_DIFFERENT_TYPES
dispenseInitiatePurchaseFlowError(activity, initiatePurchaseListener, InitiatePurchaseErrorCodes.ERROR_IN_QUERYING_SKU_DETAILS_PRODUCTS_HAVE_DIFFERENT_TYPES, getBillingClientErrorDescription(0));
}
@Override
public void onBillingClientError(int error_code) {
//ERROR_IN_QUERYING_SKU_DETAILS
dispenseInitiatePurchaseFlowError(activity, initiatePurchaseListener, InitiatePurchaseErrorCodes.ERROR_IN_QUERYING_SKU_DETAILS, getBillingClientErrorDescription(error_code));
}
}, product);
}
else {
//ERROR_BILLING_CLIENT_IS_NOT_READY
//Trying to reconnect once
billingClient.startConnection(new BillingClientStateListener() {
@Override
public void onBillingSetupFinished(BillingResult billingResult) {
if (billingResult.getResponseCode() == BillingResponse.OK) {
//launching again
initiatePurchaseFlow(activity, oldProduct, product, metadata, initiatePurchaseListener);
}
else {
// showing an error dialog
dispenseInitiatePurchaseFlowError(activity, initiatePurchaseListener, InitiatePurchaseErrorCodes.ERROR_BILLING_CLIENT_IS_NOT_READY, getBillingClientErrorDescription(billingResult.getResponseCode()));
}
}
@Override
public void onBillingServiceDisconnected() {
// showing an error dialog
}
});
}
}
onPurchasesUpdated(BillingResult billingResult, @Nullable List<Purchase> purchases)
如果您使用幸运补丁破解应用程序,计费客户端的方法会返回此错误代码 (
BillingResponseCode.ERROR
),但我在
querySkuDetailsAsync()
中没有收到任何错误……这有关系吗?
最佳答案
为了将来引用和其他一些遭受此困扰的人(例如 IAB 3.0.1 中的我),OP 打开的问题跟踪器错误中的某个人发表了评论,如果我们收到此代码,我们应该如何 react
Error 6 (https://developer.android.com/reference/com/android/billingclient/api/BillingClient.BillingResponseCode#error) usually represents a transient error from our backend servers. This error code should trigger a retry which in most cases should succeed.
@Override
public void onSkuDetailsResponse(@NonNull BillingResult billingResult, @Nullable List<SkuDetails> list) {
Utils.log("BILLING: onSkuDetailsResponse(). Result (" + billingResult.getResponseCode() + ") List size: " + (list == null ? "null" : list.size()));
if (billingResult.getResponseCode() == BillingClient.BillingResponseCode.OK && list != null) {
if (mSkuQueryErrorCounter > 0) mSkuQueryErrorCounter--;
// process the SkuDetail list...
}
} else {
// https://issuetracker.google.com/issues/139631105#comment11
mSkuQueryErrorCounter++;
if (mSkuQueryErrorCounter <= 2) scheduleUpdate(NOW);
else if (mSkuQueryErrorCounter < 5) scheduleUpdate(TEN_SECONDS);
else if (mSkuQueryErrorCounter < 10) scheduleUpdate(ONE_HOUR);
else scheduleUpdate(ONE_DAY);
}
}
关于android - Google Play 计费库 - querySkuDetailsAsync 偶尔会返回 BillingResponseCode.ERROR (6),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/57550575/
如果应用中的购买调用 BillingClient.BillingResponseCode.ITEM_ALREADY_OWNED:需要调用 acknowledgePurchase(... 重新验证订单的
我正在使用 Google Play 计费库 2.0.3 ( implementation 'com.android.billingclient:billing:2.0.3' ) 并且它在大多数情况下都
我是一名优秀的程序员,十分优秀!