[Amazon IAP] Amazonのアプリ内課金を使ってみる

Amazonには、Androidアプリをリリース可能。

アプリのパッケージ名

jp.自分のドメイン名.アプリ名
アプリ毎に持っている識別名は、もしGoogleストアにすでにリリース済みであれば、Amazon用に別途用意して、プロジェクトを書き換えましょう。

jp.自分のドメイン名.amazon.アプリ名
のような。

AdMobはほぼ表示されない現状ですが、広告使うとか、こういった専用のIAPを入れるとか、基本的にあとからは変更できないので。
IAPとは関係ないですが。

IAPアイテムを作成

IAPアイテムの新規作成に記載がありましたが、SKUは、すべてのアプリですべてのIAPアイテムにわたって一意でなければなりません。

自身のSKUの後ろに、IAPアイテムの名称を追加するのがよい感じですね。iOSもそんな感じです。

名称の例
アプリのSKU: jp.cocoamix.amazon.アプリ名
IAPのSKU: jp.cocoamix.amazon.アプリ名.iap_name

jp.cocoamix.amazon.アプリ名.coin
jp.cocoamix.amazon.アプリ名.removeads
のような。

(別の場所には、開発者単位でユニークという記載もありました。「(開発者の)すべてのアプリ」なのかもしれない。)

App Testerなるもの

Amazonが提供しているApp Testerアプリは、アプリからのIAP購入をインターセプトし、App Tester側に用意した結果をアプリに返してくれます。
インターセプトというよりは、App Testerアプリへ直接要求を投げる感じに。

サンプルのビルド

SDKをダウンロード、解凍。
https://developer.amazon.com/ja/docs/in-app-purchasing/iap-get-started.html

上記サイト内の説明のように、examplesフォルダ内のどれか(SampleIAPConsumablesAppなど)を、Import Projectして、新しいプロジェクトを作成。

消費型(使うとなくなるゲーム内コインなど)
非消費型(1度買うとずっと使える。広告解除、機能開放などの利用)
定期購入型(非消費型のような機能を継続させるために、期間ごとの購入)

課金形式には3種類ありますが、非消費型に関しては、マニュアル内でもいくつかの呼び方がされていて、多分戸惑います。
このサンプルでは、SampleIAPEntitlementsAppが、非消費型。

「非消費型=プレミアムバージョン=Entitlements」

build.gradleにgoogle()を追加する。

buildscript {
    repositories {
        google()
        jcenter()
    }
    dependencies {
        classpath 'com.android.tools.build:gradle:4.2.2'
    }
}

allprojects {
    repositories {
        google()
        jcenter()
    }
}

app/libsへ、amazon-appstore-sdk-3.x.x.jarを配置。
Project表示、jarファイルを右クリックからAdd as Libraryする。

Android表示、build.gradle(Module)に、libsを参照する依存関係dependenciesを追加。
(Add as Library時に、単体参照が自動追加されるかもしれない。)

targetSdkVersionも適切な数値に。
(関係ないけれど、現在AdMob利用時のminSdkVersionは最低値16です。)

android {
    compileSdkVersion 30
    buildToolsVersion "30.0.3"

    defaultConfig {
        applicationId "com.amazon.sample.iap.consumable"
        minSdkVersion 10
        targetSdkVersion 30
    }

    buildTypes {
        release {
            minifyEnabled false
            proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.txt'
        }
    }
}

dependencies {
    implementation fileTree(dir: 'libs', include: ['*.jar'])
}

これでビルド可能となる(はず)。

Fireタブレットへビルドする。
画面上のBuy Orangeが最初有効になっているが、アイテムが有効ではないため、しばらくすると無効化される。
→以下のテスターアプリをいれることで、購入対象がみつかり、購入操作が可能になる。

Amazon App Tester
Amazon App Testerを利用すると、疑似的なストアを対象に購入操作ができるようになる。

Amazon App Tester
を、Fireタブレットへダウンロード。

App Testerをインストールして構成する方法

このページでは、adb pushコマンドでコピーしてますが、
examples\SampleIAPConsumablesAppフォルダにあるamazon.sdktester.jsonファイルを、
PCに接続したFireデバイス
PC\Fire\Internal storage直下へファイルをドラッグしてコピーすると、Amazon App Tester内で表示されました。
同じことですね。

このIAPアイテムが記載されているテスト用のjsonファイルは、実際作ろうとするアプリでも、ストアページでアイテムを作成後、ダウンロード可能。

デバイスをサンドボックスモードにする

Windowsではコマンドプロンプトを開き、
SDKフォルダ\platform-tools>adb devices
List of devices attached
00XXXXXXXXXXXXX device

一台だけ表示されるのを確認し、以下のコマンドでアプリをサンドボックスモードに設定。

