Android应用内结算:由于launchPurchaseFlow正在进行,因此无法启动launchPurchaseFlow

我正在首次实施“应用内结算”,并使用静态SKU IDtesting我的第一笔交易。

它第一次运行得非常好。 我打电话给mHelper.launchPurchaseFlow(...)并完成了testing购买。 我的活动收到onActivityResultcallback,并确保使用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); } } 

然而,我想testing下一个部分,所以我重新启动应用程序,并试图购买相同的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:由于另一个asynchronous操作(launchPurchaseFlow)正在进行,无法启动asynchronous操作(launchPurchaseFlow)。

当我尝试购买失败时, onActivityResultcallback不会发生,所以失败的启动stream程不会得到处理和清理。 所以,当我尝试另一次购买时,这就是为什么它崩溃,因为它仍然在最后一次失败的交易中。

我究竟做错了什么? 如何确保launchPurchaseFlow()在发生故障后被清除?

我相信你只需要获取更新后的代码就可以看到应用内结算类别,而且不会再遇到同样的问题。

据我所知,谷歌还没有推出对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文件

我知道这是一个迟到的问题,但我今天面对的是同样的问题,我在一个片段中调用了应用程序中的计费,所以我查了一下“labHelper.java”,我看到了一个直接的解决scheme,我相信问题是…我修改了labHelper.java中的方法“void flagStartAsync(String operation)”,如下所示

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

我希望这会帮助那里的一个…

对我来说,最好的解决办法是把代码添加到最近的代码( 这里 ),并做这个post的build议:

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

2)让每个监听者调用iabHelper.flagEndAsync来确保程序标记正确; 这似乎是所有听众都需要的。

3)用try/catch环绕调用来捕获可能发生的IllegalStateException ,并以这种方式处理。

更新代码的原因还不够,我发现这个错误仍然存​​在(或至less一个)的特殊情况:

  • 与互联网断开;
  • input你的应用程序
  • 让它初始化IabHelper ;
  • 连接到互联网;
  • 一旦设备连接,尝试购买。

我也有同样的问题。

第一次尝试:解决方法

我下载了当前的IabHelper.java ,按照jmrmb80的解决scheme ,但是这并不起作用。 (看起来repo现在已经被弃用了 ,我们应该依靠Android SDK manager提供的版本。)所以我遵循了Khan的build议 :

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

这似乎是一个公然的黑客! 它可能有不良的副作用。 但是,它“工作”…

这似乎是一个已知的错误: #134和#189 。

第二次尝试:修复

经过进一步调查,我不认为上述解决方法解决了我的问题。 我认为真正的解决scheme是重写UI线程中的onActivityResult

不需要哈克解决scheme。 请求购买stream程的活动或片段应具有以下内容:

 @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意味着您Error response: 7:Item Already Owned购买了物品,但是您还没有使用它,并且您尝试再次购买物品。

当我在AndroidManifest launchMode中设置了我的应用程序对singleInstance活动时,发生了这种情况。 应用程序总是完成你所描述的错误。

要避免这种行为,请将您的launchMode更改为适合您需要的任何其他值android:launchMode="singleInstance" – > android:launchMode="singleTask"

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

所以我的解决scheme是更改launchMode并消耗已经拥有的项目。 从那时起,IAP对我来说工作得很好。