Исключение для выставления счетов на Android

Я тестирую свой биллинг, и у меня есть это исключение:

java.lang.IllegalStateException: Can't start async operation (launchPurchaseFlow) because another async operation(launchPurchaseFlow) is in progress.
        at utils.IabHelper.flagStartAsync(IabHelper.java:711)
        at utils.IabHelper.launchPurchaseFlow(IabHelper.java:316)
        at utils.IabHelper.launchPurchaseFlow(IabHelper.java:294)
        at com.problemio.SubscribeIntroActivity$6.onClick(SubscribeIntroActivity.java:117)
        at android.view.View.performClick(View.java:2532)
        at android.view.View$PerformClick.run(View.java:9308)
        at android.os.Handler.handleCallback(Handler.java:587)
        at android.os.Handler.dispatchMessage(Handler.java:92)
        at android.os.Looper.loop(Looper.java:150)
        at android.app.ActivityThread.main(ActivityThread.java:4293)
        at java.lang.reflect.Method.invokeNative(Native Method)
        at java.lang.reflect.Method.invoke(Method.java:507)
        at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:839)
        at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:597)
        at dalvik.system.NativeStart.main(Native Method)

После того, как я запустил этот код:

    Button subscribe = (Button)findViewById(R.id.subscribe);
    subscribe.setOnClickListener(new Button.OnClickListener() 
    {  
       public void onClick(View v) 
       {              
           // FIRST CHECK IF THE USER IS ALREADY A SUBSCRIBER.
          mHelper.launchPurchaseFlow(SubscribeIntroActivity.this, SUBSCRIBE_SKU, RC_REQUEST, mPurchaseFinishedListener);

       }
    });   

Но до этого я запускал его как тестовый пользователь и с идентификатором тестового продукта, который был следующим: android.test.purchased, и это сработало. Но когда я изменил идентификатор продукта на один из моих собственных идентификаторов продуктов, он разбился, за исключением указанного выше.

Есть идеи, почему это произошло? Спасибо!


person Oyoyoy    schedule 02.01.2013    source источник
comment
спасибо, но как воспроизвести эту ошибку, не могли бы вы предоставить мне шаги, пользователи сообщают об этом, но я не могу воспроизвести   -  person Goofy    schedule 17.09.2013


Ответы (4)


IabHelper позволит выполнять только один асинхронный запрос за раз. Вам нужно реализовать onActivityResult() и передать параметры в метод handleActivityResult() IabHelper.

Пример кода биллинга в приложении реализует метод следующим образом:

