アプリ内課金テスト:android.test.purchasedは既に所有されています


122

私は現在、将来のアプリのアプリ内課金をテストしており、テスト項目「android.test.purchased」を初めて正常に「購入」した後、再び購入しようとするたびに、応答コード7を受け取ります。つまり、私はすでにこのアイテムを所有しています。

12-15 23:02:14.149:E / IabHelper(19829):アプリ内課金エラー:アイテムを購入できません、エラー応答:7:アイテムは既に所有されています

私の理解から、この購入は常に可能であるはずですよね?開発者が自分のアプリをテストできるようにするには?

そうでない場合、どうすればその状態を「所有されていない」に「リセット」できますか?私はGoogleアプリ内課金サンプルのutilパッケージを使用しています。


1
私の募集は万力の詩です..私はすでに所有しているメッセージが必要ですが、毎回購入を許可する
Sandeep P

回答:


109

このコードをスレッドに追加して、消費要求を開始します。

int response = mService.consumePurchase(3, getPackageName(), purchaseToken);

購入テストの場合、purchaseTokenは

purchaseToken = "inapp:" + getPackageName() + ":android.test.purchased";

そして

if (response == 0)

その後、消費は成功します。

また、mServiceをpublicにすることを忘れないでください

IabHelper.Java

その後、次のようにアクセスすることが可能です:

int response = mHelper.mService.consumePurchase(3, getPackageName(), purchaseToken);

2
伝説はこれでうまくいき、@ psykhiは本当にあなたにポイントを与えたはずです。私はそれを消費しようとしましたが、購入トークンを見つけることができませんでした。ありがとう
Blundell

1
ありがとうございました!@prasharonnet
Y2i 2013

1
これは非常に時間の節約になります。完璧です。ありがとう。
PrivusGuru 2013年

13
mServiceとは何ですか?mHelper?しかし、consumePurchase()が見つかりません
Bagusflyer 2014

1
mServiceは、アプリ内購入のために開始された購入サービスにバインドされているIInAppBillingService.aidlインターフェイスのオブジェクトです。
Aashutosh Sharma

92

特別な消費コードを記述する必要はありません。Google Playストアのデータをクリアするには、adbコマンドを使用します。

adb shell pm clear com.android.vending

1
おかげで、アプリをクリアする必要があったので、完全な回答を用意しました。これは私にとって正しいアプローチです。
sivi 2015

これは多くの人にとって正しいアプローチです。アプリにコードを追加して再デプロイするのは、時間がかかります(意外と意図的)。
MichaelLabbé、2015年

9
これはテストデバイスに適したソリューションですが、注意してください。GooglePlayストアアプリのすべての設定がリセットされます。だから、私は自分のデバイスではやらないほうがいい。
2016年

7
番号!これは悪い考えです、あなたは他の製品や他のアプリのアプリ内購入を失いました、良いものはあなたがアプリ内購入をテストしたいなら製品を消費しなければならないことです、シナリオは購入用と購入用の2つのものを作成するだけです項目。
Rahul Mandaliya 2016

2
@RahulMandaliyaアプリケーションは、getPurchases()APIを使用してすでに購入されているものを知ることにより、キャッシュのクリアに対して回復力を備えている必要があります。
mttmllns

66

android.test.purchasedアイテムは通常のIDのように動作することがわかりました。つまり、もう一度購入できるようにするには、コードのどこかで消費する必要があります。Googleのドキュメントはこの問題について誤解を招くものであり、テスト目的で無限に購入できる別の静的IDを追加する必要があると思います。


在庫呼び出しを使用してPurchaseオブジェクトをフェッチし、それを消費します-頭にくれば簡単です。
スロット

3
@mttmlinsから以下の回答を参照するか、vvse.com / blog
blog

完全に真実ではありませんが、未使用のテストアイテムがある場合がありますが、未使用のアイテムbillingClient.queryPurchases()は返されません。そのため、アイテムを取得できないためpurchaseToken、アイテムを消費できません
Jemshit Iskenderov

28

アプリ内バージョン3:

IabHelper.QueryInventoryFinishedListener mGotInventoryListener = new IabHelper.QueryInventoryFinishedListener() {

    public void onQueryInventoryFinished(IabResult result, Inventory inventory) {

        .....................

        if (inventory.hasPurchase(SKU_CONTENT)) {

            mHelper.consumeAsync(inventory.getPurchase(SKU_CONTENT), null);
        }
    }
};

絵は千の言葉に値するので、完全に機能する最低限のコード部分は「このコードをスレッドに追加する」には千の価値があります。。。 '。
Androidcoderの2018

11

バージョン3-解決する最速の方法:Google Playストアのキャッシュをクリアすると、「android.test.purchased」が再び利用可能になります。


システムにインストールされている他のアプリにも影響しませんか?
IgorGanapolsky 2017

1
@IgorGanapolsky、いいえ。シミュレートされた購入のみが影響を受けます。「実際の」購入はGoogleのサーバーに保存され、変更されません。
Denis

