我目前正在为未来的应用程序测试In-App Billing,并且在我第一次成功“购买”测试项目“android.test.purchased”后,我现在每次尝试购买时都会收到响应代码7它再一次,这意味着我已经拥有了这个项目。
12-15 23:02:14.149:E / IabHelper(19829):应用内结算错误:无法使用 购买物品,错误回复:7:物品已经拥有
根据我的理解,这次购买应该永远是可能的,对吧?那么开发人员可以测试他/她的应用程序吗?
如果没有,我如何“重置”其状态为不拥有?我正在使用Google In-App Billing Sample中的util包。
答案 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”选项卡中选择了应用程序,然后选择了“清除缓存”。