Google In-App billing, IllegalArgumentException: Service Intent must be explicit, after upgrading to Android L Dev Preview

AndroidAndroid IntentIn App-BillingIllegalargumentexceptionAndroid 5.0-Lollipop

Android Problem Overview


My in-app billing code was working fine until I upgraded to the Android L Dev Preview. Now I get this error when my app starts. Does anyone know what's changed about L that causes this or how I should change my code to fix this?

android {
compileSdkVersion 'android-L'
buildToolsVersion '20'
defaultConfig {
    minSdkVersion 13
    targetSdkVersion 'L'
...
...


compile 'com.google.android.gms:play-services:5.+'
compile 'com.android.support:support-v13:21.+'
compile 'com.android.support:appcompat-v7:21.+'
...
...

The error when the app starts:

06-29 16:22:33.281    5719-5719/com.tbse.wnswfree D/AndroidRuntime﹕ Shutting down VM
06-29 16:22:33.284    5719-5719/com.tbse.wnswfree E/AndroidRuntime﹕ FATAL EXCEPTION: main
Process: com.tbse.wnswfree, PID: 5719
java.lang.RuntimeException: Unable to start activity ComponentInfo{com.tbse.wnswfree/com.tbse.wnswfree.InfoPanel}: java.lang.IllegalArgumentException: Service Intent must be explicit: Intent { act=com.android.vending.billing.InAppBillingService.BIND }
        at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2255)
        at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2317)
        at android.app.ActivityThread.access$800(ActivityThread.java:143)
        at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1258)
        at android.os.Handler.dispatchMessage(Handler.java:102)
        at android.os.Looper.loop(Looper.java:135)
        at android.app.ActivityThread.main(ActivityThread.java:5070)
        at java.lang.reflect.Method.invoke(Native Method)
        at java.lang.reflect.Method.invoke(Method.java:372)
        at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:836)
        at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:631)
 Caused by: java.lang.IllegalArgumentException: Service Intent must be explicit: Intent { act=com.android.vending.billing.InAppBillingService.BIND }
        at android.app.ContextImpl.validateServiceIntent(ContextImpl.java:1603)
        at android.app.ContextImpl.bindServiceCommon(ContextImpl.java:1702)
        at android.app.ContextImpl.bindService(ContextImpl.java:1680)
        at android.content.ContextWrapper.bindService(ContextWrapper.java:528)
        at com.tbse.wnswfree.util.IabHelper.startSetup(IabHelper.java:262)
        at com.tbse.wnswfree.InfoPanel.onStart(InfoPanel.java:709)
        at android.app.Instrumentation.callActivityOnStart(Instrumentation.java:1217)
        at android.app.Activity.performStart( Activity.java:5736)
        at android.app.ActivityThread.performLaunchActivity( ActivityThread.java:2218)
        at android.app.ActivityThread.handleLaunchActivity( ActivityThread.java:2317)
        at android.app.ActivityThread.access$800( ActivityThread.java:143)
        at android.app.ActivityThread$H.handleMessage( ActivityThread.java:1258)
        ...

           

