当前位置: 首页 > 知识库问答 >
问题:

应用内计费消耗品

吕皓
2023-03-14

我正在尝试实现销售消耗品(硬币)的谷歌应用内计费。我用一个非消耗品测试了它,它工作正常。但是我不能让它成为消耗品。每次我测试它,我只能买一次!这是我的代码:

公共类MainActivity扩展了AppCompatActivity{IabHelper mHelper;

boolean verifyDeveloperPayload(Purchase p) {
    String payload = p.getDeveloperPayload();

/*
 * TODO: verify that the developer payload of the purchase is correct. It will be
 * the same one that you sent when initiating the purchase.
 *
 * WARNING: Locally generating a random string when starting a purchase and
 * verifying it here might seem like a good approach, but this will fail in the
 * case where the user purchases an item on one device and then uses your app on
 * a different device, because on the other device you will not have access to the
 * random string you originally generated.
 *
 * So a good developer payload has these characteristics:
 *
 * 1. If two different users purchase an item, the payload is different between them,
 *    so that one user's purchase can't be replayed to another user.
 *
 * 2. The payload must be such that you can verify it even when the app wasn't the
 *    one who initiated the purchase flow (so that items purchased by the user on
 *    one device work on other devices owned by the user).
 *
 * Using your own server to store and verify developer payloads across app
 * installations is recommended.
 */

    return true;
}
@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);

    String base64EncodedPublicKey = "MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAlJQQTbdM6zP0585Ar0YKZAYQish29+AkZpdu4fGUO3WLoVm9UPOSNMMBmo8odzQbcVZdlKUfocohg/52qoQk9crVIhdHJM+O1GK9+hJSdVkZo0PWW5+1sJSCQ7cw0NTxIdDQVSYT0WWC2zkn8Fpxyz1N9pGHh21jxbviDYcnh1gyK+mCLt6jWcVxKl8BYgC0SS7K9F+7kHy+B/GG8ZSl2xhcCqlid/8cEjqH7yvMPciWA8lHvHB7rGz/nUg/v2ydhmUY6f8Ifh6+ygUu2XrhDU0v8wZ24yKw2Kw4SVZbm5ZmC/DXCgx+hIWVL+/yAFqHJ0ygqwW4aLTuKV6PyDaC1QIDAQAB";

    // compute your public key and store it in base64EncodedPublicKey
    mHelper = new IabHelper(this, base64EncodedPublicKey);
    mHelper.enableDebugLogging(true);

    mHelper.startSetup(new IabHelper.OnIabSetupFinishedListener() {
        public void onIabSetupFinished(IabResult result) {
            if (!result.isSuccess()) {
                // Oh no, there was a problem.
                Log.d("TAG", "Problem setting up In-app Billing: " + result);
                Log.i("TAG", "ERROR");
            }
            // Hooray, IAB is fully set up!
            //check owned items & consum em
            checkOwnedItems();
            //make a test purchase
                makePurchase();
        }
    });

}

private void makePurchase() {
    try {
        mHelper.launchPurchaseFlow(this, "next", 10001,
                mPurchaseFinishedListener, "bGoa+V7g/yqDXvKRqq+JTFn4uQZbPiQJo4pf9RzJ");
    } catch (IabHelper.IabAsyncInProgressException e) {
        e.printStackTrace();
        showToast("oh no error purchase" + String.valueOf(e));
    }
}

private void checkOwnedItems() {
    try {
        mHelper.queryInventoryAsync(mGotInventoryListener);
    } catch (IabHelper.IabAsyncInProgressException e) {
        showToast("Oh no error in check()");
        //complain("Error querying inventory. Another async operation in progress.");
    }
}


// Listener that's called when we finish querying the items and subscriptions we own
IabHelper.QueryInventoryFinishedListener mGotInventoryListener = new IabHelper.QueryInventoryFinishedListener() {
    public void onQueryInventoryFinished(IabResult result, Inventory inventory) {
        Purchase item = inventory.getPurchase("next");
        if (item != null && verifyDeveloperPayload(item)) {
            //Log.d("TAG", "We have gas. Consuming it.");
            try {
                mHelper.consumeAsync(inventory.getPurchase("next"), mConsumeFinishedListener);
            } catch (IabHelper.IabAsyncInProgressException e) {
                // complain("Error consuming gas. Another async operation in progress.");
                showToast("oh no error when consuming");
            }
            return;
        }
    }

};


