Google In-App billing, IllegalArgumentException: намерение службы должно быть явным, после перехода на Android L Dev Preview
Мой код биллинга в приложении работал нормально, пока я не перешел на 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)
...
Линия 709 в InfoPanel.java:
mHelper.startSetup(new IabHelper.OnIabSetupFinishedListener() {
@Override
public void onIabSetupFinished(IabResult result) {
...
Ответы
Ответ 1
У меня была такая же проблема, и явная настройка пакета решила его. Как и Алексей отвечает, но проще:
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
Как указано в ответе ниже, решения заключались бы в создании явного намерения вручную:
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 для проверки явного намерения. Он получил в комментариях в настоящее время, но на Nexus 5 с предварительным просмотром L он все еще работает и генерирует исключение для неявных намерений.
Изменить: @alav ответ намного лучше и проще. Просто добавьте
intent.setPackage("com.android.vending");
Все кредиты для . И здесь - это код в источниках L для проверки явного намерения.
Ответ 3
Здесь найдено ясное решение:
https://code.google.com/p/android-developer-preview/issues/detail?id=1674
В библиотеке лицензирования Google (LVL), файле LicenseChecker.java замените вызов "bindService" следующим образом:
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.
Ответ 4
В привязке "L" к службе требуется использование явного намерения.
См. http://commonsware.com/blog/2014/06/29/dealing-deprecations-bindservice.html
Ответ 5
Просто замените код
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
, который вы поместили в папку inappbilling utils (если вы следуете инструкциям Google InApp Billing tutorial).
Ответ 6
Я получал ту же ошибку из старого кода настройки Cloud Cloud Messaging. Самое простое исправление, по-видимому, меняет
Intent registrationIntent = new Intent(
"com.google.android.c2dm.intent.REGISTER");
в
Intent registrationIntent = new Intent();
registrationIntent.setClassName("com.google.android.c2dm.intent", "REGISTER");
Ответ 7
Для меня это работало с использованием текущего IabHelper из образцов:
SDK/дополнительные/Google/play_billing/образцы/TrivialDrive/SRC/COM/пример/Android/trivialdrivesample/Util/IabHelper.java
Не забудьте сначала запустить диспетчер обновлений sdk, чтобы убедиться, что у вас установлена текущая версия.
Ответ 8
Ответы на эти конкретные проблемы уже были опубликованы, но только для того, чтобы помочь другим с той же проблемой, но на этот раз для лицензионного API.
Вы получите ту же ошибку в сообщении 5.0, что и в библиотеке IAP, опубликованной выше, но вы можете найти исправление (с помощью ручного изменения нескольких строк в LicenseChecker.java(код Google), а затем перекомпиляции вашего проекта, который будет включать эту библиотеку).
Подробнее: https://code.google.com/p/android/issues/detail?id=78505.
Надеюсь, кто-нибудь сможет его использовать.
Ответ 9
Это сработало для меня, но я хотел бы знать, что это приемлемый способ сделать это:
i.setClass(контекст, MyService.class);
Ответ 10
если у вас есть ошибка ниже, установите targetSdkVersion 19 в build.gradle.
Когда я установил 19, моя проблема решена. Для публикации я установите targetSdkVersion 27
в com.google.android.vending.licensing.LicenseChecker.checkAccess(LicenseChecker.java:150)
на com.google.android.vending.expansion.downloader.impl.DownloaderService $LVLRunnable.run
defaultConfig {
applicationId "com.brain.math.game.free"
minSdkVersion 15
targetSdkVersion 19
targetSdkVersion 19