@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
    Log.d(TAG, "onActivityResult(" + requestCode + "," + resultCode + "," + data);

    // Pass on the activity result to the helper for handling
    if (!mHelper.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.");
    }
}
person ashughes    schedule 02.01.2013
comment
спасибо, да, я не понимал, что это необходимый метод для реализации. Есть ли порядок, когда я звоню? Или это вызывается системой? - person Oyoyoy; 03.01.2013
comment
Он вызывается системой, когда пользователь возвращается к вашей активности с экрана покупки (независимо от того, нажал ли он кнопку «Назад», завершил покупку и т. д.). Затем IabHelper позвонит вашему mPurchaseFinishedListener и сообщит результат покупки. - person ashughes; 03.01.2013
comment
Спасибо. Моя основная проблема заключается в том, что я получаю сообщение об ошибке «Предмет не найден», когда пытаюсь купить предмет. Но это сработало, когда я использовал тестовый элемент следующим образом: android.test.purchased ... вы случайно не знаете, в чем может быть проблема? - person Oyoyoy; 03.01.2013
comment
Чтобы протестировать покупку реального предмета, вам нужно загрузить версию своего приложения в консоль разработчика (но вам не нужно ее публиковать), и вы должны использовать ту же (подписанную) версию для тестирования. Google Play также требуется некоторое время для обработки/распространения новых добавленных элементов... так что, к сожалению, иногда вам просто нужно подождать. Ознакомьтесь с developer.android.com/training/in- app-billing/test-iab-app.html, если вы еще этого не сделали. - person ashughes; 03.01.2013
comment
Я только что разместил этот вопрос здесь, если вы хотите получить баллы за ответ: stackoverflow.com/questions/14130477/ - person Oyoyoy; 03.01.2013
comment
У меня есть одна проблема: я загрузил приложение в консоль dveloper (неопубликовано). Но я не уверен, как поставить неопубликованный элемент на устройство из консоли. - person Oyoyoy; 03.01.2013
comment
@Oyoyoy: если вас спрашивают, как разместить неопубликованное приложение на устройстве, вы можете просто использовать: abd install appname.apk - person gcl1; 13.04.2013
comment
onActivityResult() также не решил проблему, по-прежнему получая исключение при нажатии кнопки "Купить" второй раз - person Muhammad Babar; 10.05.2013
comment
Я также использую образец и получаю то же исключение. Вызов onActivityResult() определенно выполняется. - person user291701; 20.05.2013
comment
я реализовал это, но все равно получаю исключение, любое другое решение? - person Goofy; 17.09.2013
comment
Хотя ответ @ashughes верен, есть еще один случай, когда эта ошибка возникает, т. Е. Когда пользователь дважды нажимает кнопку. Решение было бы либо установить флаг при вызове launchPurchaseFlow и снять его в onActivityResult, либо просто поймать IllegalStateException - person defhlt; 02.03.2015
comment
Этот элегантный фрагмент кода работал намного лучше, чем тривиальные реализации onActivityResult() в коде привода или шаблона. - person Androidcoder; 07.08.2015

На случай, если кто-то, как я, скучает по лесу за деревьями...

Я получил трассировку стека java.lang.IllegalStateException в консоли разработчика Play, которая не предоставила ничего, кроме сообщения об ошибке... так что я был в тупике.

Сначала я не мог понять, как это происходит, потому что мне никогда не приходило в голову дважды нажать кнопку, которая запускает IAB! (он выглядит отключенным после первого касания из-за наложения, которое позволяет касаться, [иногда]).

Итак, убедитесь, что ваши пользователи не могут нажать вашу кнопку дважды.

person David Murdoch    schedule 24.11.2015

Вы используете пример кода Google, и в строке 793 класса IabHelper есть этот фрагмент кода

 if (mAsyncInProgress) throw new IllegalStateException("Can't start async operation (" +
            operation + ") because another async operation(" + mAsyncOperation + ") is in       progress.");

и когда вы совершаете покупку в первый раз, «mAsyncInProgress» становится истинным, и до тех пор, пока вы не израсходуете свою покупку, она остается истинной, поэтому вам нужно использовать свою покупку. Я рекомендую вам полностью прочитать все классы в пакете util, это поможет вам.

после любой удачной покупки нужно ее потреблять

mHelper.consumeAsync(purchase, mConsumeFinishedListener)

но иногда запрос на потребление не выполняется, поэтому вам нужно обрабатывать свои покупки каждый раз, когда создается ваша активность:

mHelper.queryInventoryAsync(mGotInventoryListener);

и попробуйте использовать ваши покупки в обратном вызове mGotInventoryListener.

person sadegh saati    schedule 14.11.2013
comment
Потребление покупок — это модель выставления счетов. Вы хотите потреблять, когда хотите позволить пользователю повторно купить больше одного и того же продукта. Здесь у нас есть проблема, когда мы отправляем покупку, а затем поворачиваем телефон (или в этом случае нажимаем кнопку покупки во второй раз), и выдается новый запрос на покупку, в то время как первый все еще находится на рассмотрении. - person eugene; 03.12.2014

получить последнюю версию библиотеки здесь: https://code.google.com/p/marketbilling/source/browse/ где исправили проблему

person user3681346    schedule 27.05.2014