36

アプリ内課金を初めて実装し、静的SKUIDを使用して最初の購入をテストしています。

それは最初は非常にうまくいきました。電話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(静的purchasedSKU)を購入しようとしました。

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

2回目にアイテムを購入しようとすると、OnIabPurchaseFinishedListenerが呼び出さpurchase failedれ、ログに「アプリ内請求エラー:アイテムを購入できません。エラー応答:7:アイテムは既に所有されています」と表示されます。

それは理にかなっていますが、別のアイテムを購入しようとすると、次のエラーでアプリがクラッシュします。

java.lang.IllegalStateException:別の非同期操作(launchPurchaseFlow)が進行中であるため、非同期操作(launchPurchaseFlow)を開始できません。

失敗したonActivityResult購入を実行しようとしてもコールバックが発生しないため、失敗した起動フローは処理およびクリーンアップされません。したがって、別の購入を試みると、最後に失敗したトランザクションの途中にあると思われるため、クラッシュするのはそのためです。

私は何が間違っているのですか?失敗後にlaunchPurchaseFlow()が確実にクリーンアップされるようにするにはどうすればよいですか?

4

6 に答える 6

43

アプリ内課金クラスで更新されたコードを取得するだけで、同じ問題が再び発生することはないと思います。

私の知る限り、GoogleはまだSDKマネージャーへの変更をプッシュしていません。新しいクラスをコピーして自分のクラスに貼り付けるだけで、問題が発生することはなくなります。

ここで新しいコードの変更をご覧ください: 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ファイルの一部です。

于 2013-04-02T06:20:15.990 に答える
29

質問への貢献が遅れていることはわかっていますが、今日も同じ問題に直面しており、フラグメント内でアプリ内課金を呼び出していたので、「labHelper.java」を調べたところ、私が信じている直接的な解決策が見つかりました。問題は...labHelper.javaのメソッド「voidflagStartAsync(Stringoperation)」を次のように変更しました

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

私はこれがそこに誰かを助けることを願っています...

于 2014-10-08T02:12:22.830 に答える
10

私にとって最善の解決策は、コードを最近のコード(ここ)に更新することと、この投稿が示唆することを実行することの両方でした。

1)メソッドをflagEndAsync公開します。そこにありますが、見えません。

2)すべてのリスナーを呼び出しiabHelper.flagEndAsyncて、プロシージャが正しく終了したとマークされていることを確認します。すべてのリスナーで必要なようです。

try/catch3)発生する可能性のあるものをキャッチするために、呼び出しをaで囲みIllegalStateException、そのように処理します。

コードを更新するだけでは不十分だった理由は、このバグがまだ発生する(または少なくとも1つ)特殊なケースを見つけたためです。

  • インターネットから切断します。
  • アプリを入力します。
  • IabHelper;を初期化します。
  • インターネットに接続します。
  • デバイスが接続されたら、購入してみてください。
于 2013-11-30T12:34:00.163 に答える
8

私も同じ問題を抱えてる。

最初の試み:回避策

jmrmb80のソリューションに従って 、現在のIabHelper.javaをダウンロードしましたが、機能しませんでした。(リポジトリは非推奨になっているようです。AndroidSDKマネージャーが提供するバージョンに依存する必要があります。)そこで、Khanのアドバイスに従いました。

  • IabHelper.flagEndAsync()をpublicとして定義し、
  • iabHelper.flagEndAsync()前に追加iabHelper.launchPurchaseFlow(...)

これは露骨なハックのようです!そして、それは望ましくない副作用をもたらす可能性があります。しかし、それは「機能」します...

これは既知のバグのようです:#134#189

2回目の試行:修正

さらに調査した結果、上記の回避策で問題が解決したとは思いません。本当の解決策onActivityResultは、UIスレッドでオーバーライドすることだと思います。

于 2014-10-09T09:51:30.607 に答える
2

ハッキーなソリューションは必要ありません。購入フローを要求しているアクティビティまたはフラグメントには、次のものが必要です。

@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のサンプルプロジェクトからのもので、私のプロジェクトで試してみましたが、機能します。

于 2016-09-10T17:30:47.970 に答える
0

Error response: 7:Item Already Ownedアイテムを購入したが、まだ消費しておらず、もう一度購入しようとしていることを意味します。

これは、アプリ内アクティビティでAndroidManifestlaunchModeを設定したときに発生しましたsingleInstance。アプリは常にあなたが説明したエラーで終了しました。

この動作を回避するには、launchModeをニーズに合った他の値に変更します android:launchMode="singleInstance"->android:launchMode="singleTask"

singleInstanceが機能しない理由を深く理解しようとはしませんでした。誰かが知っているなら、より多くの情報を提供してください。

したがって、私の解決策は、launchModeを変更し、すでに所有しているアイテムを消費することでした。その時以来、IAPは私にとってうまく機能します。

于 2014-01-08T10:58:01.803 に答える