Google Billing Problems to be Aware Of!!

Just a quick post on this as I’m really busy so will just provide links. Recently I implemented Google Billing into Arrow Mania 2 and there are a couple of heads-up warnings for others who are using it, or about to.

1. Testing with the “android.test.purchased” item causing a signature verification error and an infinite fail loop. I gave an answer to this on Stack Overflow (look for GMTDev’s reply).

http://stackoverflow.com/questions/14600664/android-in-app-purchase-signature-verification-failed/22088718#22088718

2. With Arrow Mania 2 out and a few thousand people playing I have received a crash error report in my dev console involving an illegalArgumentException in IabHelper. The problem stems from when the connection to the billing server is broken, the line in the dispose() funtion “if (mContext != null) mContext.unbindService(mServiceConn);” fails as mServiceConn is NULL. A simple fix is to change this line to “if (mContext != null && mService != null) mContext.unbindService(mServiceConn);” which simply checks for mService being null.

This is discussed on StackOverflow too: http://stackoverflow.com/questions/16222015/in-app-billing-v3-illegalargumentexception-using-iabhelper

 

Update 5th May 2014: Oh boy, another day, more IAB exceptions+errors. More changes to the IAPHelper code:-

3. I was getting billing exception reports from my app (now using CrashLytics) which I traced back to the billing not being initialised (returning NULL) but still falling through IABHelpers code (not detected). A bit of research and this is discussed in part of a page on Stackoverflow here.

A simple fix is to handle this in  IabHelper.java’s queryInventoryAsync function, adding a catch(IllegalStateException ex), see the new code below:

 

[php]
IabResult result = new IabResult(BILLING_RESPONSE_RESULT_OK, "Inventory refresh successful.");
Inventory inv = null;
try {
inv = queryInventory(querySkuDetails, moreSkus);
}
catch (IabException ex) {
result = ex.getResult();
}
catch(IllegalStateException ex){ //ADDED THIS CATCH
result = new IabResult(BILLING_RESPONSE_RESULT_ERROR, "Helper is not setup.");
}

flagEndAsync();

[/php]

4. 1st August 2014. had a new Crashlytics report just now.
Fatal Exception: java.lang.IllegalStateException – Can’t start async operation (refresh inventory) because another async operation(launchPurchaseFlow) is in progress.

So with a little digging there is a great thread here, most of which mentioned in the replies I’ve already accounted for but I’ve updated some parts of my purchase code which are:

The line before your call “mHelper.launchPurchaseFlow(….” call a flagEndAsync() just in case some previous operation is stuck. So your call becomes:

    if (mHelper != null) mHelper.flagEndAsync();     // flagEndAsync() should be made public
    mHelper.launchPurchaseFlow(this, "your item id",RC_REQUEST,mPurchaseFinishedListener,payload);

onActivityResult now looks like this:

    @Override
    protected void onActivityResult(int requestCode, int resultCode, Intent data)
    {
        Log.d(TAG, "onActivityResult(" + requestCode + "," + resultCode + "," + data);

        // Pass on the activity result to the helper for handling
        if (mHelper != null && mHelper.handleActivityResult(requestCode, resultCode, data))
        {
            Log.d(TAG, "onActivityResult handled by IABUtil.");
            return;
        }

        // not handled, so handle it ourselves (here's where you'd
        // perform any handling of activity results not related to in-app
        // billing...

        super.onActivityResult(requestCode, resultCode, data);
    }