2012年12月21日金曜日

In-App Billing version 3を使ってみた


先日、既存の有料アプリを無料化→アプリ内課金を追加しよう、という流れで実装をしてみました。
たまたま新しいバージョンのライブラリが出たタイミングだったようで、折角だからこのライブラリを使って実装してみたときのメモです。

In-App Billing version3との遭遇

いつも通りに、「In-App Billingのサンプルが載っているブログ・サイトを探して、それを参考にしながら実装を進めていこう!」 と思っていたところ、IInAppBillingService.aidlを使ったサンプルがさっぱり見つからず、見つかるのはIMarketBillingService.aidlを使うものばかり…。
記事がないとか、そんなバカな…とか思っていたら、Android Developer Blogの記事を見つけました。つい最近バージョンアップしてたんですね。

先の記事によると、向上した点はこんな感じのようです。

  • 設計を改善して、アプリが完結に書けてデバッグ・メンテナンスしやすくなった。以前だと数100行書かないといけなかったコードが、50行くらいでできるように。
  • 堅牢なアーキテクチャにより、決済のロストが少なくなった。
  • ローカルへのキャッシュによって、API 呼び出しが高速になった。
  • 待望されていた、「一度だけ購入できるアイテム」の購入や、アイテム情報の問合せができるようになった。

SDKのサンプルを試そう

というわけで、SDKのサンプルを見ていくことにしました。まずは、SDK Managerから「Google Play Billing Library」をインストールします。
サンプルプロジェクトはSDKをインストールしたディレクトリ内の「extras/google/play_billing/in-app-billing-v03」にあります。Eclipseに取り込んでビルドします。

一旦apkを作成してアップロード

サンプルコードがビルドできたら、一旦apkをアップロードしておきます。この手順は、後述するProduct IDを設定・取得するために必要になります。

「リリース版」のapkファイルを作ります。アプリに署名して、Android Developer Consoleの「古いデザイン版」にアップロードして「保存」します(「公開」はしません)。こうすることで、新しいバージョンを公開していない状態で 、ローカルで実装したアプリ内課金を検証することができるようです。

注意:「 新しいデザイン」から apkファイルを追加すると、アップロード→「保存」の時点でアプリが公開されてしまいます!

課金処理の実装

サンプルの「MainActivity.java」の、課金に絡むところを変更していきます。
コードを眺めてみると、課金アイテムは以下の2種類があります。

  • SKU_PREMIUM(プレミアム権の購入):一度しか買えないアイテム
  • SKU_GAS(燃料の購入):何度でも買えるアイテム

今回は、何度でも買えるアイテムのみを提供する予定だったので、定数SKU_GASに注目して実装していきます。

Product IDの追加

Android Developer Consoleの、先ほどアップロードしたアプリを開いて、Product IDを登録します。

必要な入力項目は、 以下の通りです。

  • Productの種類(Managed: 一度だけ買える、Unmanaged: 何度でも買える、Subscription: 定期購読)
  • Product ID
  • タイトル
  • 説明
  • 値段

値段は検証段階のうちは少額にしておきましょう(万が一ということもあるので)。
Product IDに使えるのは、小文字のアルファベットと数字、アンダーラインとドットのみです。メールアドレスの@より前、みたいなルールですね。

詳細の入力欄はこのような感じです。入力が終わったら右上のコンボボックスから「Active」を選んでおきます(アプリがまだ非公開の場合には、検証はできますが、公開されることはないようです)。
こうして登録したProduct IDを、MainActivity内の定数「SKU_GAS」に指定しておきます。

アクティビティの初期化


MainActivityのonCreate メソッドの中ほどに、

String base64EncodedPublicKey = "CONSTRUCT_YOUR_KEY_AND_PLACE_IT_HERE";


という行があるので、ここにアプリごとに割り振られる「パブリックキー」を指定します。
パブリックキーは、Android Developer Consoleの「新デザイン」のみに表示されます。
パブリックキーは、検証の段階ではコピペでOKですが、リリース版ではセキュリティの観点から、ビットシフトなどの処理で生成してやる(キー文字列を、そのままの形でアプリ内に含めないようにする)必要があります。

購入処理の実装

Unmanaged Productの購入処理は、MainActivityのonBuyGasButtonClickedメソッドから追っていくことができます。

IabHelperというクラスのlaunchPurchaseFlowメソッドを呼ぶと、購入画面に遷移させることができます。

iabHelper.launchPurchaseFlow(this, SKU_DONATION, RC_REQUEST, purchaseFinishedListener);

最後の引数はIabHelper.OnIabPurchaseFinishedListenerクラスのインスタンスで、課金の一連の処理が終わると、onIabPurchaseFinishedメソッドが呼ばれます。その後、consume処理で購入を確定させるようです。

テストアカウントによる検証

テスト課金をするためには、テスト用のGoogle Playアカウントの設定が必要です。Android Developer Consoleを開いて、Account detaisの中ほどのテキストボックスに、テストに使うGoogle Playアカウントを入力します。

課金の検証には、その端末のGoogle Playプライマリアカウントがこのアドレスになっている必要があります。それ用に端末を用意するか、「出荷時の状態に戻す」が必要です。

「開発者用として登録されているGmailアカウント」をテストアカウントとして登録しても、課金の検証はできません(自分で自分のアイテムは買えません)。

「署名されたリリース版ビルドのapk」を端末に流し込み、そのアプリで、テストアカウントから課金します。Google Checkoutにログインして確認すると、履歴に明細が残っています。

テストアカウント設定テキストボックスの直下にある「License Test Response」RESPOND_NORMALLYになっている場合は、通常の課金と同じ結果を返します。実際のアプリに組み込む場合には、ここを他の値に設定して、それぞれの場合にちゃんと処理できるかどうかも確かめたほうが良いでしょう。

MainActivityをそのまま使っている場合は、Logcatに詳細な情報が出力されるので、どういう順にメソッドが呼ばれるかなど、必要に応じて確認しておきます。

In-App Billing version 3に必要な実装まとめ

以下の項目を実装・設定すれば大丈夫…のはずです。

aidlファイルの配置

「com.android.vending.billing」パッケージを作成し、サンプルのディレクトリ直下にある「IInAppBillingService.aidl」ファイルをそのまま置きます。
(genパッケージに必要なクラスが生成されるはずです)。

AndroidManifest.xmlの編集


以下のパーミッションが必要です。
    <uses-permission android:name="com.android.vending.BILLING" />

ライブラリ・クラス群の追加

パッケージ「example.android.trivialdrivesample.util」内のクラスを、適当なパッケージを作ってコピーします。
いろいろとアレなところもあるので、適宜リファクタリングしてみるのも良いのではないでしょうか。

base64EncodedPublicKeyの編集

Developer Consoleのアプリ情報のところからコピペしてきたLicence Keyを指定します。
ビット演算などによる動的生成で「Public Key」を取得するようなメソッドを書いて、その戻り値を設定するようにします。

Product IDの設定

MainActivityでいうところの、定数SKU_GAS・SKU_PREMIUMなどの値を変更します。アプリで使うアイテムの種類に応じて、Product IDを追加・削除します。

IabHelperのデバッグログ設定を無効に

アクティビティのonCreate()内で、iabHelper.enableDebugLogging(false)を呼びます。