实施Google Play结算库版本2 [英] Implement Google Play Billing Library version 2

查看:327
本文介绍了实施Google Play结算库版本2的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

Google发布了一个全新的版本来处理Android中的付款,但是搜索了一段时间后,我找不到成功实施该示例的人提供的单个示例或教程.

Google published a brand new version to handle the payments in Android but after searching quite a while I cannot find a single example or tutorial from someone who succeeded implementing it.

文档非常简短,仅提供必要代码的一部分: https://developer.android.com/google/play/billing/billing_library_overview

The documentation is very short and provides only a part of the necessary code: https://developer.android.com/google/play/billing/billing_library_overview

提供的唯一样品是用Kotlin制成的: https://github.com/android/play-billing-samples

The only sample provided is made with Kotlin: https://github.com/android/play-billing-samples

好像他们忘记了Java开发人员...

Seems like they forgot about Java developers...

有人知道在线教程或成功实现了该教程吗?我当前的代码尚未发布.

Does anyone know a tutorial online or succeeded to implement it? My current code is far from working to be published yet.

推荐答案

感谢@Webfreak,您对Kotlin的回答将我引向了正确的方向.

Thanks @Webfreak, your answer for Kotlin guided to me to the right direction.

这是我为Java实现的方式:

Here is how I implemented it for Java:

首先将'billingclient'库添加到gradle中:

First add the 'billingclient' library to gradle :

implementation 'com.android.billingclient:billing:X.X.X'

并在清单文件中添加所需的权限:

And add the required permissions in the manifest file:

<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="com.android.vending.BILLING" />

该活动必须实现以下接口:

The Activity must implements the following interfaces:

public class MainActivity extends AppCompatActivity implements
        ...
        PurchasesUpdatedListener,
        AcknowledgePurchaseResponseListener {

然后我在onCreate方法中初始化计费客户端:

Then I initialize the billing client inside the onCreate method:

/** IN-APPS PURCHASE */
    private BillingClient mBillingClient;
    private long mLastPurchaseClickTime = 0;
    private List<String> mSkuList = new ArrayList<>();
    private List<SkuDetails> mSkuDetailsList = new ArrayList<>();

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);

        // AppPrefs is just a standalone class I used to get or set shared preferences easily
        mPrefs = AppPrefs.getInstance(this);


        // Rest of your code ...


        /** IN-APP PURCHASES */
        // Initialize the list of all the in-app product IDs I use for this app
        mSkuList.add(Parameters.UNIT_P1);// NoAdsPurchased
        mSkuList.add(Parameters.UNIT_P2);// CustomizationPurchased
        mSkuList.add(Parameters.UNIT_P3);// ChartsPurchased

        // Initialize the billing client
        setupBillingClient();

        // Apply the upgrades on my app according to the user's purchases
        applyUpgrades();
    }

设置计费客户端的方法在这里,以及我用来从应用程序检索可用的应用内商品的方法:

The method setting up the billing client is here, along with the metyhod I use to retrieve the avaialble in-app products fro the app:

private void setupBillingClient() {
        mBillingClient = BillingClient
                .newBuilder(MainActivity.this)
                .enablePendingPurchases() // Useful for physical stores
                .setListener(MainActivity.this)
                .build();

        mBillingClient.startConnection(new BillingClientStateListener() {
            @Override
            public void onBillingSetupFinished(BillingResult billingResult) {
                if (billingResult.getResponseCode() == BillingClient.BillingResponseCode.OK) {
                    // Load the available products related to the app from Google Play
                    getAvailableProducts();

                    Purchase.PurchasesResult purchasesResult = mBillingClient.queryPurchases(BillingClient.SkuType.INAPP);// Or SkuType.SUBS if subscriptions

                    // Init all the purchases to false in the shared preferences (security prevention)
                    mPrefs.setNoAdsPurchased(false);
                    mPrefs.setCustomizationPurchased(false);
                    mPrefs.setChartsPurchased(false);

                    // Retrieve and loop all the purchases done by the user
                    // Update all the boolean related to the purchases done in the shared preferences
                    if (purchasesResult.getPurchasesList() != null) {
                        for (Purchase purchase : purchasesResult.getPurchasesList()) {
                            if (purchase.isAcknowledged()) {
                                Log.e(TAG, purchase.getSku());

                                switch (purchase.getSku()) {
                                    case Parameters.UNIT_P1:
                                        mPrefs.setNoAdsPurchased(true);
                                        break;
                                    case Parameters.UNIT_P2:
                                        mPrefs.setCustomizationPurchased(true);
                                        break;
                                    case Parameters.UNIT_P3:
                                        mPrefs.setChartsPurchased(true);
                                        break;
                                }
                            }
                        }
                    }
                }
            }

            @Override
            public void onBillingServiceDisconnected() {
                // Try to restart the connection on the next request to
                // Google Play by calling the startConnection() method.
                // TODO Note: It's strongly recommended that you implement your own connection retry policy and override the onBillingServiceDisconnected() method. Make sure you maintain the BillingClient connection when executing any methods.
                Log.e(TAG, "onBillingServiceDisconnected");
            }
        });
    }

    private void getAvailableProducts() {
        if (mBillingClient.isReady()) {
            SkuDetailsParams params = SkuDetailsParams
                    .newBuilder()
                    .setSkusList(mSkuList)
                    .setType(BillingClient.SkuType.INAPP)
                    .build();

            mBillingClient.querySkuDetailsAsync(params, new SkuDetailsResponseListener() {
                @Override
                public void onSkuDetailsResponse(BillingResult billingResult, List<SkuDetails> skuDetailsList) {
                    if (billingResult.getResponseCode() == BillingClient.BillingResponseCode.OK) {
                        mSkuDetailsList = skuDetailsList;
                    }
                }
            });
        }
    }

