【Android開発】Google Playアプリ内課金の実装方法ガイド

DAIKI MOCHIZUKI
17 min readNov 10, 2018

--

Photo by Anton Ljungberg on Unsplash
注意: 2017年9月時点での解説記事となりますので、情報が一部古い可能性があります。ご了承下さいませ。

今回は、Google Playアプリ内課金の実装方法を解説していきます。アプリ内課金は、ちょっと難しそうなイメージがありますよね。しかし、Google Playが提供するアプリ内課金の仕様が「Version 2」から「Version 3」に移行したことにより、かなりシンプルに実装できるようになりました。

実装するにあたってのコーディング、また複雑な箇所やハマりやすいポイント等を今回は紹介したいと思います。それでは、まずは課金の種類について理解していきましょう。

課金の種類について理解する

アプリ内課金は複雑そうに見えますが、実はGooglePlayによるアプリ内課金は、主に2つの種類しかないのです。今回は、下記で紹介する『管理対象のアイテム — 非消耗型課金』のアプリ内課金プログラミングを紹介していきます。課金の種類が変わっても基本は同じなので、ご自身のアプリに合わせ実装をしていくと良いでしょう。

管理対象のアイテム

この種類は、購入すると一部コンテンツがアンロックされる、広告除去のようなプレミアム機能を提供する「非消耗型課金」と、ゲームで使用するライフで見られるような購入すると消費できる「消費型」の2つがあります。

消費型は、使う度に消費するアイテム形式で、必要時に毎回購入しなければならず、無料で再ダウンロードすることはできません。例えば、ゲーム内通貨、ゲームのライフなど。ポケモンGOのアプリ内通貨、ツムツムのルビーを購入する時に使用する課金形態などです。

非消費型は、一度購入すると永続的に使えるアイテム形式で、1 回のみ購入が必要で、それ以降は使っている googleアカウントに関連付けられているほかのデバイスにも転送できます。例えば、広告の削除、機能のアンロックなど、一度購入すると半永久的に使用できる課金形態。スーパーマリオランのステージアンロックをイメージしてもらえると分かりやすいですね。

厳密には、Google Playのアプリ内課金は『消費型』と『非消費型』を分けていません。実装していく段階で、課金アイテムを消費できるようにするか、永続的に持てるようにするかの違いだけなのです。

今回は種類を分かりやすくするために、あえてiOSのアプリ内課金のような『消費型』と『非消費型』に分けて説明しました。

定期購入型のアイテム

一定期間が過ぎたら、自動で課金を更新できる定期購入型課金です。週間、月間、年間などの設定を適用できるほか、自由に期間を設定することができます。また、無料の試用期間等も設定できます。いわゆるサービスに加入したら、退会するまで自動で購入継続されるという形式ですね。例えば、定期配信の購読、NetflixやHuluなどの月額定額サービスなどがイメージしやすいと思います。

1. プロジェクトにアプリ内課金を導入する

SDK Managerの導入

始めに、アプリ内課金をプロジェクトに導入するための環境を整えていきましょう。上記の画像の指示通り、『SDK Manager』を選択しタブを開いて下さい。

Google Play Billing Libraryの導入

開くと、設定のタブが開きます。『Android SDK ⇒ Android Tools』と進み、画像で示してある『Google Play Billing Library, rev 5』にチェックを入れて下さい。その後、『OK』を選択し、SDKのインストールを完了させて下さい。

完了すると、IInAppBillingService.aidl ファイルが <Android/sdk/extras/google/play_billing/> にインストールされます。ローカルのライブラリから、Android SDKまでのパスを辿りアクセスしてみましょう。IInAppBillingService.aidl ファイルを見つけたら、コピーして下さい。

2. IInAppBillingService.aidlファイルをプロジェクトにペースト

次に、先ほどインストールされた『aidlファイル』をプロジェクトに追加していきます。下記の通りにご自身のアプリプロジェクトに下記順番でディレクトリを作り、aidlファイルをペーストして下さい。

/src/main/com/android/vending/billing

aidlファイルをプロジェクトに含めて、Gradle ツールでプロジェクトをビルドすると、IInAppBillingService.javaファイルが生成されます。正しく生成されたのを確認するために、始めにアプリをビルドします。プロジェクト内の/generatedディレクトリにIInAppBillingService.javaというファイルが生成されたことを確認できましたか?生成できていなかった場合は、もう一度正しい順序で行われているかどうか確認をして下さい。