adb shell setprop debug.amazon.sandboxmode debug

サンドボックスモードを終了するコマンド(ダブルクォーテーションではダメ)
adb shell setprop debug.amazon.sandboxmode ”

サンドボックスモードにした後で、サンプルアプリのSampleIAPConsumablesAppを起動すると、アイテムが購入できるようになっています。
Tester内の設定は標準のまま、Buy Orangeすると、購入画面が表示され、Get Itemすると、orangeが1追加されます。

購入後、Tester内の6. Manage Transactionsを開くと、購入のトランザクションログが追加されています。

1連の購入処理が動いたということですね。

これで購入を確認できる環境ができた。

実装

アプリ内課金(IAP)について
アプリ内課金(IAP)の実装について
IAP APIをアプリに組み込む方法

見ながら作っていたつもりだったけど、リスナーが呼ばれない。
Testerだと確認ができない?なんて思ったりもしたけれど、単に記述が足りなかった。

まず、AndroidManifest.xmlへ、Amazon購入処理からリスナーへのコールバックを受けとるための記述が必須です。

    <receiver android:name = "com.amazon.device.iap.ResponseReceiver"
        android:permission = "com.amazon.inapp.purchasing.Permission.NOTIFY" >
      <intent-filter>
        <action android:name = "com.amazon.inapp.purchasing.NOTIFY" />
      </intent-filter>
    </receiver>

「IAP APIをアプリに組み込む方法」より前に、この記載があるので、最初の結構な見落とし場面です。

基本的には、
1.アプリの起動時に、過去の購入情報を反映させる。
2.購入後に、アプリへ反映させる。
この2か所へ入れ込みます。

onCreate()メソッド内でregisterListener()を呼び出す。
onResume()メソッド内でgetUserData()を呼び出す。
onResume()メソッド内でgetPurchaseUpdates()を呼び出す。
onResume()メソッド内でgetProductData()を呼び出す。

と、説明がありますが

起動時は、
onStartあたりで、
リスナー登録
PurchasingService.registerListener(this, purchasingListener);
購入情報読み込み
PurchasingService.getPurchaseUpdates(false);
→リスナーのonPurchaseUpdatesResponseで購入情報をアプリへ反映

購入時は、購入画面で
リスナー登録
PurchasingService.registerListener(this, purchasingListener);
購入呼び出し
PurchasingService.purchase(sku)
→リスナーのonPurchaseResponseで購入結果をアプリへ反映

この2つの実装で事足りました。
入れたのが、ひとつの非消費型だけだったのもありますが。
画面によってわかりやすくリスナークラスまるまる別でもよい気もします。

いくつか考慮事項として、
購入して、その結果をアプリ反映後は、
PurchasingService.notifyFulfillment(receipt.getReceiptId(), FulfillmentResult.FULFILLED);
での「購入の確定」が必要。

PurchasingService.getPurchaseUpdates(false);
この引数は、falseで、前回呼び出し以降の購入処理が返ってくる。
購入情報は一度反映させるだけでよいため、これでよいはずですが、すべての購入情報を読み込みたいときはtrueにするようです。

ストア上のアイテム一覧を取得する必要があれば、getProductDataで取得。

起動時のMainActivityと、購入用Activityの2か所で利用するため、PurchasingServiceの何かを呼ぶ直前にリスナーを入れ替えました。

そのあたりを気にすると、すぐ作れると思われます。
マニュアル通りに作っていると、日が暮れます。

Testerを使うと、作ったアイテムのjsonファイルをダウンロードして、サンプルのように入れ込めば、自分のアプリでの購入をそのままSANDBOX実行できました。
それで動作が確認できれば、リリースでよいのかもしれない。

ライブテストという機能がストアにあり、一応試したけれど、届くメールからアプリの落とし方がわからず、結局やってません。
実際にリリースできたのち試そうと、しているところ。
リリース済みのアプリなら、そこから落とせるのかなと思ったりはした。

ライブテストできた方、教えてください。

あと、IAPを使う場合は、プロジェクト設定で、以下も必須のようでした。

アプリのコードを難読化する方法
具体的には、
proguard-rulesに何か書いてあったら無効化して、以下だけにする。

#
# いろんなコメント
#
-dontwarn com.amazon.**
-keep class com.amazon.** {*;}
-keepattributes *Annotation*

-dontoptimize

最初に見ないといけなかった所まだありました。
パブリックキーを使用してAppstore SDKを設定する
ストアからAppstoreAuthenticationKey.pemファイル落として、assetsフォルダに入れないといけない。

テスト購入お待ちしてます!!^^
アイデアメモ – 手書きメモ帳アプリ

スポンサーリンク

シェアする

  • このエントリーをはてなブックマークに追加

フォローする