2013年6月7日金曜日

アンドロイドでアプリ内課金(v3)のテスト環境




アプリ内課金のテストを行うまでの手順を簡単にまとめます。

①googleアカウントを作成

  普通のgoogleアカウントです。


②googleウォレットの登録

  クレジットカード情報等を登録しましょう。


③販売・配布事業者登録

  Developer Console ( https://play.google.com/apps/publish )
  話を進めていき登録手数料$25支払う
  ※これをしないとアプリが公開できません


④google checkoutの登録

  google checkoutの登録(②のウォレット登録していれば入力が楽)
  ※これをしないと有料アプリやアプリ内課金ができません。


⑤Developer Consoleへ新規のアプリを登録する

  apkのアップロードを行います。
  ※特にこのアップロードしたapkを使わないとアプリ内課金のテストができないという事ではないので
    形式的なものです。未完成のapkをアップロードするのでも全然かまいません。
  ※apkを上げても「公開」されるわけではありません。


⑥Developer Console-アプリ内アイテム-新しいサービスを追加

サービスタイプは以下の3つ
1.管理対象の商品
2.管理対象外の商品
3.定期購入

1.はアカウント単位で1回購入できるアイテム(電子書籍とか)。appleでいうNon-consumable
2.は同一アカウントで何回も購入できるアイテム(回復系アイテムとか)。appleでいうConsumable
3.これはappleのAuto-renewable subscriptionsかな?

今回は何度も購入できるアイテム「2」を選択しました。
サービスID⇒アイテムに一意のIDを振ります。appleのproductID相当です。
後は、タイトルと説明と値段を書く。


⑦上記で作成したアイテムのステータスを「有効」にする



⑧テストアカウント作成

  テストアカウントとはアイテムを購入しても実際に課金される事は無いアカウントです。

  左のメニューバーから「設定」をクリック。
  [アカウントの詳細]ページで少し下にスクロールすると
  [テスト用のアクセス権があるGmailアカウント]という項目があるので
  テスト用のgoogleアカウントを設定する。

  複数のテストアカウントを登録する場合は , で区切ります
  例 test201306071014@gmail.com,test201306071015@gmail.com


⑨アイテム取得のサンプルアプリ

  実装はいろんなサイトで紹介されていますのでそちらを参照下さい。
  例えば http://y-anz-m.blogspot.jp/2013/02/android-api-version3.html

  まずはアイテム情報を取得するプログラムから作成し、それが成功したら
  購入の処理を追加すると良いと思います。

  appleの課金と違って消耗型は明示的に消耗した事をgoogle pleyに連絡しなければならない。
  consumePurchaseしないで再度購入しようとするとエラーになります

  [参考]
  http://catsdallas.blogspot.jp/2012/12/3-in-app-billing-version-3.html


【様々なエラーを体験したので記録しておきます】


(■エラー1)aidlのexception
05-28 11:42:53.068: W/Parcel(709): **** enforceInterface() expected 'com.android.vending.billing.IInAppBillingService' but read 'jp.co.arise.smp.rd002_inapppurchase.purchase.IInAppBillingService'
05-28 11:42:53.068: W/System.err(9859): java.lang.SecurityException: Binder invocation to an incorrect interface
05-28 11:42:53.076: W/System.err(9859):  at android.os.Parcel.readException(Parcel.java:1425)
05-28 11:42:53.076: W/System.err(9859):  at android.os.Parcel.readException(Parcel.java:1379)
05-28 11:42:53.076: W/System.err(9859):  at jp.co.arise.smp.rd002_inapppurchase.purchase.IInAppBillingService$Stub$Proxy.getSkuDetails(IInAppBillingService.java:251)
05-28 11:42:53.076: W/System.err(9859):  at jp.co.arise.smp.rd002_inapppurchase.MainActivity$2.run(MainActivity.java:62)
         ・
         ・
         ・
  ⇒プロジェクトに com.android.vending.billing というパッケージを作って IInAppBillingService.aidl を
    格納しました。勝手にパッケージ名を変えたら上記の様に怒られます。

(■エラー2)「このバージョンのアプリは、Google Playを通じたお支払いはご利用になれません。
    詳しくはヘルプセンターをご覧ください。」
  ⇒署名されたapkファイルを作り(⑤でアップロードしたAPKファイルを作成するときに
     使ったキーで署名しましょう)

    adb.exeを使ってインストールする。
    例:
        (a) [プロジェクト右クリック]-[android tools]-[export signed application package...]で
            apkを作成。
            例 C:\home\RD002_InAppPurchase.apk を作成
        (b) コマンドプロンプトを開く
        (c) cd c:\developAndroid\sdk\platform-tools (SDKの場所は環境により異なります)
        (d) adb install C:\home\RD002_InAppPurchase.apk
            少しすると Successs とでればOK 自動起動しないので実機のアプリ一覧から起動する。
        ※アンインストール adb uninstall jp.co.arise.smp.rd002_inapppurchase
           (マニフェストに書かれているパッケージ)

(■エラー3)「このIDでは課金できません的なエラー」
  ⇒テストアカウントではないから。
     ⑧で登録したテストアカウントがandroid端末に設定されていますか?

(■エラー4)サービスにバインドできない。(以下の部分がfalseになる)
boolean b = bindService(
new Intent("com.android.vending.billing.InAppBillingService.BIND"),
            mServiceConn, Context.BIND_AUTO_CREATE);

  ⇒サービスにバインドできないケースはTabActivityの子Activity内でbindServiceした場合に
    発生するようです。
    解決方法は bindService()を getApplicationContext().bindService() にすればうまくいきます。
boolean b = getApplicationContext().bindService(
new Intent("com.android.vending.billing.InAppBillingService.BIND"),
            mServiceConn, Context.BIND_AUTO_CREATE);


(■エラー5)startIntentSenderForResult()でonActivityResult()がコールバックされない
  ⇒tabactivityを使って startChildActivity() を呼んだ時に onActivetyResultがコールバック
    されない動きになるようです。例えばTab2SubActivityに課金処理を記述した場合

    【コールバックされない呼び方】
Intent intentTicket = new Intent(getParent(), Tab2SubActivity.class);
TabGroupActivity parentActivity = (TabGroupActivity)getParent();
parentActivity.startChildActivity("Tab2SubActivity", intentTicket);

    【コールバックされた呼び方】
Intent intentTicket = new Intent(getParent(), Tab2SubActivity.class);
TabGroupActivity parentActivity = (TabGroupActivity)getParent();
parentActivity.startActivity(intentTicket);

  こういうのは当たり前なのですかね?Activityのメカニズムとか知識が乏しくてすみません・・・


成功するとこんな感じのポップアップが表示されます。

-------------------------
| アプリ内課金チケット               ¥170
| 1枚(test)                                    
|                                                
| これはテスト用の注文です。課金は発生しません。
| お支払い方法を追加して購入を完了するには、[続行]
| をタップしてください。                        
|                                                
| ▲Google play                   [   続行   ]  
-------------------------


■1.続行を押してみる。

■2.「クレジット」か「キャリア課金」の選択を求められる。

■3.とりあえずキャリア課金を選択してみた。

■4.NTT DOCOMOの課金に関する利用規約が表示された。

■5.同意した。

■6.Googleアカウントに保存する請求先住所を入力して下さいと。。。

■7.恐る恐る入力。

すると違う画面が出てきた。
-------------------------
| アプリ内課金チケット               ¥170
| 1枚(test)
| NTT DOCOMO利用料金と一緒に支払い
|                          
| これはテスト用の注文です。課金は発生しません。
| [購入]をタップすると、Googleウォレット利用規約に
| 同意したことになります。          
|                                  
| ▲Google play                   [   購入   ]  
-------------------------

■8.SPモードのパスワードを聞いてきた。

■9.「お支払いが完了しました」という画面が・・・本当に大丈夫だよね。


以上です。


課金周りは実装もそうですが環境で大変な思いをする事があるかと思います。
少しでも助けになればと思い今回はお恥ずかしながらエラーもさらけ出しました。
役に立てば良いなと思います。ありがとうございました。

0 件のコメント:

コメントを投稿