58

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) {
            ...
MrEngineer13
  • 38,642
  • 13
  • 74
  • 93
elliptic1
  • 1,654
  • 1
  • 19
  • 22
  • This line and the code around it would be interesting: `com.tbse.wnswfree.util.IabHelper.startSetup(IabHelper.java:262)` – HHK Jun 29 '14 at 20:49
  • Hans - That's Google's code, you can see it here: http://goo.gl/KLMllR – elliptic1 Jun 30 '14 at 04:45
  • Possible duplicate of [Android L (API 21) - java.lang.IllegalArgumentException: Service Intent must be explicit](http://stackoverflow.com/questions/27183164/android-l-api-21-java-lang-illegalargumentexception-service-intent-must-be) – regisd Feb 20 '16 at 22:07

10 Answers10

118

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);
alav
  • 1,522
  • 1
  • 12
  • 13
  • 3
    Amazing - even in the latest IabHelper.java from Google this is missing. Not sure if this is only an requirement for 5.0 but it cant hurt to add it thats for sure. – slott Nov 28 '14 at 12:42
  • 3
    Last iAbHelper.java now includes that line (rev 5), however I still received the exact same error!? So I've added this to IapHelper: if (ris.get(0) != null && ris.get(0).serviceInfo != null) serviceIntent.setClassName(ris.get(0).serviceInfo.packageName, ris.get(0).serviceInfo.name); – 3c71 Jan 04 '15 at 10:00
  • @3c71 where did you get rev 5? – swalkner Jan 30 '15 at 08:42
  • Just a little note that this code is located in the IabHelper.java file in your "util" package. It was not obvious to me – Don Jul 05 '15 at 08:58
  • It is in LicenseChecker class now. – Noundla Sandeep Oct 30 '15 at 14:08
  • 2017 and the bug is still there. Unbelievable. – Rick77 Feb 19 '17 at 09:30
  • It's incredible that this bug still exists going on three years later. – Ethan Hohensee Jul 07 '17 at 14:57
  • Excellent! Saved me tons of time. Thanks! – tomurka Aug 09 '18 at 11:58
42

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.

Community
  • 1
  • 1
Oleksii Masnyi
  • 2,922
  • 2
  • 22
  • 27
  • This works (at least the warning is gone now). Additionally, you can enforce that there is a single app installed that resolves this action to also prevent piracy. – ekawas Oct 17 '14 at 20:04
  • 1
    Also posted a more general solution inspiring from this answer, if you are encountering this problem in something other than the IAB : http://blog.android-develop.com/2014/10/android-l-api-21-javalangillegalargumen.html – Sean Oct 19 '14 at 19:13
  • using this solution does correct the problem but for me creates another issue. Please see my question here: http://stackoverflow.com/questions/27495659/mservice-npe-on-android-5-0-devices – ez4nick Dec 16 '14 at 00:37
  • 2
    The official solution by Google (http://developer.android.com/google/play/billing/billing_integrate.html#billing-service) is to add serviceIntent.setPackage("com.android.vending") as in the answer by @alav – marmor Dec 16 '14 at 14:39
  • 2
    That does not work. This line is already in the last IabHelper.java since a long time, and I still got the errors. – Stéphane Jan 06 '15 at 08:58
6

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.

Roy
  • 673
  • 11
  • 21
  • We just updated our target SDK and hit this issue. Thanks for the fix. As a note this only affects devices running Android 5.0. Devices running 5.0.1 and up seem fine. – Danny Parker Apr 13 '15 at 13:21
3

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

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

cketti
  • 1,277
  • 11
  • 15
  • So I'm just wondering if we're supposed to use a solution like in the blog or if the IAP API will be updated. I suppose it'll be updated... – elliptic1 Jun 30 '14 at 04:45
  • @elliptic1 It's not fixed in the API 21 yesterday, so I'm not sure if it will be ever changed. :( – Sean Oct 19 '14 at 19:13
  • Also posted a more general solution inspiring from the marked answer, if you are encountering this problem in something other than the IAB : http://blog.android-develop.com/2014/10/android-l-api-21-javalangillegalargumen.html – Sean Oct 19 '14 at 19:16
  • 1
    Well, it's just incredible that Google hasn't updated their IABHelper code yet. None of these solutions are working for me on an Emulator running 5.0, which still crashes on bindService(). – Alchete Oct 22 '14 at 13:52
2

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).

Harpreet
  • 2,990
  • 3
  • 38
  • 52
1

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");
Don Park
  • 457
  • 5
  • 6
0

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.

Björn Kechel
  • 7,933
  • 3
  • 54
  • 57
0

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.

zaifrun
  • 931
  • 9
  • 21
0

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

i.setClass(context, MyService.class);

midiwriter
  • 426
  • 5
  • 12
0

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

ethemsulan
  • 2,241
  • 27
  • 19