見出し画像

【Android】アプリ内課金の実装方法例(Google Play Billing Library ver6)_2024年1月時点

この度、久しぶりにアプリを作ってリリースすることにしました。

その中で、アプリ内課金(Google Play Billing Library)を実装したのですが、
このBilling Libraryは頻繁に更新されていて、
僕が実装した2024年1月時点ではver6だったので、
Billing Library ver6の実装方法を下に記します。

ちなみに、僕のアプリのアプリ内課金の仕組みは、一度権利を購入するとずっと有効なもので、「非消費型アイテム 」と呼ばれるものになり、
その実装方法になっています。

まず、設定ファイルに必要な情報を記載します。
(あ、ネットワークの許可も必要です。)

build.gradle
    implementation("com.android.billingclient:billing:6.0.1")

次に、アプリ課金システムにまず接続する処理を実装します。
また、接続する際に、接続に成功した時の状態を受け取るリスナーと購入処理を行なった結果を受け取るリスナーを登録します。
そのリスナーの中身で、購入済みという状態・結果を受け取った時の処理も実装します。

private String PRODUCT_ID = "アプリ内課金のアイテムID";    

private void initGooglePlay() { // アプリ課金システムに接続
        billingClient = BillingClient.newBuilder(context)
                .setListener(purchasesUpdatedListener)
                .enablePendingPurchases()
                .build();
        if(billingClient!=null){
            billingClient.startConnection(new BillingClientStateListener() {
                @Override
                public void onBillingSetupFinished(BillingResult billingResult) {
                    if (billingResult.getResponseCode() ==  BillingClient.BillingResponseCode.OK) {

                        if(queryPurchasesAsyncFlg)queryPurchasesAsync();
                    }
                }
                @Override
                public void onBillingServiceDisconnected() {

                }
            });
        }
    }


    // 購入処理時の購入処理結果などをアプリ課金システムから受け取るリスナー
    private PurchasesUpdatedListener purchasesUpdatedListener = new PurchasesUpdatedListener() {
        @Override
        public void onPurchasesUpdated(BillingResult billingResult, List<Purchase> purchases) {
            if (billingResult.getResponseCode() == BillingClient.BillingResponseCode.OK
                    && purchases != null) {
                for (Purchase purchase : purchases) {
                    handlePurchase(purchase);
                }
            } else if (billingResult.getResponseCode() == BillingClient.BillingResponseCode.USER_CANCELED) {
            } else {
            }
        }
    };

    // 実際に購入された事実などをアプリ課金システムから受け取った時の実処理
    private void handlePurchase(final Purchase purchase) {

        //非消費型アイテム
        AcknowledgePurchaseResponseListener acknowledgePurchaseResponseListener = null;
        if (purchase.getPurchaseState() == Purchase.PurchaseState.PURCHASED) {
            if (!purchase.isAcknowledged()) {
                AcknowledgePurchaseParams acknowledgePurchaseParams =
                        AcknowledgePurchaseParams.newBuilder()
                                .setPurchaseToken(purchase.getPurchaseToken())
                                .build();
            }

            String productId = purchase.getProducts().get(0);
            // 購入済み履歴をアプリ内に保存
            if (productId.equals(PRODUCT_ID)) {
                SharedPreferences.Editor editor = sharedPref.edit();
                editor.putBoolean("rightPurchased", true);
                editor.apply();
                if (alertDialog != null) alertDialog.dismiss();
                queryPurchasesAsyncFlg = false;
            }
        }
    }

    // Google側との接続時の購入履歴の確認
    private  void  queryPurchasesAsync(){
        if(billingClient!=null){
            if(!billingClient.isReady()){
                Toast.makeText(context,"BillingClient is not ready",Toast.LENGTH_SHORT).show();
            }
            billingClient.queryPurchasesAsync(
                    QueryPurchasesParams.newBuilder()
                            .setProductType(BillingClient.ProductType.INAPP)
                            .build(),
                    new PurchasesResponseListener() {
                        public void onQueryPurchasesResponse(
                                BillingResult billingResult,
                                List<Purchase> purchases) {
                            if(billingResult.getResponseCode()==BillingClient.BillingResponseCode.OK){
                                if(purchases!=null&&purchases.size()>0){
                                    for (Purchase purchase:purchases){
                                        handlePurchase(purchase);
                                    }
                                }
                            }
                        }
                    }
            );
        }
    }

次に、実際の購入処理を実装します。

    private  void  toGooglePay(){//購入処理

        QueryProductDetailsParams queryProductDetailsParams =
                QueryProductDetailsParams.newBuilder()
                        .setProductList(
                                ImmutableList.of(
                                        QueryProductDetailsParams.Product.newBuilder()
                                                .setProductId(PRODUCT_ID)
                                                .setProductType(BillingClient.ProductType.INAPP)
                                                .build()))
                        .build();


        if(billingClient!=null){
            billingClient.queryProductDetailsAsync(
                    queryProductDetailsParams,
                    new ProductDetailsResponseListener() {
                        public void onProductDetailsResponse(BillingResult billingResult,
                                                             List<ProductDetails> productDetailsList) {
                            if(productDetailsList!=null&&productDetailsList.size()>0){
                                ProductDetails productDetails=productDetailsList.get(0);

                                ImmutableList productDetailsParamsList =
                                        ImmutableList.of(
                                                BillingFlowParams.ProductDetailsParams.newBuilder()
                                                        .setProductDetails(productDetails)
                                                        .build()
                                        );

                                BillingFlowParams billingFlowParams = BillingFlowParams.newBuilder()
                                        .setProductDetailsParamsList(productDetailsParamsList)
                                        .build();

                                billingResult = billingClient.launchBillingFlow((Activity) context, billingFlowParams);
                            }else {
//                                Toast.makeText(context,"商品IDエラー",Toast.LENGTH_SHORT).show();
                            }
                        }
                    }
            );
        }
    }

後は、上記の処理を、アプリ起動時やボタンなどのトリガーから呼び出すことで、アプリ内課金が動作します。

購入処理実行時のキャプチャ(画像はテスト実施時です)

また、正常に購入処理結果を受け取った後の後続処理をアプリに実装していけば、アプリ内課金関連処理は完成です。

興味があったり、必要に迫られて困ったりされていれば、
上記を参考にしてみてください。

また、アプリも使ってみて頂けるとありがたいです。


最後までお読みいただき、ありがとうございました。

この記事が気に入ったらサポートをしてみませんか?