我有一个新的Android应用程序,其中我添加了应用程序内的计费,我正在沮丧地撕裂我的头发。
我上传了已签名的APK并发布到了alpha版。我创建了一组应用内商品并将其全部激活。我创建了一个新的Gmail帐户,并将其定义为应用程序apk页面上的应用程序的测试人员。 我有工厂重置我的Android手机,并用新的Gmail帐户初始化它。我已将/ apps / testing链接输入chrome并注册为测试人员。然后我下载并安装了我的应用程序。在我的应用程序内部,我询问了可用的应用程序产品,并显示了我在上面创建的集合。我选择了一个购买并完成了以下购买流程。 1.屏幕显示要购买的产品,价格和请求按继续我这样做 2.屏幕显示付款方式,我选择兑换代码 3.屏幕显示兑换您的代码,我输入我之前在开发者控制台中设置的促销代码之一(上面没有提到 - 抱歉)并按下兑换 4.屏幕再次显示产品,这次价格划掉并提供选项添加我选择的项目(很奇怪被要求再添加买嘿ho) 5.屏幕显示添加的项目 6.几秒钟后,屏幕显示错误,您已经拥有此项目。
这怎么可能,这个用户在十分钟之前就不存在了,并且只使用了这个应用程序一次,如上所述。
我已经看到很多问题在堆栈溢出和其他地方类似于此并尝试了一切,清除谷歌播放商店缓存,清除谷歌播放商店数据等。上面描述的这个序列是我最新的尝试与一个完全干净的用户完全清洁电话。
我可以上传我使用的应用程序代码,但是错过了重点,这个gmail帐户在此之前从未购买任何东西时,如何拥有该项目。当然这是一个错误。
所有关于如何进行的线索都非常受欢迎。代码现已添加,注意这是一个混合Android应用程序,用户购买决策代码在javascript / html和in app动作在下面的包装代码
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:");
}
}
);
}
}
};
答案 0 :(得分:0)
我发现使用paypal(即真钱)进行购买时不会发生此错误,所以我相信这个&#34;错误你已经拥有这个项目&#34;消息在某种程度上与使用促销代码进行测试有关。并且(到目前为止)我的paypal帐户尚未收取费用(因为我是应用程序的重新注册测试人员)。