android - 错误你已经拥有这个项目

我有一个新的 Android 应用程序,我要在其中添加应用程序内结算,但我沮丧得焦头烂额。

我已上传已签名的 APK 并发布到 alpha 版。我创建了一组应用内产品并将它们全部激活。我创建了一个新的 gmail 帐户,并将其定义为应用程序 apk 页面上的应用程序测试人员。 我已将我的 android 手机恢复出厂设置并使用新的 gmail 帐户对其进行初始化。我已经在 chrome 中输入/apps/testing 链接并注册为测试人员。然后我下载并安装了我的应用程序。在我的应用程序中,我询问了可用的应用程序内产品,并显示了我在上面创建的产品集。我选择了一个购买并经历了以下购买过程。 1. 屏幕显示要购买的产品和价格,并要求按继续,我这样做 2. 屏幕显示付款方式,我选择兑换码 3. 屏幕显示 redeem your code 我输入我之前在开发者控制台中设置的促销代码之一(上面没有提到 - 抱歉)然后按 redeem 4. 屏幕再次显示产品,这次价格被划掉并提供添加我选择的项目的选项(很奇怪被要求再次添加购买嘿嘿) 5.屏幕显示添加的项目 6. 几秒钟后屏幕显示您已经拥有此项目的错误。

怎么会这样,这个用户在十分钟前不存在,并且如上所述只使用过一次这个应用。

我在堆栈溢出和其他类似的地方看到了很多问题,并尝试了一切,清除 google play 商店缓存,清除 google play 商店数据等。上面描述的这个序列是我对一个完全干净的用户的最新尝试,在一个完全干净的电话。

我可以上传我使用过的应用程序代码,但这没有捕获要点,即当这个 gmail 帐户以前从未从任何人那里购买过任何东西时,这个 gmail 帐户怎么可能已经拥有一个项目。这肯定是一个错误。

非常欢迎提供有关如何进行的所有线索。现在添加了代码,请注意这是一个混合 android 应用程序,用户购买决策代码在 javascript/html 中,应用程序内操作在下面的包装器代码中

private void processCommand(JSONObject commandJSON) throws JSONException
    {
    String command = commandJSON.getString("method");
    if ("GetInAppProducts".equals(command))
        {
        Log.d(TAG, "Querying Inventory");
        InAppPurchaseSkuString = null ; // clear the purchased sku. Note this is tested in mConsumeFinishedListener
        mHelper.queryInventoryAsync(true, itemSkus, new IabHelper.QueryInventoryFinishedListener()
            {
            @Override
            public void onQueryInventoryFinished(IabResult iabResult, Inventory inventory)
                {
                InventoryRecord = inventory ;
                if (iabResult.isFailure())
                    {
                    Log.d(TAG, "Query inventory failed");
                    SendEndItemsToApp ();
                    }
                else
                    {
                    Log.d(TAG, "Query inventory was successful.");
                    InventoryCheckCount = 0 ; // seems that we cannot just fire off a whole lot of these checks at the same time, so do them in sequence
                    if (itemSkus.size()>0) { CheckForOwnedItems (); } else { SendEndItemsToApp (); }
                    }
                }
            });

        }
    else if ("BuyInAppProduct".equals(command))
        {
        JSONArray params = commandJSON.getJSONArray("parameters");
        InAppPurchaseSkuString = params.getString(0);
        Log.d(TAG, "User decision to purchase " + InAppPurchaseSkuString);
        mHelper.launchPurchaseFlow( MainActivity.this, InAppPurchaseSkuString, InAppPurchaseActivityCode, mPurchaseFinishedListener, "mypurchasetoken"); // consider putting the user email address in the last field - need to get from app
        };
    }//end of ProcessCommand


public void CheckForOwnedItems ()
    {
    Log.d(TAG, "Pre Purchase Inventory Processing Started");
    String sku = itemSkus.get(InventoryCheckCount);
    if (InventoryRecord.getSkuDetails(sku) != null)
        {
        if (InventoryRecord.hasPurchase(sku))
            {
            consumeItem ();
            }
        else
            {
            SendItemToApp ();
            InventoryCheckCount++;
            if (InventoryCheckCount < itemSkus.size()) { CheckForOwnedItems (); } else { SendEndItemsToApp (); }
            };
        };
    }//end of CheckForOwnedItems

