Help us understand the problem. What is going on with this article?

Google Play In-app BillingをAPI v3のサンプルを使って楽して導入する

More than 5 years have passed since last update.

課金怖くない。

v2からかなり改善されていて良い。BroadcastをReceiveするのでなくて、onActivityResultへ結果が降ってくるようになったので、サンプルから持って来てそのままActivityに取り込みやすい。

対応しました。Subscriptionには非対応とのこと。
v2, v3で迷う時は

1. SDKから持ってくる

IInAppBillingService.aidl

{sdk}/extras/google/play_billing/in-app-billing-v03/IInAppBillingService.aidlsrc.com.android.vending.billingパッケージへコピー。

buildするとproject/genIInAppBillingService.javaが生成される。

サンプルのUtility

extras/google/play_billing/in-app-billing-v03/samples/TrivialDrive/src/com/example/android/trivialdrivesample/util/*.javaを自分のプロジェクトで適当なパッケージを切ってコピー。よしなにpackage, importをエラーが出ないように抑制する。

2. サンプルのActivityを参考に課金処理をActivityに実装する

以下、実装例。

  • void requestBilling()をActivity上で実行すれば非消費型アイテムの購入プロセスがスタートする
  • void requestSubscriptionBilling()を実行すれば定期購読アイテムの購入プロセスがスタートする
  • boolean isPremiumUser(),boolean isPremiumSubscriber()で課金した状態かどうかを取得出来る ような各アクティビティで継承する基底のクラスをイメージ。

あとはPlayから確実に課金状態が取得出来ない(v2ではちらほら起きていた)ことも考慮して本体に保存、定期的にチェックを入れるような実装をするのが良さそう。また、BillingがSupportedかどうかをちゃんとハンドリングするべき。あとサンプルのUtilityの中身も精査した方が良さそう。

public abstract class BaseActivity extends SherlockFragmentActivity {

    private static final String SKU_PREMIUM = "Developer Consoleで設定した非消費型アイテムのproduct id";
    private static final String SKU_PREMIUM_SUBSCRIPTION = "Developer Consoleで設定した定期購読アイテムのproduct id";

    private static final int REQUEST_CODE_PURCHASE_PREMIUM = よしなにリクエストコードを;
    private static final String BILLING_PUBLIC_KEY = "Developer Consoleで得られるBase64encodedな公開鍵(そのままコードに持たせず別の形からデコードなりして持ってくるのが推奨されている";

    private IabHelper mBillingHelper;
    private boolean mIsPremium = false;
    private boolean mIsSubscriber = false;

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

    @Override
    protected void onDestroy() {
        super.onDestroy();
        tearDownBilling();
    }

    private void setupBilling() {
        mBillingHelper = new IabHelper(this, BILLING_PUBLIC_KEY);
        mBillingHelper.enableDebugLogging(true); // Remove before release
        mBillingHelper.startSetup(new IabHelper.OnIabSetupFinishedListener() {
            public void onIabSetupFinished(IabResult result) {
                Log.d("billing", "Setup finished.");
                if (result.isFailure()) return;
                Log.d("billing", "Setup successful. Querying inventory.");
                mBillingHelper.queryInventoryAsync(mGotInventoryListener);
            }
        });
    }

    private void tearDownBilling() {
        if (mBillingHelper != null) mBillingHelper.dispose();
        mBillingHelper = null;
    }

    private IabHelper.QueryInventoryFinishedListener mGotInventoryListener = new IabHelper.QueryInventoryFinishedListener() {
        public void onQueryInventoryFinished(IabResult result, Inventory inventory) {
            Log.d("billing", "Query inventory finished.");
            if (result.isFailure()) return;
            Log.d("billing", "Query inventory was successful.");
            mIsPremium = inventory.hasPurchase(SKU_PREMIUM);
            Log.d("billing", "User is " + (mIsPremium ? "PREMIUM" : "NOT PREMIUM"));
        }
    };

    private IabHelper.OnIabPurchaseFinishedListener mPurchaseFinishedListener = new IabHelper.OnIabPurchaseFinishedListener() {
        public void onIabPurchaseFinished(IabResult result, Purchase purchase) {
            Log.d("billing", "Purchase finished: " + result + ", purchase: " + purchase);
            if (result.isFailure()) return;
            Log.d("billing", "Purchase successful.");
            if (purchase.getSku().equals(SKU_PREMIUM)) {
                Log.d("billing", "Purchase is premium upgrade. Congratulating user.");
                mIsPremium = true;
            }
            if (purchase.getSku().equals(SKU_PREMIUM_SUBSCRIPTION)) {
                Log.d("billing", "Purchase is new subscribing. Congratulating.");
                mIsSubscriber = true;
            }
        }
    };

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

    protected boolean isPremiumUser() {
        return this.mIsPremium;
    }

    protected boolean isSubscriber() {
        return this.mIsSubscriber;
    }

    protected void requestBilling() {
        mBillingHelper.launchPurchaseFlow(this, SKU_PREMIUM, REQUEST_CODE_PURCHASE_PREMIUM, mPurchaseFinishedListener);
    }

    protected void requestSubscriptionBilling() {
        if (mBillingHelper.subscriptionsSupported()) {
            mBillingHelper.launchSubscriptionPurchaseFlow(this, SKU_PREMIUM_SUBSCRIPTION, REQUEST_CODE_PURCHASE_PREMIUM, mPurchaseFinishedListener);
        }
    }

    protected void cancelSubscription() {
        startActivity(new Intent(Intent.ACTION_VIEW, Uri.parse("market://details?id=" + getPackageName())));
    }

}

これだけ。v2で必死にListener作ったのは何だったんだ。

Why do not you register as a user and use Qiita more conveniently?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
Comments
Sign up for free and join this conversation.
If you already have a Qiita account
Why do not you register as a user and use Qiita more conveniently?
You need to log in to use this function. Qiita can be used more conveniently after logging in.
You seem to be reading articles frequently this month. Qiita can be used more conveniently after logging in.
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away