Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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);
}
like image 611
Florian Walther Avatar asked Jan 03 '23 10:01

Florian Walther


2 Answers

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
    }
}
like image 197
Kuffs Avatar answered Jan 17 '23 14:01

Kuffs


I don't know if this applies to your exact scenario, but we are experiencing the same thing and it is a bug on Google's end.

See https://issuetracker.google.com/issues/66054158 for more information.

Edit: I just saw that @goRGon posted the same thing :)

The example of multiple people in Spain isn't the same situation as what's described above. In the Spain scenario, the users are actually purchasing two copies of the IAP, so they are two separate receipts and the users should be rewarded with two copies of whatever they purchased. In the bug scenario, one single receipt is presented to the user twice so duplicates can actually be caught. But either way, back-end validation systems need to accommodate hackers/bugs in code that might cause the same receipt to be sent twice in a row.

like image 44
Jeg Elsker Avatar answered Jan 17 '23 13:01

Jeg Elsker