web-dev-qa-db-ja.com

アプリ内課金テスト:Android.test.purchasededは既に所有しています

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

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

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

そうでない場合、どうすればその状態を「所有しない」に「リセット」できますか? Google In-App Billing Sampleのutilパッケージを使用しています。

107
psykhi

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

60
psykhi

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

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

購入テストの場合、purchaseTokenは

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

そして

if (response == 0)

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

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

IabHelper.Java

この場合、次のようにアクセスできます。

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

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

adb Shell pm clear com.Android.vending
80
mttmllns

アプリ内バージョン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);
        }
    }
};
28
embo

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

 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();
        }
    });
9
Shivaraj Patil

Version:Google Playストアのキャッシュをクリアすると、「Android.test.purchased」が再び利用可能になります。

9
Denis

私はadbシェルを使用しました:

adb Shell pm clear com.Android.vending
6
Shwarz Andrei

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

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でもかなり簡単だと思います。アプリの請求にAndroidを実装することで、誰かが数日を費やすのを助けてくれることを願っています。

6
sivi

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

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

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

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

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

お役に立てれば。

4
Tang Tung Ai

テスト環境にいる場合

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

2)InApp utilには、一時的に使用するSecurity.Javaというファイルがあります。テストの支払い(偽)は、セキュリティ例外のため常に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");
                }
            }
        };
1
Ebin Joy

テストの目的で、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);
1
sodiumnitrat

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

1
Sai Nadh
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();
            }
       }

    };
0
Girish Patel