如何设置应用内购买(非消耗品)?

2024-03-17

我正在使用一些在线教程在我的应用程序中实现应用程序内购买。但该教程适用于消费品应用内购买。但就我而言,用户只需要购买一次。

我修改了代码,在购买应用内购买后禁用“购买按钮”。现在一切正常。但问题是,如果我关闭并打开应用程序,“购买按钮”就会启用。

这是我的 xml 代码

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent"
    android:layout_height="match_parent" android:paddingLeft="@dimen/activity_horizontal_margin"
    android:paddingRight="@dimen/activity_horizontal_margin"
    android:paddingTop="@dimen/activity_vertical_margin"
    android:paddingBottom="@dimen/activity_vertical_margin" tools:context=".InAppBillingActivity">

    <Button
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="@string/click_string"
        android:id="@+id/clickButton"
        android:layout_alignParentTop="true"
        android:layout_centerHorizontal="true"
        android:layout_marginTop="113dp"
        android:onClick="buttonClicked"/>

    <Button
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="@string/buy_string"
        android:id="@+id/buyButton"
        android:layout_centerVertical="true"
        android:layout_centerHorizontal="true"
        android:onClick="buyClick" />
</RelativeLayout>

这是我的应用内结算活动

public class InAppBillingActivity extends AppCompatActivity {

    private static final String TAG =
            "InAppBilling";
    IabHelper mHelper;
    static final String ITEM_SKU = "com.example.buttonclick";

    private Button clickButton;
    private Button buyButton;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_in_app_billing);

        buyButton = (Button)findViewById(R.id.buyButton);
        clickButton = (Button)findViewById(R.id.clickButton);
        clickButton.setEnabled(false);
        String base64EncodedPublicKey =
                "<place your public key here>";

        mHelper = new IabHelper(this, base64EncodedPublicKey);

        mHelper.startSetup(new
                                   IabHelper.OnIabSetupFinishedListener() {
                                       public void onIabSetupFinished(IabResult result) {
                                           if (!result.isSuccess()) {
                                               Log.d(TAG, "In-app Billing setup failed: " +
                                                       result);
                                           } else {
                                               Log.d(TAG, "In-app Billing is set up OK");
                                           }
                                       }
                                   });
    }

    public void buttonClicked (View view)
    {
        Intent Quiz = new Intent(getApplicationContext(), QuestionYearwises.class);
        startActivity(Quiz);
    }

    public void buyClick(View view) {
        mHelper.launchPurchaseFlow(this, ITEM_SKU, 10001,
                mPurchaseFinishedListener, "mypurchasetoken");
    }

    @Override
    protected void onActivityResult(int requestCode, int resultCode,
                                    Intent data)
    {
        if (!mHelper.handleActivityResult(requestCode,
                resultCode, data)) {
            super.onActivityResult(requestCode, resultCode, data);
        }
    }

    IabHelper.OnIabPurchaseFinishedListener mPurchaseFinishedListener
            = new IabHelper.OnIabPurchaseFinishedListener() {
        public void onIabPurchaseFinished(IabResult result,
                                          Purchase purchase)
        {
            if (result.isFailure()) {
                // Handle error
                return;
            }
            else if (purchase.getSku().equals(ITEM_SKU)) {
                consumeItem();
                buyButton.setEnabled(false);
            }

        }
    };
    public void consumeItem() {
        mHelper.queryInventoryAsync(mReceivedInventoryListener);
    }

    IabHelper.QueryInventoryFinishedListener mReceivedInventoryListener
            = new IabHelper.QueryInventoryFinishedListener() {
        public void onQueryInventoryFinished(IabResult result,
                                             Inventory inventory) {

            if (result.isFailure()) {
                // Handle failure
            } else {
                mHelper.consumeAsync(inventory.getPurchase(ITEM_SKU),
                        mConsumeFinishedListener);
            }
        }
    };

    IabHelper.OnConsumeFinishedListener mConsumeFinishedListener =
            new IabHelper.OnConsumeFinishedListener() {
                public void onConsumeFinished(Purchase purchase,
                                              IabResult result) {

                    if (result.isSuccess()) {
                        clickButton.setEnabled(true);
                    } else {
                        // handle error
                    }
                }
            };

    @Override
    public void onDestroy() {
        super.onDestroy();
        if (mHelper != null) mHelper.dispose();
        mHelper = null;
    }


}

每次用户打开应用程序时,您要做的第一件事就是检查购买状态。如果用户已经拥有购买的商品,请在应用程序中发布与购买相关的功能,然后只需将按钮可见性设置为View.GONE或者一些对你有意义的事情,我个人只是隐藏它。

如果您的购买是一次性购买,则不得消费,似乎在您的mPurchaseFinishedListener您正在消费它,然后当您在用户打开应用程序时检查该商品的所有权时,这似乎是递归购买,因为您已经消费了该商品,它将允许您再次购买。

您可能需要考虑使用Google Play 结算库 https://developer.android.com/google/play/billing/billing_library_overview,如果您使用的是带有AIDL它将被弃用see https://developer.android.com/google/play/billing/api.html.

这是一个Codelab https://codelabs.developers.google.com/codelabs/play-billing-codelab/#0让您开始使用Google Play 结算库

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

如何设置应用内购买(非消耗品)? 的相关文章