これでアプリ内課金を導入する上での準備は整いました。

3. アプリ内課金サンプルファイルから、必要ファイルをコピー&ペースト

下記ディレクトリアクセスし、samples内にあるTrivialDriveを開きます。

Android/sdk/extras/google/play_billing/samples/

『example』というフォルダは見つかりましたでしょうか?それをクリックし、『Utilフォルダ』にある下記ファイルをアプリ内課金を導入したいご自身のアプリプロジェクトに移動して下さい。

・Base64.java
・Base64DecoderException.java
・IabException.java
・IabHelper.java
・IabResult.java
・Inventory.java
・Purchase.java
・Security.java
・SkuDetails.java

4. アプリのマニフェストを更新する

Google Play アプリを使うには、AndroidManifest.xml ファイルに com.android.vending.BILLING パーミッションを追加しなければいけません。 アプリ内課金パーミッションを宣言していない場合に課金リクエストを送った場合、アプリ内課金のリクエストはエラーを返します。

アプリに必要なパーミッションを付与するには、AndroidManifest.xml ファイルの中に以下の一行を追加してください。

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

5. 上記ファイルのパッケージ名を全て変更

パッケージ名を変更

次に、先ほどサンプルプロジェクトから追加した『IabException.java』等のパッケージ名をご自身のプロジェクトのパッケージ名に忘れずに変更して下さい。これを忘れると、ビルドエラーになります。

6. Google Play Developer Consoleからライセンスキーを入手する

ライセンスキーをコピー&ペースト

次に、開発者として登録したDeveloer Consoleへアクセスし、『サービスとAPI』にあるライセンスキーをコピーして下さい。開発者登録をしないとライセンスキーを入手できないので、アプリ内課金フレームワークは試すことができません。

7. Google Developer Consoleで課金アイテムを登録する

課金IDの登録画面

次に、Developer Consoleから『アプリ内アイテム』に進み、新しいアイテムをクリックし、課金アイテムを追加して下さい。課金タイプは『管理対象のアイテム』を設定し、アイテムIDは『ここに課金IDする』を入力する部分に書いていきます。

課金IDはユニークなものにする必要があるため、会社ドメインや自身のドメインなど『com.hoge.item01』のような形が良いと思います。

8. アプリ内課金をセットアップ

ActivityのonCreate内に、下記コードを追加していきます。アプリ内課金の接続が正常にされているかどうかをチェックします。また、ユーザーが既に保有しているアイテムを確認するメソッドを実行します。