当用户完成购买时(我允许在我的应用中的多个Fragment上购买),我在主Activity上调用此函数(使用界面):

When a purchase is done by the user (I allow purchases on several Fragments in my app), I call this function on the main Activity (using an interface):

@Override
    public void purchase(String sku) {
        // Mis-clicking prevention, using threshold of 3 seconds
        if (SystemClock.elapsedRealtime() - mLastPurchaseClickTime < 3000){
            Log.d(TAG, "Purchase click cancelled");
            return;
        }
        mLastPurchaseClickTime = SystemClock.elapsedRealtime();

        // Retrieve the SKU details
        for (SkuDetails skuDetails : mSkuDetailsList) {
            // Find the right SKU
            if (sku.equals(skuDetails.getSku())) {
                BillingFlowParams flowParams = BillingFlowParams.newBuilder()
                        .setSkuDetails(skuDetails)
                        .build();
                mBillingClient.launchBillingFlow(MainActivity.this, flowParams);
                break;
            }
        }
    }

我在这里实现继承的方法:

Here I implement the methods inherited:

@Override
    public void onPurchasesUpdated(BillingResult billingResult, @Nullable List<Purchase> purchases) {
        if (billingResult.getResponseCode() == BillingClient.BillingResponseCode.OK && purchases != null) {
            for (Purchase purchase : purchases) {
                handlePurchase(purchase);
            }
        } else {
            displayError(R.string.inapp_purchase_problem, billingResult.getResponseCode());
        }
    }

    private void handlePurchase(Purchase purchase) {
        if (purchase.getPurchaseState() == Purchase.PurchaseState.PURCHASED) {
            // Grant entitlement to the user.
            applyPurchase(purchase);

            // Acknowledge the purchase if it hasn't already been acknowledged.
            if (!purchase.isAcknowledged()) {
                AcknowledgePurchaseParams acknowledgePurchaseParams =
                        AcknowledgePurchaseParams.newBuilder()
                                .setPurchaseToken(purchase.getPurchaseToken())
                                .build();
                mBillingClient.acknowledgePurchase(acknowledgePurchaseParams, MainActivity.this);
            }
        }
    }

    @Override
    public void onAcknowledgePurchaseResponse(BillingResult billingResult) {
        if (billingResult.getResponseCode() == BillingClient.BillingResponseCode.OK) {
            displayError(R.string.inapp_purchase_success, billingResult.getResponseCode());
        }
    }

我添加的用于在我的应用中确认购买的方法:

The method I added to acknowledge a purchase on my app:

private void applyPurchase(Purchase purchase) {

        switch (purchase.getSku()) {
            case Parameters.UNIT_P1:
                mPrefs.setNoAdsPurchased(true);
                break;
            case Parameters.UNIT_P2:
                mPrefs.setCustomizationPurchased(true);
                break;
            case Parameters.UNIT_P3:
                mPrefs.setChartsPurchased(true);
                break;
        }

        // I remove the ads right away if purchases
        if(mPrefs.getNoAdsPurchased()) {
            destroyAds();
        }
    }

最后一种方法用于在应用程序上应用所有升级/购买(以删除广告为例):

This last method is used to apply all the upgrades/purchases on the app (with an example with the removal of the ads):

private void applyUpgrades() {
        // No ads
        if (mPrefs.getNoAdsPurchased()) {
            destroyAds();
        } else {
            loadAds();
        }

        if (mPrefs.getCustomizationPurchased()) {
            // Allow customization
            // ...
        }

        if (mPrefs.getChartsPurchased()) {
            // Allow charts visualization
            // ...
        }
    }

我认为此解决方案尚不完善,但可以正常工作,如果发现改进,我将修改代码.

I guess this solution is not perfect yet but it is working, I will modify the code if I find improvements.

这篇关于实施Google Play结算库版本2的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
相关文章
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