Android в биллинге приложений: не удается запустить launchPurchaseFlow, потому что выполняется launchPurchaseFlow
я реализую в биллинге приложений в первый раз, и я тестирую свои первые покупки, используя статические идентификаторы SKU.
это сработало очень хорошо в первый раз. Я позвал!--2--> и завершается проверочной закупки. Моя деятельность получила onActivityResult
обратный вызов, и я убедился, чтобы обработать его с mHelper.handleActivityResult(...)
. Все было замечательно.
@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
// Pass on the activity result to the helper for handling
log("onActivityResult");
if (!this.mHelper.handleActivityResult(requestCode, resultCode, data)) {
log("cleared the launch flow");
// not handled, so handle it ourselves (here's where you'd
// perform any handling of activity results not related to in-app
// billing...
super.onActivityResult(requestCode, resultCode, data);
}
}
однако я хотел протестировать следующую часть, поэтому я перезапустил приложение и попытался купить тот же SKU (статический purchased
SKU).
mHelper.launchPurchaseFlow(rootActivity, "android.test.purchased", 10002,
new IabHelper.OnIabPurchaseFinishedListener() {
@Override
public void onIabPurchaseFinished(IabResult result, Purchase purchaseInfo) {
if (result.isFailure()) {
log("purchased failed");
} else {
log("purchase succeeded");
}
}
}, "bGoa+V7g/yqDXvKRqq+JTFn4uQZbPiQJo4pf9RzJ");
второй раз, когда я пытаюсь купить товар, мой OnIabPurchaseFinishedListener
называется и вижу purchase failed
в моем журнале: "ошибка выставления счетов в приложении: невозможно купить товар, ответ на ошибку: 7: товар уже принадлежит"
это имеет смысл, но если я попытаюсь купить другой элемент, то мое приложение вылетает со следующей ошибкой:
java.ленг.IllegalStateException: не удается запустить асинхронную операцию (launchPurchaseFlow) потому что другой асинхронный операция (launchPurchaseFlow) является в процессе.
на onActivityResult
обратный вызов не происходит, когда я пытаюсь сделать покупку, которая терпит неудачу, поэтому поток запуска, который потерпел неудачу, не обрабатывается и не очищается. Поэтому, когда я пробую другую покупку, она падает, потому что она все еще предположительно находится в середине последней неудачной транзакции.
что я делаю не так? Как убедиться, что launchPurchaseFlow() очищается после сбоя?
6 ответов
Я считаю, что вам просто нужно получить обновленный код классов биллинга в приложении, и вы не должны снова столкнуться с той же проблемой.
Google еще не вытолкнул изменения в Диспетчере SDK, насколько я знаю. Просто скопируйте / вставьте новые классы в свой, и вы больше не должны сталкиваться с проблемой.
посмотрите на новые изменения кода здесь: https://code.google.com/p/marketbilling/source/detail?r=7ec85a9b619fc5f85023bc8125e7e6b1ab4dd69f&path=/v3/src/com/example/android/trivialdrivesample/MainActivity.java
классы, которые были изменены по состоянию на 15 марта: IABHelper.java, инвентарь.java, SkuDetails.java и некоторые из MainActivity.файл java
Я знаю, что это своего рода поздний вклад в вопрос, но сегодня я столкнулся с той же проблемой, и я звонил в приложение биллинга в фрагменте, поэтому я посмотрел в "labHelper.java", и я видел прямое решение, которое я считаю проблемой, которая есть ... Я изменил метод "void flagStartAsync (String operation)" в labHelper.java должен быть следующим
void flagStartAsync(String operation) {
if (mAsyncInProgress) {
flagEndAsync();
}
if (mAsyncInProgress) throw new IllegalStateException("Can't start async operation (" +
operation + ") because another async operation(" + mAsyncOperation + ") is in progress.");
mAsyncOperation = operation;
mAsyncInProgress = true;
logDebug("Starting async operation: " + operation);
}
Я надеюсь, что это поможет кому-то там ...
для меня лучшим решением было как udpate код к недавнему (здесь), и делать, что этот пост предлагаем:
1) Сделать метод
flagEndAsync
общественности. Она есть, просто не видно.2) у каждого слушателя называть
iabHelper.flagEndAsync
чтобы убедиться, что процедура отмечена правильно; кажется, это необходимо во всех слушателях.3) объемные вызовы с
try/catch
пойматьIllegalStateException
что может произойти, и обработать его таким образом.
причина, по которой обновление кода было недостаточно, заключается в том, что я нашел особые случаи, когда эта ошибка все еще происходит (или, по крайней мере, один):
- отключение от сети Интернет;
- введите ваши приложения;
- пусть он инициализирует
IabHelper
; - подключение к интернету;
- после подключения устройства попробуйте совершить покупку.
у меня такая же проблема.
первая попытка: обходной путь
Я скачал ток IabHelper.java, согласно jmrmb80 это, но это не сработало. (Похоже, что РЕПО сейчас устаревший и мы должны полагаться на версию, поставляемую Android SDK manager.) Поэтому я последовал совет Хана:
- определить IabHelper.flagEndAsync() как public, и
- добавить
iabHelper.flagEndAsync()
доiabHelper.launchPurchaseFlow(...)
Это похоже на откровенную халтуру! И это может иметь нежелательные побочные эффекты. Но это "работает"...
Это, кажется, известная ошибка: #134 и #189.
вторая попытка: исправление
после дальнейшего расследования, я не думаю, что приведенное выше решение решить мою проблему. Я думаю, что реальное решение - переопределение onActivityResult
в потоке пользовательского интерфейса.
Не нужно богатство решений. Действие или фрагмент, запрашивающий поток покупки, должен иметь следующее:
@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
Log.d(TAG, "onActivityResult(" + requestCode + "," + resultCode + "," + data);
if (billingHelper == null) return;
// Pass on the activity result to the helper for handling
if (!billingHelper.handleActivityResult(requestCode, resultCode, data)) {
// not handled, so handle it ourselves (here's where you'd
// perform any handling of activity results not related to in-app
// billing...
super.onActivityResult(requestCode, resultCode, data);
}
else {
Log.d(TAG, "onActivityResult handled by IABUtil.");
}
}
Это из примера проекта Google, попробовал его на моем проекте, и он работает.
Error response: 7:Item Already Owned
означает, что вы купили товар, но вы еще не потребляли его, и вы пытаетесь купить его снова.
Это случилось со мной, когда я установил в AndroidManifest launchMode в моей активности в приложении к singleInstance
. Приложение всегда заканчивается с ошибкой, которую вы описали.
чтобы избежать такого поведения, измените launchMode на любое другое значение, соответствующее вашим потребностям
android:launchMode="singleInstance"
->android:launchMode="singleTask"
Я не пытался глубоко понять, почему singleInstance не работает. Если кто-то знает пожалуйста, предоставьте больше информации.
поэтому моим решением было изменить launchMode и потреблять уже принадлежащий элемент. С тех пор IAP отлично работает для меня.