问题
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) {
...
回答1:
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);
回答2:
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.
回答3:
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.
回答4:
In "L" binding to a service requires using an explicit intent.
See http://commonsware.com/blog/2014/06/29/dealing-deprecations-bindservice.html
回答5:
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).
回答6:
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");
回答7:
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.
回答8:
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.
回答9:
This worked for me but I'd like to know of it's an acceptable way to do this:
i.setClass(context, MyService.class);
回答10:
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
来源:https://stackoverflow.com/questions/24480069/google-in-app-billing-illegalargumentexception-service-intent-must-be-explicit