Line 709 in InfoPanel.java:

        mHelper.startSetup(new IabHelper.OnIabSetupFinishedListener() {
          @Override
          public void onIabSetupFinished(IabResult result) {
            ...
          

Android Solutions


Solution 1 - Android

I had the same problem and explicitly setting the package solved it. Similar to Aleksey's answer, but simpler:

Intent intent = new Intent("com.android.vending.billing.InAppBillingService.BIND");
// This is the key line that fixed everything for me
intent.setPackage("com.android.vending");

getContext().bindService(intent, serviceConnection, Context.BIND_AUTO_CREATE);

Solution 2 - Android

As pointed out in answer below, solutions would be to create explicit intent manually:

private Intent getExplicitIapIntent() {
        PackageManager pm = mContext.getPackageManager();
        Intent implicitIntent = new Intent("com.android.vending.billing.InAppBillingService.BIND");
        List<ResolveInfo> resolveInfos = pm.queryIntentServices(implicitIntent, 0);

        // Is somebody else trying to intercept our IAP call?
        if (resolveInfos == null || resolveInfos.size() != 1) {
            return null;
        }

        ResolveInfo serviceInfo = resolveInfos.get(0);
        String packageName = serviceInfo.serviceInfo.packageName;
        String className = serviceInfo.serviceInfo.name;
        ComponentName component = new ComponentName(packageName, className);
        Intent iapIntent = new Intent();
        iapIntent.setComponent(component);
        return iapIntent;
    }

Here is the code in L preview sources for check explicit intent. It's got commented currently, but on Nexus 5 with L preview it still runs and throws exception for implicit intents.


Edit: @alav's answer is much more better and simpler. Just add

intent.setPackage("com.android.vending");

All credits for him. And here is the code in L release sources for check explicit intent.

Solution 3 - Android

Found clear solution here: https://code.google.com/p/android-developer-preview/issues/detail?id=1674

In Google Licensing Library (LVL), LicenseChecker.java file, replace "bindService" call with this:

 Intent serviceIntent = new Intent(
         new String(Base64.decode("Y29tLmFuZHJvaWQudmVuZGluZy5saWNlbnNpbmcuSUxpY2Vuc2luZ1NlcnZpY2U=")));
         serviceIntent.setPackage("com.android.vending");

     boolean bindResult = mContext
             .bindService(
               serviceIntent,
               this, // ServiceConnection.
               Context.BIND_AUTO_CREATE);

AND in the AndroidManifest.xml set: android:minSdkVersion="4"

The "setPackage" requires Android version 4.

Solution 4 - Android

In "L" binding to a service requires using an explicit intent.

See http://commonsware.com/blog/2014/06/29/dealing-deprecations-bindservice.html

Solution 5 - Android

Just replace the code

boolean attempt = mContext.bindService(new Intent("com.android.vending.billing.InAppBillingService.BIND"),
                mServiceConn, Context.BIND_AUTO_CREATE);

with the following code

Intent serviceIntent = new Intent("com.android.vending.billing.InAppBillingService.BIND");
        serviceIntent.setPackage("com.android.vending");
        boolean attempt = mContext.bindService(serviceIntent, mServiceConn, Context.BIND_AUTO_CREATE);

in the class IabHelper which you have placed in the inappbilling's utils folder (if you have followed the instruction of Google InApp Billing tutorial).

Solution 6 - Android

I was getting the same error from older Google Cloud Messaging setup code. The simplest fix appears to be changing

Intent registrationIntent = new Intent(
        "com.google.android.c2dm.intent.REGISTER");

into

Intent registrationIntent = new Intent();
registrationIntent.setClassName("com.google.android.c2dm.intent", "REGISTER");

Solution 7 - Android

For me it worked to use the current IabHelper from the samples: sdk/extras/google/play_billing/samples/TrivialDrive/src/com/example/android/trivialdrivesample/util/IabHelper.java

Don't forget to run the sdk update manager first to make sure that you have the current version installed.

Solution 8 - Android

The answers for this specific problems have already been posted, but just to help out others with the exact same problem, but this time for the Licence API.

You get the same error on 5.0 message as in the IAP library posted above, but you can find a fix (involving manually changing a few lines in LicenseChecker.java (Google's code) and then recompiling your project that will include this library).

Check out: https://code.google.com/p/android/issues/detail?id=78505 for details. Hope anyone can use it.

Solution 9 - Android

This worked for me but I'd like to know of it's an acceptable way to do this:

i.setClass(context, MyService.class);

Solution 10 - Android

if you have below error please set targetSdkVersion 19 in the build.gradle. When i set 19 my problem solved. For publish i set targetSdkVersion 27

at com.google.android.vending.licensing.LicenseChecker.checkAccess(LicenseChecker.java:150) at com.google.android.vending.expansion.downloader.impl.DownloaderService$LVLRunnable.run

defaultConfig {
    applicationId "com.brain.math.game.free"
    minSdkVersion 15
    targetSdkVersion 19 

> targetSdkVersion 19

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
Questionelliptic1View Question on Stackoverflow
Solution 1 - AndroidalavView Answer on Stackoverflow
Solution 2 - AndroidOleksii MasnyiView Answer on Stackoverflow
Solution 3 - AndroidRoyView Answer on Stackoverflow
Solution 4 - AndroidckettiView Answer on Stackoverflow
Solution 5 - AndroidHarpreetView Answer on Stackoverflow
Solution 6 - AndroidDon ParkView Answer on Stackoverflow
Solution 7 - AndroidBjörn KechelView Answer on Stackoverflow
Solution 8 - AndroidzaifrunView Answer on Stackoverflow
Solution 9 - AndroidmidiwriterView Answer on Stackoverflow
Solution 10 - AndroidethemsulanView Answer on Stackoverflow