2013年6月4日火曜日

In-app billing V3 は singleInstance な Activity では使えない

「Android launchMode の違い」 で解説したように、Activity には4つの launchMode が設定できます。
  • standard
  • singleTop
  • singleTask
  • singleInstance
それぞれの解説は上のエントリーに任せるとして、このなかの singleInstance を指定した Activity で In-app billing V3 の購入処理を行うとうまくいきません。

singleInstance はアプリでタスク1個、タスク内の Activity も1個というストイックな設定です。

In-app billing V3 の課金処理では、Activity の startIntentSenderForResult (IntentSender intent, int requestCode, Intent fillInIntent, int flagsMask, int flagsValues, int extraFlags) を使って購入フローの Activity を起動し、結果を onActivityResult (int requestCode, int resultCode, Intent data) で受けとります。 Result を受けとるため、起動した Activity は同じタスクに入る必要があります。

singleInstance だとタスク内の Activity は1つだけなので、購入フローの Activity は別のタスクとして起動されます。別タスクだと結果が受けとれないので、購入フローの Activity を呼び出した直後に responseCode = RESULT_CANCELED, data = null で onActivityResult() が呼ばれます。

購入フローでは、購入処理が終わったあとに onActivityResult() が呼ばれ、data に購入処理の結果が入ります。このため、singleInstance だと購入情報が受けとれないということになってしまうのです。

Logcat でも下のように購入フロー Activity の呼び出し直後に「Activity is launching as a new task, so cancelling activity result.」と言われています。

06-04 11:59:57.619: I/ActivityManager(533): START u0 {cmp=com.android.vending/com.google.android.finsky.billing.lightpurchase.IabV3Activity (has extras)} from pid -1
06-04 11:59:57.619: W/ActivityManager(533): Activity is launching as a new task, so cancelling activity result.


購入フロー以外の処理、例えば、アイテムの詳細を取得(getSkuDetails())や購入済みアイテムの一覧を取得(getPurchases())やアイテムの消費(consumePurchase ())は普通にできます。



まぁ、singleInstance にするアプリなんてそうそうないと思うけど。



0 件のコメント:

コメントを投稿