In app billing v3 NullPointerException

android, in-app-billing, nullpointerexception

Solution

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.

Problem

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)

Original source