I am trying to implement in-app-billing for my application.
I follow the implementation used in the Google TriviaDrive sample application and the related documentation on the developer's website.
My code works as expected, but when I try to "Request items available for purchase" , the resulting Inventory object contains 0 objects, although I have created a product.
I created a managed product with the paid_version ID using the Google Play Developer Console, as shown in the image below: 
The documentation states that "To get product details, call queryInventoryAsync(boolean, List, QueryInventoryFinishedListener) in your IabHelper instance."
In my own code, I call mHelper.queryInventoryAsync(true, iabItemSkus, mQueryFinishedListener)
Where:
mHelper - my instance of IabHelper
iabItemSkus is a list containing one item with the value "paid_version"
mQueryFinishedListener is my listener defined below.
IabHelper.QueryInventoryFinishedListener mQueryFinishedListener = new IabHelper.QueryInventoryFinishedListener() { @Override public void onQueryInventoryFinished(IabResult result, Inventory inv) { if (result.isFailure()) { Log.d(TAG, "Querying Inventory Failed: " + result); return; } Log.d(TAG, "Title: " + inv.getSkuDetails(SKU_PAID).getTitle()); Log.d(TAG, "Description: " + inv.getSkuDetails(SKU_PAID).getDescription()); Log.d(TAG, "Price = " + inv.getSkuDetails(SKU_PAID).getPrice()); } };
But when debugging, I see that the Inventory object passed back to the QueryInventoryFinishedListener contains 0 elements, and therefore calls like inv.getSkuDetails(SKU_PAID).getTitle() provide a null pointer exception.
I can’t understand where I am going wrong. I expected the Inventory object to contain the details for my paid_version product in the application.
Below are only parts of my code and LogCat that I think are relevant to this problem (trying to avoid code overload!), But if more detailed information about any other part of the code is useful, let me know.
From my activity:
... private static final String SKU_PAID = "paid_version"; private static final String TAG = "MyActivity"; private IabHelper mHelper; ... IabHelper.QueryInventoryFinishedListener mQueryFinishedListener = new IabHelper.QueryInventoryFinishedListener() { @Override public void onQueryInventoryFinished(IabResult result, Inventory inv) { if (result.isFailure()) { Log.d(TAG, "Querying Inventory Failed: " + result); return; } Log.d(TAG, "Title: " + inv.getSkuDetails(SKU_PAID).getTitle()); // <-- Line 266 of MyActivity.java Log.d(TAG, "Description: " + inv.getSkuDetails(SKU_PAID).getDescription()); Log.d(TAG, "Price = " + inv.getSkuDetails(SKU_PAID).getPrice()); } }; ... @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); ... final List<String> iabItemSkus = new ArrayList<String>(); iabItemSkus.add(SKU_PAID); // In App Billing String base64EncodedPublicKey = "... My Public Key ..."; mHelper = new IabHelper(this, base64EncodedPublicKey); mHelper.enableDebugLogging(true); mHelper.startSetup(new IabHelper.OnIabSetupFinishedListener() { @Override public void onIabSetupFinished(IabResult result) { if (!result.isSuccess()) { Log.d(TAG, "Problem setting up In-app Billing: " + result); } // Have we been disposed of in the meantime? If so, quit. if (mHelper == null) return; // IAB is fully set up. Now, let get list of available items Log.d(TAG, "Setup successful. Querying inventory."); mHelper.queryInventoryAsync(true, iabItemSkus, mQueryFinishedListener); } }); ... }
From my LogCat:
... 05-13 19:46:59.609 22390-22390/xxx.xxxxxx.xxxxxx D/IabHelper﹕ Starting in-app billing setup. 05-13 19:46:59.629 22390-22390/xxx.xxxxxx.xxxxxx D/IabHelper﹕ Billing service connected. 05-13 19:46:59.629 22390-22390/xxx.xxxxxx.xxxxxx D/IabHelper﹕ Checking for in-app billing 3 support. 05-13 19:46:59.629 22390-22390/xxx.xxxxxx.xxxxxx D/IabHelper﹕ In-app billing version 3 supported for xxx.xxxxxx.xxxxxx 05-13 19:46:59.639 22390-22390/xxx.xxxxxx.xxxxxx D/IabHelper﹕ Subscriptions AVAILABLE. 05-13 19:46:59.639 22390-22390/xxx.xxxxxx.xxxxxx D/MyActivity﹕ Setup successful. Querying inventory. 05-13 19:46:59.639 22390-22390/xxx.xxxxxx.xxxxxx D/IabHelper﹕ Starting async operation: refresh inventory 05-13 19:46:59.649 22390-22596/xxx.xxxxxx.xxxxxx D/IabHelper﹕ Querying owned items, item type: inapp 05-13 19:46:59.649 22390-22596/xxx.xxxxxx.xxxxxx D/IabHelper﹕ Package name: xxx.xxxxxx.xxxxxx 05-13 19:46:59.649 22390-22596/xxx.xxxxxx.xxxxxx D/IabHelper﹕ Calling getPurchases with continuation token: null 05-13 19:46:59.659 22390-22596/xxx.xxxxxx.xxxxxx D/IabHelper﹕ Owned items response: 0 05-13 19:46:59.659 22390-22596/xxx.xxxxxx.xxxxxx D/IabHelper﹕ Continuation token: null 05-13 19:46:59.659 22390-22596/xxx.xxxxxx.xxxxxx D/IabHelper﹕ Querying SKU details. 05-13 19:46:59.689 22390-22596/xxx.xxxxxx.xxxxxx D/IabHelper﹕ Querying owned items, item type: subs 05-13 19:46:59.689 22390-22596/xxx.xxxxxx.xxxxxx D/IabHelper﹕ Package name: xxx.xxxxxx.xxxxxx 05-13 19:46:59.689 22390-22596/xxx.xxxxxx.xxxxxx D/IabHelper﹕ Calling getPurchases with continuation token: null 05-13 19:46:59.699 22390-22596/xxx.xxxxxx.xxxxxx D/IabHelper﹕ Owned items response: 0 05-13 19:46:59.699 22390-22596/xxx.xxxxxx.xxxxxx D/IabHelper﹕ Continuation token: null 05-13 19:46:59.699 22390-22596/xxx.xxxxxx.xxxxxx D/IabHelper﹕ Querying SKU details. 05-13 19:46:59.829 22390-22596/xxx.xxxxxx.xxxxxx D/IabHelper﹕ Ending async operation: refresh inventory 05-13 19:46:59.829 22390-22390/xxx.xxxxxx.xxxxxx D/AndroidRuntime﹕ Shutting down VM 05-13 19:46:59.829 22390-22390/xxx.xxxxxx.xxxxxx W/dalvikvm﹕ threadid=1: thread exiting with uncaught exception (group=0x41b31ba8) 05-13 19:46:59.839 22390-22390/xxx.xxxxxx.xxxxxx E/AndroidRuntime﹕ FATAL EXCEPTION: main Process: xxx.xxxxxx.xxxxxx, PID: 22390 java.lang.NullPointerException at xxx.xxxxxx.xxxxxx.MyActivity$1.onQueryInventoryFinished(MyActivity.java:266) at xxx.xxxxxx.xxxxxx.util.IabHelper$2$1.run(IabHelper.java:630) at android.os.Handler.handleCallback(Handler.java:733) at android.os.Handler.dispatchMessage(Handler.java:95) at android.os.Looper.loop(Looper.java:136) at android.app.ActivityThread.main(ActivityThread.java:5017) at java.lang.reflect.Method.invokeNative(Native Method) at java.lang.reflect.Method.invoke(Method.java:515) at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:779) at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:595) at dalvik.system.NativeStart.main(Native Method) ...
PS: I just updated my code to highlight line 266.
Additionally
I experienced this problem 12 hours after loading the APK, and as you can see from LogCat, it indicates "In-app billing version 3 supported" for my application.
The problem persisted whether I was set to IN-APP PRODUCT status active or inactive.
Now, after 24 hours, he magically decides to work correctly.
From this, I can only determine that it was a problem with Google Play, and not with my code.