現在、将来のアプリのアプリ内課金をテストしています。テスト項目「Android.test.purchased」を初めて「購入」した後、再度購入しようとするたびに応答コード7を受け取ります。つまり、私はすでにこのアイテムを所有しています。
12-15 23:02:14.149:E/IabHelper(19829):アプリ内課金エラー:アイテムを購入できません、エラー応答:7:アイテムはすでに所有されています
私が理解していることから、この購入は常に可能であるはずですよね?開発者が自分のアプリをテストできるように?
そうでない場合、どうすればその状態を「所有しない」に「リセット」できますか? Google In-App Billing Sampleのutilパッケージを使用しています。
Android.test.purchasedアイテムは通常のIDのように動作することがわかりました。つまり、再び購入できるようにするには、コードのどこかでそれを消費する必要があるということです。 Googleのドキュメントはこの問題について誤解を招くものであり、テスト目的で無限に購入できる別の静的IDを追加する必要があると思います。
このコードをスレッドに追加して、消費要求を開始します。
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);
特別な消費コードを書く必要はありません。 Google Playストアのデータを消去するには、adbコマンドを使用します。
adb Shell pm clear com.Android.vending
アプリ内バージョン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);
}
}
};
これがアイテムの消費方法です
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();
}
});
Version:Google Playストアのキャッシュをクリアすると、「Android.test.purchased」が再び利用可能になります。
私はadbシェルを使用しました:
adb Shell pm clear com.Android.vending
私の意見では、プログラムがアイテムを消費するように設計されていない場合、外部ベンダーのメモリをクリアするためにコードを微調整する必要はありません。これによりコードがより脆弱になり、ソフトウェアに属さないコードを追加および削除するのに多くの時間を費やす必要があるため、そのようなソリューションを実装するのは悪い設計です。
Android.test.purchasedをクリアするのに私にとって働いた最高のソリューションは
adb uninstall com.yourapp.name
その後
adb Shell pm clear com.Android.vending
現金を清算したり、アプリの設定を閲覧したり、そのためのコードを変更したりする必要はありませんでした。 Windowsシステムのパス変数にadbを追加する必要がありましたが、これは非常に簡単でした。そう、あなたはおそらくあなたがおそらくとにかく必要とするadbを使用する必要があります..
C:\ ...\Android-sdk\platform-toolsを追加するだけです。環境変数のWindowsパスで、MacとLinux OSでもかなり簡単だと思います。アプリの請求にAndroidを実装することで、誰かが数日を費やすのを助けてくれることを願っています。
主な問題は、Android.test.purchased
アイテムを消費する必要があることです。ただし、このアイテムはクエリインベントリで使用できないため、通常のフローを使用して消費することはできません。
したがって、IabHelper
クラスでIabHelperを使用している場合、IInAppBillingService
mServiceを一時的にパブリックに変更して、IabHelperからアクセスできるようにすることができます。
そして、あなたのクラスでは、このように消費することができます、
int response = mHelper.mService.consumePurchase(3, getPackageName(), "inapp:"+getPackageName()+":Android.test.purchased");
成功した場合、応答は0になります。
お役に立てれば。
テスト環境にいる場合
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");
}
}
};
テストの目的で、gp購入フローを初期化するメソッドを呼び出す前に、購入したすべての製品をクリアするコードを挿入することもお勧めします。現時点で1つの項目のみをテストする場合、これは特に快適です。例えば。このような:
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);
google Playコンソールに移動して、[注文管理]タブを開きます。そこで、テスト購入の払い戻し/キャンセルができます。
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();
}
}
};