// Called when consumption is complete
IabHelper.OnConsumeFinishedListener mConsumeFinishedListener = new IabHelper.OnConsumeFinishedListener() {
    public void onConsumeFinished(Purchase purchase, IabResult result) {
        Log.d("TAG", "Consumption finished. Purchase: " + purchase + ", result: " + result);

        // if we were disposed of in the meantime, quit.
        if (mHelper == null) return;

        // We know this is the "gas" sku because it's the only one we consume,
        // so we don't check which sku was consumed. If you have more than one
        // sku, you probably should check...
        if (result.isSuccess()) {
            // successfully consumed, so we apply the effects of the item in our
            // game world's logic, which in our case means filling the gas tank a bit
            //Log.d(TAG, "Consumption successful. Provisioning.");
            //mTank = mTank == TANK_MAX ? TANK_MAX : mTank + 1;
            // saveData();
            // alert("You filled 1/4 tank. Your tank is now " + String.valueOf(mTank) + "/4 full!");
        }
        else {
            //complain("Error while consuming: " + result);
        }
        Log.d("TAG", "End consumption flow.");
    }
};


// Callback for when a purchase is finished
IabHelper.OnIabPurchaseFinishedListener mPurchaseFinishedListener = new IabHelper.OnIabPurchaseFinishedListener() {
    public void onIabPurchaseFinished(IabResult result, Purchase purchase) {
        Log.d("TAG", "Purchase finished: " + result + ", purchase: " + purchase);

        // if we were disposed of in the meantime, quit.
        if (mHelper == null) return;

        if (result.isFailure()) {
            // complain("Error purchasing: " + result);
            return;
        }
        if (!verifyDeveloperPayload(purchase)) {
            // complain("Error purchasing. Authenticity verification failed.");
            return;
        }

        Log.d("TAG", "Purchase successful.");

        if (purchase.getSku().equals("next")) {

            Log.d("TAG", "Purchase is gas. Starting gas consumption.");
            try {
                mHelper.consumeAsync(purchase, mConsumeFinishedListener);
            } catch (IabHelper.IabAsyncInProgressException e) {
                //complain("Error consuming gas. Another async operation in progress.");
                showToast("oh no error when consuming");
                return;
            }
        }
    }
};

@Override
public void onDestroy() {
    super.onDestroy();
    if (mHelper != null) try {
        mHelper.dispose();
    } catch (IabHelper.IabAsyncInProgressException e) {
        e.printStackTrace();
    }
    mHelper = null;
}
private void showToast(String message) {
    Toast.makeText(this, message, Toast.LENGTH_LONG).show();
}

###

对不起我的英语,谢谢。

共有2个答案

经福
2023-03-14

我现在明白了:所以我的第一个问题是,我在checkOwnedItems方法之后立即调用makePurchase--

钱振
2023-03-14

我在使用本机应用内计费系统时也遇到了问题,但后来我找到了这个库

希望能有所帮助。

 类似资料:
  • 我在测试我的应用内计费时遇到了麻烦。 (使用Google Play应用内计费版本3 API) 问题: 已退款的应用程序内购买仍然存在于购买列表中,该列表由BillingClient.query购买()提供。 当我在一月份尝试退款时,退款的物品从购物清单上消失了。 我所做的: 作为测试人员购买了一些物品。 (我很确定对话框说是测试购买。) 之后在谷歌游戏控制台退款。 等到他们的付款状态变成退款。 清

  • 为了测试Android应用内计费v3,我实现了一个对话框,其中添加了一个选项适配器。我添加了测试SKU,“Android.测试.购买”,“Android.测试.取消”,“Android.测试.退款”,“Android.测试.项目不可用”。 当我使用该对话框启动购买流时,一切正常,我能够购买该商品,并且该商品是绝对购买的。然而,当我的应用程序尝试刷新UI时,我会收到一个nullpointerexce

  • 启动购买流后,onActivityResult方法需要什么? 来自平凡的驱动器示例: msgstr"在这里,您可以对与应用内计费无关的活动结果执行任何处理" 这是否意味着您需要更新用户的清单或显示警报框?如果是这样,我已经在OnConsumeFinishedListener中这样做了。我已经测试了我的代码,留下了上面的onActivityResult方法,看起来没问题。这可能会导致任何问题吗? 或

  • 我意识到每次应用程序运行时都没有必要检查谷歌play商店,尤其是如果购买已经准备好了。如果用户在使用应用程序时没有GPRS/WiFi,这也可能会导致问题! 因此,我在考虑创建一个共享偏好,它将作为检查用户是否购买了应用内购买的条件。 还有其他更安全的方法吗?正如我所读到的,共享首选项可以很容易地改变。

  • 本文向大家介绍浅谈PostgreSQL消耗的内存计算方法,包括了浅谈PostgreSQL消耗的内存计算方法的使用技巧和注意事项,需要的朋友参考一下 wal_buffers默认值为-1,此时wal_buffers使用的是shared_buffers,wal_buffers大小为shared_buffers的1/32 autovacuum_work_mem默认值为-1,此时使用maintenance_

  • 我的问题是围绕着用谷歌的应用内计费API处理应用内消耗品的购买。(https://developer.android.com/google/play/billing/api.html#consumetypes) 相反,您可以对可供多次购买的产品实施消费。通常,这些产品提供某些暂时效果。例如,用户在游戏中的角色可能会获得生命点数或者在他们的库存中获得额外的金币。在应用程序中分配购买的产品的好处或效果