1
Google Playアプリデータをクリアしましたが、機能しませんでした。テスト購入の詳細はまだ存在します。
Srikar Reddy

2
「設定/アプリケーションマネージャ/」を介して@Richardを使用するか、Google Playストアアイコンをメニューから[情報]ボタン(画面上部)にドラッグします。最後に、「キャッシュをクリア」ボタンをクリックするだけです。
Denis

1
私にとって最良の答え。他のすべては良いですが、この1は間違いなく解決するための最速の方法です
イグナシオ・ローダ


9

これがアイテムを消費する方法です

 consume.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View view) {
            Thread t = new Thread(new Runnable() {
                @Override
                public void run() {
                    String purchaseToken = "inapp:" + getPackageName() + ":android.test.purchased";
                    try {
                        Log.d("","Running");
                        int response = mService.consumePurchase(3, getPackageName(), purchaseToken);
                        if(response==0)
                        {
                            Log.d("Consumed","Consumed");
                        }else {
                            Log.d("","No"+response);
                        }
                    }catch (RemoteException e)
                    {
                        Log.d("Errorr",""+e);
                    }

                }
            });
            t.start();
        }
    });

私のために働きました- android.test.purchase問題を引き起こしていたある時点で使用していました-アプリ内課金の在庫タスクは大量のエラーをスローし、終了しませんでした。これを1回限りで実行するとクリアされたため、実際のSKUの使用を再開して、以前と同じように続行できます。ありがとう
Jon

1
すばらしい答えです。静的応答で機能します=アプリ内課金が有効なAPKがGoogle Playにアップロードされる前。
インフェロ2015

ありがとう!私のために働いた。
AndroidMechanic-Viral Patel

6

私の意見では、プログラムがアイテムを消費するように設計されていない場合は、外部ベンダーのメモリをクリアするためにコードを微調整する必要はありません。これはコードをより脆弱にし、ソフトウェアに属さないコードを追加および削除するために多くの時間を費やす必要があるため、そのようなソリューションを実装することは悪い設計です。

私がandroid.test.purchasedをクリアするために機能した最善の解決策は

adb uninstall com.yourapp.name

その後

adb shell pm clear com.android.vending

現金をクリアしてアプリの設定を閲覧したり、そのためのコードを変更したりする必要はありませんでした。Windowsシステムのパス変数にadbを追加する必要がありましたが、これは非常に簡単でした。だからはい、とにかく必要なadbを使う必要があります。

C:\ ... \ android-sdk \ platform-toolsを追加するだけです。環境変数のWindowsパスで、MacとLinux OSでもかなり簡単だと思います。それが誰かがアプリの請求にアンドロイドを実装することで数日を費やすのを助けるのを願っています


uninstallandroid.test.purchased sku をクリアする必要はありません。
IgorGanapolsky 2017

4

主な問題は、android.test.purchasedアイテムを消費する必要があることです。ただし、このアイテムはクエリインベントリで使用できないため、通常のフローを使用して消費することはできません。

したがって、IabHelperクラスでIabHelperを使用している場合は、一時的にIInAppBillingServicemServiceをpublicに変更して、IabHelperからアクセスできるようにすることができます。

それからあなたのクラスでは、あなたはこのように消費することができます、

int response = mHelper.mService.consumePurchase(3, getPackageName(), "inapp:"+getPackageName()+":android.test.purchased");

成功した場合、応答は0になります。

お役に立てれば。


接線:管理対象アイテムの払い戻しを行うことができますか(テストアカウントを使用-ダッシュボードに表示されないようです)?
Ed Lee

あなたは呼び出すことができるconsumeAsync()android.test.purchased。それで問題ありません。
IgorGanapolsky 2017

簡単なテストの場合、IabHelperを使用する場合、これが最良の方法です。助けて頂きました。
ルーベン2017年

2

テスト目的で、gp購入フローを初期化するメソッドを呼び出す前に、購入したすべての製品をクリアするコードを挿入することもお勧めします。これは、現時点で1つの項目のみをテストする場合に特に快適です。例えばこのように:

PurchasesResult purchasesResult = mBillingClient.queryPurchases(BillingClient.SkuType.INAPP);
    for (Purchase sourcePurchase : purchasesResult.getPurchasesList()) {
        if(sourcePurchase != null){

            ConsumeResponseListener listener = new ConsumeResponseListener() {
                @Override
                public void onConsumeResponse(String outToken, @BillingResponse int responseCode) {

                    System.out.println("all consumed");
                }
            };
            mBillingClient.consumeAsync(sourcePurchase.getPurchaseToken(), listener);
        }else{
            System.out.println("null");
        }
    }

// and then initiate whole process with clear "shoping basket"

BillingFlowParams.Builder builder = new BillingFlowParams.Builder()
        .setSku(itemName).setType(BillingClient.SkuType.INAPP);

2

Google Playコンソールに移動し、[注文管理]タブを開きます。そこで、テスト購入の払い戻し/キャンセルができます。