public class MainActivity extends Activity {
static final String TAG = "Sample";
static final int RC_REQUEST = 10001;
boolean mIsPremium = false;
IabHelper mHelper;
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
String base64EncodedPublicKey = "ここにライセンスキーを追加する";Log.d(TAG, "Creating IAB helper.");
mHelper = new IabHelper(this, base64EncodedPublicKey);
mHelper.enableDebugLogging(true);
Log.d(TAG, "Starting setup.");
mHelper.startSetup(new IabHelper.OnIabSetupFinishedListener() {
public void onIabSetupFinished(IabResult result) {
Log.d(TAG, "Setup finished.");
if (!result.isSuccess()) {
Log.d("Problem setting up in-app billing);
return;
}
if (mHelper == null) return;
Log.d(TAG, "Setup successful. Querying inventory.");
mHelper.queryInventoryAsync(mGotInventoryListener);
}
});
}

9. 購入しているアイテムの確認を行う

上記で記載した下記コードで、ユーザーが購入しているアイテムの所有権を確認します。

mHelper.queryInventoryAsync(mGotInventoryListener);

上記コードを呼ぶと、下記コールバック関数が呼ばれます。Google Developer Consoleで登録したアイテムの課金IDをinventory.getPurchase(“ここに課金ID”)と呼ぶと、mIsPremiumにboolean型で結果が返ってくるので、それに応じてご自身のプロジェクトに合わせて実装して下さい。

IabHelper.QueryInventoryFinishedListener mGotInventoryListener = new IabHelper.QueryInventoryFinishedListener() {
public void onQueryInventoryFinished(IabResult result, Inventory inventory) {
Log.d(TAG, "Query inventory finished.");
if (mHelper == null) return;if (result.isFailure()) {
return;
}
Log.d(TAG, "Query inventory was successful.");
// ここでその課金IDが保有されているかチェックを行います。
// mIsPremiumにbooleanで結果が返ってくるので、それに応じて変化、分岐させればいいです。
Purchase premiumPurchase = inventory.getPurchase("Developer Consoleで登録した課金ID");
mIsPremium = (premiumPurchase != null && verifyDeveloperPayload(premiumPurchase));
Log.d(TAG, "User is " + (mIsPremium ? "PREMIUM" : "NOT PREMIUM"));
}
};
boolean verifyDeveloperPayload(Purchase p) {
String payload = p.getDeveloperPayload();
return true;
}

10. 購入リクエストを送る

次に、下記コードを実行すると記載した課金IDの購入リクエストが送信されます。

String payload = "";                
mHelper.launchPurchaseFlow(getAplicationContext(), "ここに課金IDを入力", RC_REQUEST, mPurchaseFinishedListener, payload);

11. 購入後のコールバック関数を受け取る

購入されると、下記コールバック関数が呼ばれます。ご自身のアプリに合わせて、購入履歴をデータベースに保存など、購入後の処理をして下さい。

// 購入後のコールバック関数
IabHelper.OnIabPurchaseFinishedListener mPurchaseFinishedListener = new IabHelper.OnIabPurchaseFinishedListener() {
public void onIabPurchaseFinished(IabResult result, Purchase purchase) {
android.util.Log.d(TAG, "Purchase finished: " + result + ", purchase: " + purchase);
if (mHelper == null) return;if (result.isFailure()) {
complain("Error purchasing: " + result);
return;
}
if (!verifyDeveloperPayload(purchase)) {
complain("Error purchasing. Authenticity verification failed.");
return;
}
android.util.Log.d(TAG, "Purchase successful.");
if (purchase.getSku().equals("課金ID") {
// 購入後の処理はここ。
// 購入された課金IDを保存などの処理。
}
}
};
// 購入結果をActivityが受け取るための設定
@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
if (mHelper != null && !mHelper.handleActivityResult(requestCode, resultCode, data)) {
super.onActivityResult(requestCode, resultCode, data);
}
}
void complain(String message) {
Log.e(TAG, "**** TrivialDrive Error: " + message);
alert("Error: " + message);
}

12. IABHelperの破棄を行う

アクティビティのonDestroyメソッド内でアクティビティが終了した時に、IABHelperのインスタンスを適切に破棄できるよう、下記コードをプロジェクトに追加します。

@Override
public void onDestroy() {
super.onDestroy();
// very important:
if (mHelper != null) {
mHelper.dispose();
mHelper = null;
}
}

これで、正常に購入アイテムの保有検索、購入処理、購入後の処理分岐など、アプリ内課金で必要な要素は紹介できたかと思います。

アプリ内課金プログラミングの役立ちTips

購入アイテムを消費する

開発をしていると、何度も購入処理をしてデバッグをする必要があると思います。その度に、課金IDを登録するのはとても効率が悪いので、下記コードを実行すると購入したものを消費できます。

mHelper.consumeAsync(inventory.getPurchase(“ここに課金ID”), null);

そうすると、再度その課金IDの購入リクエストを送ることができます。これらを使えば、消費型のアプリ内課金も実装できますね。

課金のテストはリリースビルドで行わなければいけない

アプリ内課金のテストをするには、ベータ版もしくはアルファ版のテスターから実施するか、リリースビルドをしてから、リリース用のapkファイルを直接下記のadbコマンドでインストールしないといけません。ADBコマンドをまだインストールしていない方は、インストールしてくださいね。

adb install “リリース用APKファイルまでのパス”

課金のテストアカウントを用意する

課金リクエストのテストをする場合は、事前に課金で使用するテストアカウントをGoogle Developer Consoleに登録する必要があります。さもないと高額の請求がきます。テスターとして登録されてあると、『これはテスト用の注文です。課金は発生しません。』と表示があるので、これが表示されていない場合は、テスターとしての設定が上手くいって場合があるので、再確認した方が良いです。

『設定 ⇒ テスターのリスト』から追加して下さい。

まとめ

Androidのアプリ内課金は『Version 3』になってからかなり簡単に実装できるようになりました。アプリ内課金を学んで実装できれば、アプリのマネタイズ手法に大きな選択肢ができます。難しそうなイメージがありますが、iOSもAndroidもフレームワークが用意されてあるので、それに慣れてさえすれば実装できると思います。

--

--

DAIKI MOCHIZUKI

Seattle based software developer (iOS, Android, Flutter). I have recently moved to Seattle from japan.