Исключение биллинга в 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, и он сработал. Но когда я изменил идентификатор продукта на один из моих собственных идентификаторов продуктов, он разбился с исключением выше.

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

Ответ 1

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 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.");
    }
}

Ответ 2

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

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

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

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

Ответ 3

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

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

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

после любой успешной покупки вам нужно ее использовать

mHelper.consumeAsync(purchase, mConsumeFinishedListener)

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

mHelper.queryInventoryAsync(mGotInventoryListener);

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