应用内结算测试:android.test.purchased 已拥有
Posted
技术标签:
【中文标题】应用内结算测试:android.test.purchased 已拥有【英文标题】:In-App Billing test: android.test.purchased already owned 【发布时间】:2012-12-03 12:23:24 【问题描述】:我目前正在为未来的应用测试应用内结算,在我第一次成功“购买”测试项目“android.test.purchased”后,我现在每次尝试购买时都会收到响应代码 7再说一遍,这意味着我已经拥有了这件物品。
12-15 23:02:14.149:E/IabHelper(19829):应用内计费错误:无法 购买商品,错误响应:7:商品已拥有
据我了解,这种购买应该总是可以的,对吧?以便开发者可以测试他/她的应用?
如果没有,我如何将其状态“重置”为不拥有?我正在使用 Google In-App Billing Sample 中的 util 包。
【问题讨论】:
我的招聘是虎钳..我需要已经拥有但每次允许购买的消息 【参考方案1】:转到 Google Play 开发者控制台,打开左侧的Order Management
菜单项,然后选择您要退款的订单。还要确保删除权利。
【讨论】:
我同意这一点。根据 Google,To perform multiple test purchases for the same non-consumable product, you can refund and revoke purchases using Google Play Console.
developer.android.com/google/play/billing/test 的更多详细信息。
我想这应该是当今公认的答案。退款时,请确保同时删除测试买家的权利,否则该商品仍将归您所有。见***.com/a/67633608/5369519。
如果我忘记删除权利,我该怎么办【参考方案2】:
版本 3 - 最快的解决方法:清除 Google Play 商店的缓存将使“android.test.purchased”再次可用。
【讨论】:
这不会影响系统上安装的其他应用程序吗? @IgorGanapolsky,没有。只有模拟购买会受到影响。 “真正的”购买存储在 Google 的服务器上,不会被修改。 我已经清除了 Google Play 应用数据,但它不起作用。测试购买详情仍然存在。 @Richard 通过“设置/应用程序管理器/”或将 Google Play 商店图标从菜单拖到“信息”按钮(在屏幕顶部)。最后,只需点击“清除缓存”按钮。 对我来说最好的答案。其他都不错,但是这个绝对是最快的解决方法【参考方案3】:将此代码添加到线程以发起消费请求。
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);
【讨论】:
传说这行得通,@psykhi 真的应该给你积分。我试图消费它,但无法计算出购买令牌。谢谢 这是一个巨大的节省时间。完美的。谢谢。 什么是mService?帮手?但我找不到 consumePurchase() mService是IInAppBillingService.aidl接口的对象,绑定了inapp购买发起的购买服务。 我还想指出,如果您使用具有安全性的 IABHelper,您可能需要更新 verifyPurchase 以返回 true。就我而言,它失败了,默认情况下只需要返回 true。【参考方案4】:主要问题是您必须使用 android.test.purchased
项目。但此商品在您的查询库存中不可用,因此您无法使用正常流程消费。
因此,如果您使用的是 IabHelper,在 IabHelper
类中,您可以暂时将 IInAppBillingService
mService 更改为 public,以便可以从您的 IabHelper 访问它。
那么在你的课堂上,你可以这样消费,
int response = mHelper.mService.consumePurchase(3, getPackageName(), "inapp:"+getPackageName()+":android.test.purchased");
如果成功,则响应为 0。
希望这会有所帮助。
【讨论】:
Tangent:您能否为托管项目退款(使用测试帐户 - 它似乎没有显示在仪表板中)? 您可以在 android.test.purchased 上致电consumeAsync()
。没有问题。
对于简单的测试,如果使用 IabHelper,这是最好的方法。帮助了我。【参考方案5】:
出于测试目的,我还建议您在调用初始化 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);
【讨论】:
【参考方案6】:如果你在测试环境中
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");
;
【讨论】:
【参考方案7】:就我而言,我只需要清除应用程序缓存。清除缓存后,我可以再次启动购买流程。
从我的设备 (4.4.2),我导航到“设置->应用程序管理器”。接下来,我从“下载”选项卡中选择了该应用程序,然后选择了“清除缓存”。
【讨论】:
【参考方案8】:无需编写任何特殊的消费代码。只需使用 adb 命令清除 Google Play 商店数据:
adb shell pm clear com.android.vending
【讨论】:
感谢它完成了我只需要清除应用程序的技巧,因此我提供了完整的答案。这对我来说是正确的方法。 这对很多人来说都是正确的方法。将代码添加到您的应用并重新部署更耗时(双关语)。 这对于测试设备来说是一个很好的解决方案,但要小心:它会重置您在 Google Play 商店应用中的所有设置。所以,我宁愿不在我的个人设备上这样做。 不!这是个坏主意,您失去了对其他产品和其他应用程序的应用内购买,好的一个是如果您想测试您的应用内购买,您必须消费产品,场景只是创建两件东西,一件用于购买,另一件用于消费购买项目。 @RahulMandaliya 您的应用应该能够通过使用 getPurchases() API 了解已购买的内容来抵御缓存清除。【参考方案9】:在我看来,如果您的程序不是为使用该项目而设计的,那么您无需调整代码以清除外部供应商的内存。这将使您的代码更加脆弱,然后您将不得不花费大量时间来添加和删除不属于您的软件的代码,因此实施这样的解决方案是一个糟糕的设计。
对我来说清除 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中也很简单。希望它可以帮助某人在应用计费中实现 android 少花几天的时间。
【讨论】:
uninstall
不需要清除 android.test.purchased sku。【参考方案10】:
就我而言,Google 似乎没有记录该商品的购买记录。相反,Google Play 服务的本地副本会缓存购买。这样,当在同一设备上发出第二个请求时,android.test.purchased already owned
就会出现。但是,使用其他设备或重置设备会清除缓存,并允许重复购买。
【讨论】:
【参考方案11】: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();
;
【讨论】:
【参考方案12】:这就是我们可以使用物品的方式
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();
);
【讨论】:
为我工作 - 在某些时候使用了android.test.purchase
,这导致了问题 - 应用内结算中的库存任务只是抛出了大量错误并且从未完成。一次性运行它会清除它,这样我就可以继续使用我的实际 SKU 并像以前一样继续使用它。谢谢
优秀的答案。使用静态响应 = 在启用应用内结算的 apk 上传到 Google Play 之前。
谢谢!为我工作。【参考方案13】:
应用内版本 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);
;
【讨论】:
一张图片值一千字,一个完整的可工作的基本代码片段值一千 '将此代码添加到线程中。 . .'.【参考方案14】:事实证明,android.test.purchased 项的行为类似于常规 ID。这意味着如果您想再次购买它,您必须在代码中的某个地方使用它。我认为 Google 文档在这个问题上具有误导性,他们应该添加另一个静态 ID,您可以无休止地购买以进行测试。
【讨论】:
使用inventory调用来获取Purchase对象,然后使用它——一旦你了解它就很容易了。 看下面@mttmlins的回答,或者阅读vvse.com/blog/blog/2016/08/26/… 不完全正确,我有一个案例,其中有未使用的测试项目,但billingClient.queryPurchases()
不会返回未使用的项目,所以现在我无法消费项目,因为我无法获得 purchaseToken
的它【参考方案15】:
这是消耗品和非消耗品的区别;非消耗性物品(您似乎在这里处理的东西)会持续跟踪它们的状态,而消耗性物品可以多次购买。您必须进入 Play 管理控制台并取消/退款以再次测试。
【讨论】:
但问题是我对这些“假”商品没有任何“权力”,而且我不知道在哪里可以更改销售状态,因为它们不是真正的购买。 google doc 提到了 android.test.purchased :当您使用此产品 ID 提出应用内结算请求时,Google Play 会像您成功购买商品一样做出响应。所以我很漂亮困惑:/ 你还在做静态响应测试吗?如果是这样,您只需要更改发送的静态响应。不过,听起来您正在使用“使用您自己的产品 ID 测试应用内购买”,这可以通过可取消的订单进行真正的购买。 我仍然坚持使用静态 ID。我想要的是能够使用 android.test.purchased ID 测试应用内购买。它只是第一次工作,它应该总是根据我从谷歌文档中理解的内容工作。对不起,如果我不清楚! 我的误解,对不起。在那种情况下……我不知道。每次肯定都应该返回成功,我没有看到你看到的情况。对不起。 睡一晚后会尝试再次查看问题 :) 感谢您的帮助!以上是关于应用内结算测试:android.test.purchased 已拥有的主要内容,如果未能解决你的问题,请参考以下文章