Search code examples
androidin-app-billingplay-billing-library

In App Purchase seems to be called multiple times


I implemented an In-App Purchase with the Play Billing Library 1.0 according to Google's tutorial. I have only 1 item for purchase and when it gets unlocked, I show a Toast message with the length Toast.LENGTH_SHORT. However, the Toast stays there for like 10 seconds, so I assume it gets called multiple times. It does NOT happen when I unlock it via queryPurchases (if someone bought it earlier and reinstalled the app in the meantime).

Anyone have an idea why the Toast stays so long / why it gets called multiple times?

Inside my BillingManager class:

@Override
public void onPurchasesUpdated(int responseCode, @Nullable List<Purchase> purchases) {
    if (responseCode == BillingClient.BillingResponse.OK) {
        for (Purchase purchase : purchases) {
            handlePurchases(purchase);
        }
        mBillingUpdatesListener.onPurchasesUpdated(mPurchases);
    } else if (responseCode == BillingClient.BillingResponse.USER_CANCELED) {

    } else {

    }
}

public void handlePurchases(Purchase purchase) {
    //here could be validation on own server

    mPurchases.add(purchase);
}

Main Activity implements BillingUpdatesListener:

@Override
public void onPurchasesUpdated(List<Purchase> purchases) {
    for (Purchase purchase : purchases) {
        switch (purchase.getSku()) {
            case "premium":
                unlockPremium();
                break;
        }
    }
}

public void unlockPremium() {
    mPremiumUnlocked = true;
    savePremiumUnlocked();
    Toast.makeText(this, getResources().getString(R.string.premium_congrats), Toast.LENGTH_SHORT).show();
    mAdView.setVisibility(GONE);
}

Solution

  • If I understand your correctly, you say that when you first purchase the in-app product, you are getting multiple Toasts?

    In the current version (1.0) of the Billing library, this happens because multiple broadcasts are being made by the system.

    For example, if you look at or breakpoint onPurchaseFinishedReceiver at line 120 in BillingClientImpl.java within the library, this is called at least twice after making a purchase. Both times, the in-app purchase data is attached but I noticed that the intent Action was different for each broadcast.

    In the first broadcast, the Action was com.android.vending.billing.PURCHASES_UPDATED but in the second it was proxy_activity_response_intent_action. The library does not filter out the Action values and so all of these broadcasts result in your purchasesUpdatedListener being called.

    I didn't investigate further but I think what we can take from this is that SOME sort of change occurred and it was deemed necessary to broadcast that change.

    To avoid your multiple toasts, just do not display the toast unless your Premium functionality is unlocked. i.e. If it is already unlocked, simply ignore the change notification.

    By the way, it is totally possible to debug the purchase flow in Android Studio. Just sign your debug apk with your release key and make sure the apk version is not higher than the one in Play Store.

    buildTypes {
    
        debug {
            minifyEnabled false
            debuggable true
            signingConfig signingConfigs.release
        }
    
    
        release {
            minifyEnabled false
            signingConfig signingConfigs.release
        }
    }