Improved billing error handling

pull/162/head
M66B 5 years ago
parent d0e55bf4e1
commit 81047433b5

@ -227,9 +227,8 @@ public class ActivityBilling extends ActivityBase implements PurchasesUpdatedLis
} }
BillingResult result = billingClient.launchBillingFlow(this, flowParams.build()); BillingResult result = billingClient.launchBillingFlow(this, flowParams.build());
String text = getBillingResponseText(result, "IAB launch billing flow");
if (result.getResponseCode() != BillingClient.BillingResponseCode.OK) if (result.getResponseCode() != BillingClient.BillingResponseCode.OK)
notifyError(text); reportError(result, "IAB launch billing flow");
} else } else
try { try {
Intent view = new Intent(Intent.ACTION_VIEW); Intent view = new Intent(Intent.ACTION_VIEW);
@ -244,7 +243,6 @@ public class ActivityBilling extends ActivityBase implements PurchasesUpdatedLis
billingClient.queryPurchaseHistoryAsync(BillingClient.SkuType.INAPP, new PurchaseHistoryResponseListener() { billingClient.queryPurchaseHistoryAsync(BillingClient.SkuType.INAPP, new PurchaseHistoryResponseListener() {
@Override @Override
public void onPurchaseHistoryResponse(BillingResult result, List<PurchaseHistoryRecord> records) { public void onPurchaseHistoryResponse(BillingResult result, List<PurchaseHistoryRecord> records) {
String text = getBillingResponseText(result, "IAB history");
if (result.getResponseCode() == BillingClient.BillingResponseCode.OK) { if (result.getResponseCode() == BillingClient.BillingResponseCode.OK) {
for (PurchaseHistoryRecord record : records) for (PurchaseHistoryRecord record : records)
Log.i("IAB history=" + record.toString()); Log.i("IAB history=" + record.toString());
@ -253,7 +251,7 @@ public class ActivityBilling extends ActivityBase implements PurchasesUpdatedLis
ToastEx.makeText(ActivityBilling.this, R.string.title_setup_done, Toast.LENGTH_LONG).show(); ToastEx.makeText(ActivityBilling.this, R.string.title_setup_done, Toast.LENGTH_LONG).show();
} else } else
notifyError(text); reportError(result, "IAB history");
} }
}); });
} }
@ -263,7 +261,6 @@ public class ActivityBilling extends ActivityBase implements PurchasesUpdatedLis
@Override @Override
public void onBillingSetupFinished(BillingResult result) { public void onBillingSetupFinished(BillingResult result) {
String text = getBillingResponseText(result, "IAB connected");
if (result.getResponseCode() == BillingClient.BillingResponseCode.OK) { if (result.getResponseCode() == BillingClient.BillingResponseCode.OK) {
for (IBillingListener listener : listeners) for (IBillingListener listener : listeners)
listener.onConnected(); listener.onConnected();
@ -271,7 +268,7 @@ public class ActivityBilling extends ActivityBase implements PurchasesUpdatedLis
backoff = 4; backoff = 4;
queryPurchases(); queryPurchases();
} else } else
notifyError(text); reportError(result, "IAB connected");
} }
@Override @Override
@ -280,34 +277,36 @@ public class ActivityBilling extends ActivityBase implements PurchasesUpdatedLis
listener.onDisconnected(); listener.onDisconnected();
backoff *= 2; backoff *= 2;
Log.i("IAB disconnected retry in " + backoff + " s"); retry(backoff);
new Handler().postDelayed(new Runnable() {
@Override
public void run() {
if (!billingClient.isReady())
billingClient.startConnection(billingClientStateListener);
}
}, backoff * 1000L);
} }
}; };
private void retry(int backoff) {
Log.i("IAB connect retry in " + backoff + " s");
new Handler().postDelayed(new Runnable() {
@Override
public void run() {
if (!billingClient.isReady())
billingClient.startConnection(billingClientStateListener);
}
}, backoff * 1000L);
}
@Override @Override
public void onPurchasesUpdated(BillingResult result, @Nullable List<Purchase> purchases) { public void onPurchasesUpdated(BillingResult result, @Nullable List<Purchase> purchases) {
String text = getBillingResponseText(result, "IAB purchases updated");
if (result.getResponseCode() == BillingClient.BillingResponseCode.OK) if (result.getResponseCode() == BillingClient.BillingResponseCode.OK)
checkPurchases(purchases); checkPurchases(purchases);
else else
notifyError(text); reportError(result, "IAB purchases updated");
} }
private void queryPurchases() { private void queryPurchases() {
Purchase.PurchasesResult result = billingClient.queryPurchases(BillingClient.SkuType.INAPP); Purchase.PurchasesResult result = billingClient.queryPurchases(BillingClient.SkuType.INAPP);
String text = getBillingResponseText(result.getBillingResult(), "IAB query purchases");
if (result.getResponseCode() == BillingClient.BillingResponseCode.OK) if (result.getResponseCode() == BillingClient.BillingResponseCode.OK)
checkPurchases(result.getPurchasesList()); checkPurchases(result.getPurchasesList());
else else
notifyError(text); reportError(result.getBillingResult(), "IAB query purchases");
} }
interface IBillingListener { interface IBillingListener {
@ -404,12 +403,11 @@ public class ActivityBilling extends ActivityBase implements PurchasesUpdatedLis
} else { } else {
Log.w("IAB invalid signature"); Log.w("IAB invalid signature");
editor.putBoolean("pro", false); editor.putBoolean("pro", false);
notifyError("Invalid purchase"); reportError(null, "Invalid purchase");
} }
} }
} catch (Throwable ex) { } catch (Throwable ex) {
Log.e(ex); reportError(null, Helper.formatThrowable(ex, false));
notifyError(Helper.formatThrowable(ex, false));
} }
editor.apply(); editor.apply();
@ -430,7 +428,6 @@ public class ActivityBilling extends ActivityBase implements PurchasesUpdatedLis
new SkuDetailsResponseListener() { new SkuDetailsResponseListener() {
@Override @Override
public void onSkuDetailsResponse(BillingResult result, List<SkuDetails> skuDetailsList) { public void onSkuDetailsResponse(BillingResult result, List<SkuDetails> skuDetailsList) {
String text = getBillingResponseText(result, "IAB query SKUs");
if (result.getResponseCode() == BillingClient.BillingResponseCode.OK) { if (result.getResponseCode() == BillingClient.BillingResponseCode.OK) {
for (SkuDetails skuDetail : skuDetailsList) { for (SkuDetails skuDetail : skuDetailsList) {
Log.i("IAB SKU detail=" + skuDetail); Log.i("IAB SKU detail=" + skuDetail);
@ -439,7 +436,7 @@ public class ActivityBilling extends ActivityBase implements PurchasesUpdatedLis
listener.onSkuDetails(skuDetail.getSku(), skuDetail.getPrice()); listener.onSkuDetails(skuDetail.getSku(), skuDetail.getPrice());
} }
} else } else
notifyError(text); reportError(result, "IAB query SKUs");
} }
}); });
} }
@ -452,9 +449,8 @@ public class ActivityBilling extends ActivityBase implements PurchasesUpdatedLis
billingClient.consumeAsync(params, new ConsumeResponseListener() { billingClient.consumeAsync(params, new ConsumeResponseListener() {
@Override @Override
public void onConsumeResponse(BillingResult result, String purchaseToken) { public void onConsumeResponse(BillingResult result, String purchaseToken) {
String text = getBillingResponseText(result, "IAB consumed SKU=" + purchase.getSku());
if (result.getResponseCode() != BillingClient.BillingResponseCode.OK) if (result.getResponseCode() != BillingClient.BillingResponseCode.OK)
notifyError(text); reportError(result, "IAB consumed SKU=" + purchase.getSku());
} }
}); });
} }
@ -468,7 +464,6 @@ public class ActivityBilling extends ActivityBase implements PurchasesUpdatedLis
billingClient.acknowledgePurchase(params, new AcknowledgePurchaseResponseListener() { billingClient.acknowledgePurchase(params, new AcknowledgePurchaseResponseListener() {
@Override @Override
public void onAcknowledgePurchaseResponse(BillingResult result) { public void onAcknowledgePurchaseResponse(BillingResult result) {
String text = getBillingResponseText(result, "IAB acknowledged SKU=" + purchase.getSku());
if (result.getResponseCode() == BillingClient.BillingResponseCode.OK) { if (result.getResponseCode() == BillingClient.BillingResponseCode.OK) {
SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(ActivityBilling.this); SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(ActivityBilling.this);
SharedPreferences.Editor editor = prefs.edit(); SharedPreferences.Editor editor = prefs.edit();
@ -481,27 +476,31 @@ public class ActivityBilling extends ActivityBase implements PurchasesUpdatedLis
WidgetUnified.update(ActivityBilling.this); WidgetUnified.update(ActivityBilling.this);
} else } else
notifyError(text); reportError(result, "IAB acknowledged SKU=" + purchase.getSku());
} }
}); });
} }
private void notifyError(String message) { private void reportError(BillingResult result, String stage) {
String message;
if (result == null)
message = stage;
else {
String debug = result.getDebugMessage();
message = getBillingResponseText(result) + (debug == null ? "" : " " + debug) + " " + stage;
// https://developer.android.com/reference/com/android/billingclient/api/BillingClient.BillingResponse#service_disconnected
if (result.getResponseCode() == BillingClient.BillingResponseCode.SERVICE_DISCONNECTED)
retry(60);
}
Log.e(message);
for (IBillingListener listener : listeners) for (IBillingListener listener : listeners)
listener.onError(message); listener.onError(message);
} }
private static String getBillingResponseText(BillingResult result, String message) { private static String getBillingResponseText(BillingResult result) {
String debug = result.getDebugMessage();
String text = _getBillingResponseText(result) + (debug == null ? "" : " " + debug);
if (result.getResponseCode() == BillingClient.BillingResponseCode.OK)
Log.i(message + " response=" + text);
else
Log.e(message + " response=" + text);
return text;
}
private static String _getBillingResponseText(BillingResult result) {
switch (result.getResponseCode()) { switch (result.getResponseCode()) {
case BillingClient.BillingResponseCode.BILLING_UNAVAILABLE: case BillingClient.BillingResponseCode.BILLING_UNAVAILABLE:
// Billing API version is not supported for the type requested // Billing API version is not supported for the type requested
@ -543,6 +542,10 @@ public class ActivityBilling extends ActivityBase implements PurchasesUpdatedLis
// Network connection is down // Network connection is down
return "SERVICE_UNAVAILABLE"; return "SERVICE_UNAVAILABLE";
case BillingClient.BillingResponseCode.SERVICE_TIMEOUT:
// The request has reached the maximum timeout before Google Play responds.
return "SERVICE_TIMEOUT";
case BillingClient.BillingResponseCode.USER_CANCELED: case BillingClient.BillingResponseCode.USER_CANCELED:
// User pressed back or canceled a dialog // User pressed back or canceled a dialog
return "USER_CANCELED"; return "USER_CANCELED";

Loading…
Cancel
Save