Google In-App结算,IllegalArgumentException:在升级到Android L Dev Preview之后,Service Intent必须是显式的

我的应用内结算代码工作正常,直到我升级到Android L Dev Preview。 现在我的应用程序启动时出现此错误。 有谁知道什么改变了L导致这个或我应该如何改变我的代码来解决这个问题?

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.+' ... ... 

应用程序启动时的错误:

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

InfoPanel.java中的第709行:

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

我有同样的问题,并明确设置解决scheme。 类似阿列克谢的答案,但更简单:

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

正如在下面的回答中指出的,解决scheme将是手动创build明确的意图:

 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; } 

这里是L预览源中的代码来检查显式的意图。 目前它已经被评论了 ,但是在具有L预览的Nexus 5上它仍然运行,并为隐式意图抛出exception。

编辑:@阿拉夫的答案是更好,更简单。 只需添加

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

所有的学分给他 。 这里是L版本源代码,用于检查显式的意图。

find清晰的解决scheme: https : //code.google.com/p/android-developer-preview/issues/detail?id = 1674

在Google Licensing Library(LVL)LicenseChecker.java文件中,将“bindService”调用replace为:

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

并在AndroidManifest.xml中设置:android:minSdkVersion =“4”

“setPackage”需要Android版本4。

在“L”中绑定到服务需要使用明确的意图。

请参阅http://commonsware.com/blog/2014/06/29/dealing-deprecations-bindservice.html

只需更换代码

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

用下面的代码

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

IabHelper类中放置在不可用的utils文件夹中(如果您遵循Google InApp Billing教程的说明)。

我从旧的Google Cloud Messaging安装程序代码中得到了同样的错误。 最简单的修复似乎正在改变

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

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

对我来说,它使用样本中的当前IabHelper:sdk / extras / google / play_billing / samples / TrivialDrive / src / com / example / android / trivialdrivesample / util / IabHelper.java

不要忘记先运行sdk更新pipe理器,以确保你已经安装了当前版本。

这个特定问题的答案已经发布,但只是为了帮助其他人完全相同的问题,但这次是许可证API。

在上面发布的IAP库中,你会得到与5.0消息相同的错误,但是你可以find一个修复(包括手动修改LicenseChecker.java中的几行代码(Google的代码),然后重新编译包含这个库的项目)。

有关详细信息,请参阅https://code.google.com/p/android/issues/detail?id=78505 。 希望任何人都可以使用它。

这工作对我来说,但我想知道这是一个可以接受的方式来做到这一点:

i.setClass(context,MyService.class);