My app uses In App Billing and it works fine on my phone (Android 2.3.6
). But when I run it on the emulator (Android 4.4.2
) it keeps crashing when creating the helper for performing in app purchases. It throws a NullPointerException
:
mHelper = new IabHelper(MainActivity.this, base64EncodedPublicKey); mHelper.startSetup(new IabHelper.OnIabSetupFinishedListener() { public void onIabSetupFinished(IabResult result) { if (!result.isSuccess()) { Log.d("x", "In-app Billing setup failed: " + result); } else { Log.d("x", "In-app Billing is set up OK"); } } });
This answer says I should put the code above in a try-block and put the catch in the answer below it. I get an error when doing that and the recommended solution is putting that in a try-catch block too. Eventhough I did that, it still crashes.
Can anybody tell me how to do this? I'm completely stuck.
Stack trace:
12-24 10:59:51.908: E/AndroidRuntime(2273): FATAL EXCEPTION: main 12-24 10:59:51.908: E/AndroidRuntime(2273): Process: com.sandradiependaal.mediatie, PID: 2273 12-24 10:59:51.908: E/AndroidRuntime(2273): java.lang.NullPointerException 12-24 10:59:51.908: E/AndroidRuntime(2273): at com.sandradiependaal.meditatie.util.IabHelper.startSetup(IabHelper.java:267) 12-24 10:59:51.908: E/AndroidRuntime(2273): at com.sandradiependaal.meditatie.MainActivity$4.onItemClick(MainActivity.java:142) 12-24 10:59:51.908: E/AndroidRuntime(2273): at android.widget.AdapterView.performItemClick(AdapterView.java:299) 12-24 10:59:51.908: E/AndroidRuntime(2273): at android.widget.AbsListView.performItemClick(AbsListView.java:1113) 12-24 10:59:51.908: E/AndroidRuntime(2273): at android.widget.AbsListView$PerformClick.run(AbsListView.java:2904) 12-24 10:59:51.908: E/AndroidRuntime(2273): at android.widget.AbsListView$3.run(AbsListView.java:3638) 12-24 10:59:51.908: E/AndroidRuntime(2273): at android.os.Handler.handleCallback(Handler.java:733) 12-24 10:59:51.908: E/AndroidRuntime(2273): at android.os.Handler.dispatchMessage(Handler.java:95) 12-24 10:59:51.908: E/AndroidRuntime(2273): at android.os.Looper.loop(Looper.java:136) 12-24 10:59:51.908: E/AndroidRuntime(2273): at android.app.ActivityThread.main(ActivityThread.java:5017) 12-24 10:59:51.908: E/AndroidRuntime(2273): at java.lang.reflect.Method.invokeNative(Native Method) 12-24 10:59:51.908: E/AndroidRuntime(2273): at java.lang.reflect.Method.invoke(Method.java:515) 12-24 10:59:51.908: E/AndroidRuntime(2273): at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:779) 12-24 10:59:51.908: E/AndroidRuntime(2273): at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:595) 12-24 10:59:51.908: E/AndroidRuntime(2273): at dalvik.system.NativeStart.main(Native Method)
IabHelper.java:
Intent serviceIntent = new Intent("com.android.vending.billing.InAppBillingService.BIND"); serviceIntent.setPackage("com.android.vending"); if (!mContext.getPackageManager().queryIntentServices(serviceIntent, 0).isEmpty()) { // service available to handle that Intent mContext.bindService(serviceIntent, mServiceConn, Context.BIND_AUTO_CREATE); }
It's because the list returned is not just empty but it's actually null
. You can add a simple check if the list is null
. Why the implementation doesn't return empty list instead of null
is beyond my comprehension but it's just how it's built.
Change to this:
List<ResolveInfo> queryIntentServices = mContext.getPackageManager().queryIntentServices(serviceIntent, 0); if (queryIntentServices != null && !queryIntentServices.isEmpty()) { // service available to handle that Intent mContext.bindService(serviceIntent, mServiceConn, Context.BIND_AUTO_CREATE); }
This at least did the trick for me with the emulator. This is not needed in real device if implemented correctly.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With