应用内结算测试:android.test.purchased已经拥有

时间:2012-12-15 22:09:07

标签: android in-app-billing

我目前正在为未来的应用程序测试In-App Billing,并且在我第一次成功“购买”测试项目“android.test.purchased”后,我现在每次尝试购买时都会收到响应代码7它再一次,这意味着我已经拥有了这个项目。

  

12-15 23:02:14.149:E / IabHelper(19829):应用内结算错误:无法使用   购买物品,错误回复:7:物品已经拥有

根据我的理解,这次购买应该永远是可能的,对吧?那么开发人员可以测试他/她的应用程序吗?

如果没有,我如何“重置”其状态为不拥有?我正在使用Google In-App Billing Sample中的util包。

16 个答案:

答案 0 :(得分:104)

将此代码添加到线程以启动使用请求。

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

这里是购买测试,buyToken是

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

if (response == 0)
然后消费成功。

答案 1 :(得分:79)

无需编写任何特殊消费代码。只需使用adb命令清除Google Play商店数据:

adb shell pm clear com.android.vending

答案 2 :(得分:59)

事实证明,android.test.purchased项的行为类似于常规ID。这意味着如果您希望能够再次购买它,则必须在代码中的某处使用它。我认为Google文档在这个问题上有误导性,并且他们应该添加另一个静态ID,您可以无休止地购买这些ID用于测试目的。

答案 3 :(得分: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);
        }
    }
};

答案 4 :(得分: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();
        }
    });

答案 5 :(得分:9)

版本3 :清除Google Play商店的缓存会让" android.test.purchased"再次可用。

答案 6 :(得分:6)

在我看来,如果您的程序不是为了消耗该项而设计的,则不需要调整代码以清除外部供应商的内存。这将使您的代码更加脆弱,然后您将花费大量时间来添加和删除不属于您的软件的代码,因此实现这样的解决方案是一个糟糕的设计。

清除android.test.purchased的最佳解决方案是

adb uninstall com.yourapp.name

然后

adb shell pm clear com.android.vending

我不需要清理现金并浏览我的应用设置或更改代码。我确实需要将adb添加到windows系统的路径变量中,这非常简单。所以是的,你需要使用你可能需要的adb ..

你只需添加你的C:\ ... \ android-sdk \ platform-tools;在环境变量的windows路径中,我想在mac和linux os中也很简单。希望它可以帮助别人花几天时间在app appings中实现android。

答案 7 :(得分:6)

我使用了adb shell:

adb shell pm clear com.android.vending

答案 8 :(得分:4)

主要问题是您必须使用android.test.purchased项。但是此商品在您的查询广告资源中无法使用,因此您无法使用正常流量进行消费。

因此,如果你在IabHelper课程中使用IabHelper,你可以暂时将IInAppBillingService mService更改为public,以便可以从IabHelper访问它。

然后在你的课堂上,你可以像这样消费,

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

如果成功,响应将为0。

希望这有帮助。

答案 9 :(得分:1)

如果您在测试环境中

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


    }
};

Consume Listener是

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

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

答案 10 :(得分:1)

出于测试目的,我还建议您在调用初始化gp购买流程的方法之前插入一段代码,清除您已购买的所有产品。当你仅测试一件物品时,这是特别舒服的。例如。像这样:

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

答案 11 :(得分:1)

转到Google Play控制台并打开“订单管理”标签。在那里,您可以退款/取消测试购买。

答案 12 :(得分: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();
            }
       }

    };

答案 13 :(得分:-1)

这是消耗品和非消耗品之间的区别;非消耗品(您似乎在这里处理的物品)持续跟踪状态,而消耗品可以多次购买。您必须进入Play管理控制台并取消/退还销售以再次测试。

答案 14 :(得分:-1)

就我而言,Google似乎没有记录该商品的购买。相反,Google Play服务的本地副本会缓存购买。这样,当在同一设备上发出第二个请求时,会出现android.test.purchased already owned。但是,使用其他设备或重置设备会清除缓存,并允许重复购买。

答案 15 :(得分:-1)

就我而言,我只需要清除应用缓存。清除缓存后,我能够再次启动购买流程。

从我的设备(4.4.2),我导航到“设置 - >应用程序管理器”。接下来,我从“DOWNLOADED”选项卡中选择了应用程序,然后选择了“清除缓存”。