随机推荐

  • 使用 v4l2loopback 和 EDSDK Liveview 进行佳能 DSLR 视频环回?

    我想使用 DSLR 相机作为视频输入 例如在 Linux 和 Android 下进行 Skype Google talk 是否可以使用 v4l2loopback 和 Canon EDSDK 创建视频环回 如何将实时取景缓冲区从摄像机传输到视
  • 为什么 DataContractSerializer 不支持属性?

    我根据客户的文档创建 xsd 并且所有 xsd 都有属性 我一直在使用 xsd exe 从 xsd 生成类 但我读到 DataContractSerializer 不支持属性 为什么不 这是否意味着我只能有一个只有元素的soap xml 文
  • 关于 TypeScript 的 noUnusedParameters 编译器选项的说明

    在 GitHub 上输入任何内容之前 我试图确定这实际上是否是一个错误 With noUnusedParameters启用后 TypeScript 编译器会出现如下错误 const foo one two three foo forEach
  • 生日显示为去年的年龄?

    我正在测试一个我想在其中使用它的网站的 JavaScript 片段 基本上 当页面加载我的年龄时执行的函数 我是在规定的出生日期之外做这件事的 我在使用birthDate变量时注意到一个错误 不确定为什么会发生 当birthDate月份比当
  • Doctrine ORM 内存问题

    问题 运行使用下面 Factory 类中的 Doctrine 的守护程序服务时 会出现内存问题 当守护进程服务启动时 它运行大约 175MB 一天后大约是 250MB 再过一天就达到 400MB 我正在寻找导致内存增加的原因以及如何降低内存
  • 将java库包含到自己的库中

    我为自己创建了一个小框架 我想在多个项目中使用它 我还希望分布式 jar 文件包含所有外部库 以便我的项目只需要包含我的库即可访问所有外部库 我需要这个来简化外部库的更新 所以我把它放在我的 build xml 中 它将 dist lib
  • 如何使用加特林检查 If 方法?

    记录在案here https gatling io docs current cheat sheet 加特林checkIf方法用于条件检查 它不可用于ScenarioBuilder的流畅 API 但我可以在CheckSupport班级 我在
  • 如何将在线 CSV 数据插入 SQL Server 数据库?

    我需要每天从在线可用的 csv 执行数据加载 例如http www supplier com products csv http www supplier com products csv一旦我将 csv 转储到 sql 表中 我就可以进行
  • 如何枚举es6类方法[重复]

    这个问题在这里已经有答案了 如何枚举 ES6 类的方法 如同Object keys 这是一个例子 class Callbacks method1 method2 const callbacks new Callbacks callbacks
  • 为什么 &&、&、|| 的输出不同?

    这是代码段 你能解释一下为什么输出不同 1 public static ShortCkt public static void main String args int i 0 boolean t true boolean f false
  • 使用 Makefile 在编译中排除源文件

    是否可以使用 Makefile 中的通配符函数在编译过程中排除源文件 就像有几个源文件一样 src foo cpp src bar cpp src 然后在我的 makefile 中 SRC FILES wildcard src cpp 但我
  • 以编程方式滚动离子段

    有什么办法可以控制分段的滚动吗 在我的情况下 滑块和段相互依赖 当您滑动幻灯片时 溢出段不会滑动 但将正确选择活动段 我的视图和控制器代码
  • 如何撤销 JWT 令牌?

    我正在使用 Spring Security OAuth2 和 JWT 令牌 我的问题是 如何撤销 JWT 令牌 正如这里提到的http projects spring io spring security oauth docs oauth2
  • 如何在 Node.js 中创建函数

    我正在使用 Firebase 函数创建 API 同时我使用 Firebase Firestore 作为我的数据库 我正在使用 Node js 来创建该程序 我想知道如何在 Node js 中创建函数 我将多次调用代码 因为我已经习惯了 Ja
  • 如何更改测试资源管理器的持续时间计时器,使其对于长(>1 秒)测试更有用?

    我在 Visual Studio 2013 中编写了一系列测试用例 这些测试用例通过 Visual Studio 的内置测试资源管理器运行 这些不是单元测试 因此它们都运行至少几秒钟 由于测试内容的性质 其中一些测试的运行时间甚至可能超过
  • Mac 上有什么好的 MongoDB 数据库管理应用程序吗?类似于 Sequel Pro? [复制]

    这个问题在这里已经有答案了 寻找一个可视化 mongodb 中的集合和文档的 GUI 网络上有许多可用的工具 罗博蒙戈 https robomongo org 是最好的和最著名的 Mongo客户端 http www mongoclient
  • 如何使用 Boost::Python 公开原始字节缓冲区?

    我有第三方 C 库 其中一些类方法使用原始字节缓冲区 我不太确定如何在 Boost Python 中处理它 C 库头类似于 class CSomeClass public int load unsigned char pInBufferDa
  • DynamoDB 如何同时支持 Key-Value 和 Document 数据库属性

    根据 DynamoDB 的文档 它支持 NoSQL 的键值和面向文档的属性 即使其他 NoSQL 数据库仅属于一种类型 键值 文档 图形或面向列 它还说 Amazon DynamoDB 基于 Dynamo 的原则构建 3 是 AWS 基础设
  • 必须调用“render :layout => false”才能在 Rails 2.3.3 中正确渲染 js.erb 模板

    我正在运行最新的 Rails 2 3 stable 分支 当前为 2 3 3 我正在使用 JQuery 将 AJAX 请求发布到我的 创建 操作 其中有以下块 respond to do format format js end 我创造了c
  • 如何设置应用内购买(非消耗品)?

    我正在使用一些在线教程在我的应用程序中实现应用程序内购买 但该教程适用于消费品应用内购买 但就我而言 用户只需要购买一次 我修改了代码 在购买应用内购买后禁用 购买按钮 现在一切正常 但问题是 如果我关闭并打开应用程序 购买按钮 就会启用