Android In App Billing:无法启动launchPurchaseFlow,因为launchPurchaseFlow正在进行中

时间:2013-03-26 02:12:55

标签: android in-app-billing android-billing

我是第一次实施In App Billing,我正在使用静态SKU ID测试我的第一次购买。

第一次运作良好。我致电mHelper.launchPurchaseFlow(...)并完成了测试购买。我的活动收到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.lang.IllegalStateException:无法启动异步操作   (launchPurchaseFlow)因为另一个异步   operation(launchPurchaseFlow)正在进行中。

当我尝试进行失败的购买时,onActivityResult回调不会发生,因此失败的启动流程无法得到处理和清理。因此,当我尝试另一次购买时,这就是崩溃的原因,因为它仍然处于最后一次失败交易的中间。

我做错了什么?如何确保在失败后清除launchPurchaseFlow()?

6 个答案:

答案 0 :(得分:43)

我认为您只需将更新的代码更新为应用内结算类,您就不应再遇到同样的问题了。

据我所知,谷歌尚未推出对SDK Manager的更改。只需将新类复制/粘贴到您的类中,您就不应再遇到问题了。

在这里查看新的代码更改: https://code.google.com/p/marketbilling/source/detail?r=7ec85a9b619fc5f85023bc8125e7e6b1ab4dd69f&path=/v3/src/com/example/android/trivialdrivesample/MainActivity.java

截至3月15日更改的类是:IABHelper.java,Inventory.java,SkuDetails.java和一些MainActivity.java文件

答案 1 :(得分:29)

我知道这是对这个问题的后期贡献,但我今天遇到了同样的问题,我在一个片段中调用了应用程序计费,所以我查看了" 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);
}

我希望这能帮助那些人......

答案 2 :(得分:10)

对我来说,最好的解决方法是将代码更新为最近的代码(here),并执行this post建议的代码:

  

1)公开方法flagEndAsync。它在那里,只是不可见。

     

2)让每个听众调用iabHelper.flagEndAsync以确保程序被标记为正确完成;似乎所有听众都需要它。

     

3)使用try/catch进行环绕声调用,以捕捉可能发生的IllegalStateException,并以此方式处理。

更新代码不够的原因是我发现了仍然发生此错误(或至少有一个)的特殊情况:

  • 断开互联网连接;
  • 输入您的应用;
  • 让它初始化IabHelper;
  • 连接到互联网;
  • 设备连接后,尝试购买。

答案 3 :(得分:8)

我有同样的问题。

首次尝试:解决方法

我按照下载了当前的IabHelper.java jmrmb80's solution,但这不起作用。 (似乎repo现在是deprecated,我们应该依赖Android SDK管理器提供的版本。)所以我跟着Khan's advice

  • 将IabHelper.flagEndAsync()定义为public,并
  • iabHelper.flagEndAsync()
  • 之前添加iabHelper.launchPurchaseFlow(...)

这似乎是一个公然的黑客!并且它可能具有不良副作用。但是,它确实“有效”......

这似乎是一个众所周知的错误:#134#189

第二次尝试:修复

经过进一步调查,我不认为上述解决方法解决了我的问题。我认为real solution将覆盖UI线程中的onActivityResult

答案 4 :(得分:2)

不需要hacky解决方案。 请求购买流程的活动或片段应具有以下内容:

@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的示例项目,在我的项目上进行了尝试,但它确实有效。

答案 5 :(得分:0)

Error response: 7:Item Already Owned表示您购买的物品但尚未消耗,而您又尝试再购买。

当我在我的应用内活动singleInstance中设置AndroidManifest launchMode时发生这种情况。应用程序总是以您描述的错误结束。

要避免此行为,请将launchMode更改为符合您需要的任何其他值 android:launchMode="singleInstance" - > android:launchMode="singleTask"

我没有尝试深入理解为什么singleInstance不起作用。如果有人知道请提供更多信息。

所以我的解决方案是更改launchMode并使用已拥有的项目。从那时起,IAP对我来说很好。