Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

In app billing v3 NullPointerException

To test out in app billing v3 for Android I implemented a dialog which adds a single choice items adapter. I've added the test Skus, "android.test.purchased", "android.test.canceled", "android.test.refunded", "android.test.item_unavailable".

When I use the dialog to launch a purchase flow everything is fine, I am able to purchase the item and the item is most definitely purchased. However, I get a nullpointerexception when my app then tries to refresh the UI. I know the refresh works.

Here's my logcat:

12-16 01:06:06.706: I/Running inventory query with(20846): android.test.purchased
12-16 01:06:06.706: I/Running details query with(20846): SkuDetails:{"title":"Sample Title","price":"£0.61","type":"inapp","description":"Sample description for product: android.test.purchased.","productId":"android.test.purchased"}
12-16 01:06:06.706: I/Running details query with(20846): SkuDetails:{"title":"Sample Title","price":"£0.61","type":"inapp","description":"Sample description for product: android.test.purchased.","productId":"android.test.purchased"}
12-16 01:06:06.706: I/Running inventory query with(20846): android.test.canceled
12-16 01:06:06.706: I/Running details query with(20846): null
12-16 01:06:06.706: I/Running details query with(20846): null
12-16 01:06:06.706: D/AndroidRuntime(20846): Shutting down VM
12-16 01:06:06.706: W/dalvikvm(20846): threadid=1: thread exiting with uncaught exception (group=0x40d12930)
12-16 01:06:06.706: E/AndroidRuntime(20846): FATAL EXCEPTION: main
12-16 01:06:06.706: E/AndroidRuntime(20846): java.lang.NullPointerException
12-16 01:06:06.706: E/AndroidRuntime(20846): at com.example.test.MainActivity$1.onQueryInventoryFinished(MainActivity.java:201)
12-16 01:06:06.706: E/AndroidRuntime(20846): at com.example.test.util.IabHelper$2$1.run(IabHelper.java:536)
12-16 01:06:06.706: E/AndroidRuntime(20846): at android.os.Handler.handleCallback(Handler.java:725)
12-16 01:06:06.706: E/AndroidRuntime(20846): at android.os.Handler.dispatchMessage(Handler.java:92)
12-16 01:06:06.706: E/AndroidRuntime(20846): at android.os.Looper.loop(Looper.java:137)
12-16 01:06:06.706: E/AndroidRuntime(20846): at android.app.ActivityThread.main(ActivityThread.java:5039)
12-16 01:06:06.706: E/AndroidRuntime(20846): at java.lang.reflect.Method.invokeNative(Native Method)
12-16 01:06:06.706: E/AndroidRuntime(20846): at java.lang.reflect.Method.invoke(Method.java:511)
12-16 01:06:06.706: E/AndroidRuntime(20846): at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:793)
12-16 01:06:06.706: E/AndroidRuntime(20846): at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:560)
12-16 01:06:06.706: E/AndroidRuntime(20846): at dalvik.system.NativeStart.main(Native Method)

for (String s : allSkus) {
Log.i("Running inventory query with", "" + s);
SkuDetails c = inv.getSkuDetails(s);
Log.i("Running details query with", "" + c);
if (inv.hasPurchase(s)) {
    purchaseArray.add(c.getTitle());
} else {
    **LINE 201** objects.add(c.getPrice() + "  T:" + c.getSku());
}

allSkus is an ArrayList which holds the 4 skus above.

The nullpointer is SkuDetails c = inv.getSkuDetails(s);

Which returns null on the UI refresh. But the issue is that it seems to work for the first sku (android.test.purchased) but is null for the second sku (android.test.canceled) and that too it is only null when it runs after having bought another item (refunded or purchased). However if I subsequently open it again, it's fine and no nullpointerexception is thrown.

If I add a null check before adding to the ArrayList objects, then no items are added as every item after or before the bought item is returning null on inv.getSkuDetails(s)

like image 918
AndroidPenguin Avatar asked Dec 16 '12 01:12

AndroidPenguin


2 Answers

This had me stumped and the accepted answer did not contain the pertinent details.

What you need to do is pass a List with the SKUs you want to query (whether they are purchased or not) after calling startSetup. So it would look something like the code below instead of what is provided in the (inadequate) boilerplate TrivialDrive example.

mHelper.queryInventoryAsync(true, skuList, mGotInventoryListener);

Also, it looks like there are some phantom methods (that are still not yet cleaned up in the comments, which are also inaccurate)... more details of that bug here:

http://code.google.com/p/marketbilling/issues/detail?id=98

like image 142
logray Avatar answered Nov 15 '22 18:11

logray


Figured it out, leaving this for anyone who has the same problem as me. In the UI refresh I was calling the IabHelper query without querying the details of the skus. Thus precached skus had details, but those that weren't, failed.

like image 4
AndroidPenguin Avatar answered Nov 15 '22 17:11

AndroidPenguin