Android应用内结算:由于launchPurchaseFlow正在进行,因此无法启动launchPurchaseFlow
我正在首次实施“应用内结算”,并使用静态SKU IDtesting我的第一笔交易。
它第一次运行得非常好。 我打电话给mHelper.launchPurchaseFlow(...)
并完成了testing购买。 我的活动收到onActivityResult
callback,并确保使用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)。
当我尝试购买失败时, onActivityResult
callback不会发生,所以失败的启动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对我来说工作得很好。