75
73

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 5 years have passed since last update.

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

Last updated at Posted at 2013-01-22

課金怖くない。

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作ったのは何だったんだ。

75
73
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
75
73

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?