public void SendItemToApp ()
    {
    String sku = itemSkus.get(InventoryCheckCount);
    String priceString = InventoryRecord.getSkuDetails(sku).getPrice().replaceAll("[^\\d.]+", ""); // RegExp removes all characters except digits and periods
    String infoString = "InAppProductDetails('" + sku + "','" + "dummy" + "','" + priceString + "');"; // dummy is a placeholder for product description which is not (yet?) used in the app
    Log.d(TAG, infoString);
    mWebView.evaluateJavascript (infoString, new ValueCallback<String>()
            {
            @Override
            public void onReceiveValue(String s)
                {
                //Log.d(TAG,"Returned from InAppProductDetails:");
                }
            }
        );
    }

public void SendEndItemsToApp ()
    {
    String endString = "InAppProductsEnd();"; // name is a placeholder for now
    Log.d(TAG, endString);
    mWebView.evaluateJavascript(endString, new ValueCallback<String>()
            {
            @Override
            public void onReceiveValue(String s)
                {
                //Log.d(TAG,"Returned from InAppProductsEnd:");
                }
            }
        );
    }

public void consumeItem()
    {
    Log.d(TAG,"Pre Purchase Inventory Query Started");
    String sku = itemSkus.get(InventoryCheckCount);
    mHelper.consumeAsync(InventoryRecord.getPurchase(sku), mConsumeFinishedListener);
    }

IabHelper.OnConsumeFinishedListener mConsumeFinishedListener = new IabHelper.OnConsumeFinishedListener()
    {
    public void onConsumeFinished (Purchase purchase, IabResult result)
        {
        if (result.isSuccess())
            {
            Log.d(TAG, "Pre Purchase Consume Item Completed");
            SendItemToApp ();
            InventoryCheckCount++;
            if (InventoryCheckCount < itemSkus.size()) { CheckForOwnedItems (); } else { SendEndItemsToApp (); }

            }
        else
            {
            Log.d(TAG,"Pre Purchase Consume Item Failed");
            }
        }
    };

IabHelper.OnIabPurchaseFinishedListener mPurchaseFinishedListener = new IabHelper.OnIabPurchaseFinishedListener()
    {
    public void onIabPurchaseFinished (IabResult result, Purchase purchase)
        {
        if (result.isFailure())
            {
            Log.d(TAG,"Purchase Scenario Failed");
            }
        else if (purchase.getSku().equals(InAppPurchaseSkuString))
            {
            Log.d(TAG,"Purchase Scenario Completed");
            String evalString = "InAppProductPurchased('" + InAppPurchaseSkuString + "');";
            Log.d(TAG, evalString);
            mWebView.evaluateJavascript (evalString, new ValueCallback<String>()
                        {
                        @Override
                        public void onReceiveValue(String s)
                            {
                            Log.d(TAG, "Returned from InAppProductPurchased:");
                            }
                        }
                );
            }
        }
    };

最佳答案

我发现使用 paypal(即真钱)进行购买时不会发生此错误,因此我相信此“您已拥有该商品的错误”消息在某种程度上与使用促销代码有关考试。并且(到目前为止)我的 paypal 帐户没有被收费(因为我是该应用程序的注册测试员)。

https://stackoverflow.com/questions/39027802/

相关文章:

emacs - emacs cider/paredit/clojure-mode 中的缩进配置

java - 使用 WebSecurityConfigurerAdapter 而不是 WebMvcC

modelica - 在 Dymola/Modelica 中访问经过验证的函数库(例如贝塞尔函数)

android - 使用带参数的字符串资源 (strings.xml) 时出现问题

android - Titanium SDK 5.4.0.GA 在 Android 平台的控制台上显

sql - Firebase 与 Backendless

git - bitbucket - 看不到 merge 分支的提交

dns - 如何让 DNS 从本地主机解析与从远程主机解析相同的内容?

android - 构建android源代码(AOSP)问题

python - 如何更改seaborn jointplot中注释的字体大小?