1

テスト環境にいる場合

1)android.test.purchasedの場合、androidデバイスを再起動することで偽の支払いをリセットできます(在庫を消費します)。

2)InApp utilには、Security.javaというファイルがあり、一時的に次のようにします。テストのpayment(fake)はセキュリティ例外のため常にfalseを返すので

public static boolean verifyPurchase(String base64PublicKey,
                                     String signedData, String signature) {
    return true; }

次に、OnIabPurchaseFinishedListenerでfechInvForconsumeItem()を呼び出します

IabHelper.OnIabPurchaseFinishedListener mPurchaseFinishedListener
            = new IabHelper.OnIabPurchaseFinishedListener() {
        public void onIabPurchaseFinished(IabResult result,
                                          Purchase purchase)
        {
            if (result.isFailure()) {
                // Handle error
                Log.e("123","Failure");

                return;
            }
            else if (purchase.getSku().equals(ITEM_SKU)) {
                Log.e("123","PURCAsed");
                fechInvForconsumeItem(); // Restart device if not consume

            }

        }
    };

fechInvForconsumeItem()は

    public void fechInvForconsumeItem() {
    mHelper.queryInventoryAsync(mReceivedInventoryListener);
}
IabHelper.QueryInventoryFinishedListener mReceivedInventoryListener
        = new IabHelper.QueryInventoryFinishedListener() {
    public void onQueryInventoryFinished(IabResult result,
                                         Inventory inventory) {


        if (result.isFailure()) {
            // Handle failure
            Log.e("11","Failure");



        } else {
            Log.e("11","suc");
            mHelper.consumeAsync(inventory.getPurchase(ITEM_SKU),
                    mConsumeFinishedListener);
        }


    }
};

消費リスナーは

    IabHelper.OnConsumeFinishedListener mConsumeFinishedListener =
        new IabHelper.OnConsumeFinishedListener() {
            public void onConsumeFinished(Purchase purchase,
                                          IabResult result) {

                if (result.isSuccess()) {
                } else {
                    // handle error
                    Log.e("11","sucConsume");
                }
            }
        };

0
IabHelper.QueryInventoryFinishedListener 
       mQueryFinishedListener = new IabHelper.QueryInventoryFinishedListener() {
       public void onQueryInventoryFinished(IabResult result, Inventory inventory)   
       {
          if (result.isFailure()) {
             return;
           }          
          try {

                if(inventory.hasPurchase("product_sku_id"))
                {   
                     isItemEnable= true;
                     mHelper.consumeAsync(inventory.getPurchase("product_sku_id"),null);            
                }
                else
                {
                       isItemEnable = false;
                }           

            } catch (Exception e) {
                e.printStackTrace();
            }
       }

    };

-1

私の場合、Googleはアイテムの購入を記録していないようです。むしろ、Google Play開発者サービスのローカルコピーが購入をキャッシュします。そうすることで、同じデバイスで2番目の要求が行われたときにandroid.test.purchased already ownedが表示されます。ただし、別のデバイスを使用するか、デバイスをリセットすると、キャッシュがクリアされ、購入を繰り返すことができます。


-1

私の場合、アプリのキャッシュをクリアするだけで済みました。キャッシュをクリアした後、購入フローを再開することができました。

私のデバイス(4.4.2)から、「設定->アプリケーションマネージャ」に移動しました。次に「ダウンロード」タブからアプリを選び、「キャッシュをクリア」を選びました。


-2

これは、消耗品と非消耗品の違いです。非消耗品(ここで扱っているように見えるもの)の状態は永続的に追跡されますが、消耗品は複数回購入できます。Play管理コンソールでセールをキャンセルまたは払い戻しして、もう一度テストする必要があります。


1
ただし、これらの「偽物」アイテムには「力」がなく、実際の購入品ではないため、販売ステータスを変更できる場所がわかりません。Googleドキュメントは android.test.purchasedについて述べている:あなたはこの商品IDでアプリ内課金のリクエストを行うと、Google Playでの応答があるかのようにあなたが成功したアイテムを購入しました。だから私はかなり混乱しています:/
psykhi

静的応答テストをまだ行っていますか?その場合、送信する静的応答を変更するだけです。しかし、キャンセル可能な注文で実際の購入を行う「独自の製品IDを使用したアプリ内購入のテスト」をしているようです。
アドオン

まだ静的IDが残っています。私が望むのは、android.test.purchased IDでアプリ内購入をテストできるようにすることです。それは私がグーグルドキュメントから私が理解するものから常に機能するはずであるときに初めて機能しました。よくわからなかったらごめんなさい!
psykhi

私の誤解、申し訳ありません。その場合は…わかりません。毎回間違いなく成功するはずですが、あなたが見ているようなケースは見たことがありません。ごめんなさい。
アドオン

おやすみなさいの睡眠の後で問題をもう一度調べようとします:)あなたの助けをありがとう!
psykhi
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.