Androidアプリでアプリ内課金(in-app billing v3) を実装するために、TrivialDriveを参考にしていると思います。
TrivialDriveでは、Android 2.2(android:minSdkVersion="8")のため問題なかったのですが、もし、Android 2.1(android:minSdkVersion="7")までを対象にしているアプリを作成していた場合、バックボタンやホームボタンでActivityを終了すると、下記のExceptionが発生します。
11-28 19:53:49.412: E/AndroidRuntime(3697): Uncaught handler: thread main exiting due to uncaught exception
11-28 19:53:49.422: E/AndroidRuntime(3697): java.lang.RuntimeException: Unable to destroy activity {jp.example.android.t
rivialdrivesample/jp.example.android.trivialdrivesample.MainActivity}: java.lang.IllegalArgumentException: Service not r
egistered: jp.example.android.trivialdrivesample.util.IabHelper$1@457a5280
11-28 19:53:49.422: E/AndroidRuntime(3697): at android.app.ActivityThread.performDestroyActivity(ActivityThread.java
:3476)
11-28 19:53:49.422: E/AndroidRuntime(3697): at android.app.ActivityThread.handleDestroyActivity(ActivityThread.java:
3494)
11-28 19:53:49.422: E/AndroidRuntime(3697): at android.app.ActivityThread.access$2800(ActivityThread.java:123)
11-28 19:53:49.422: E/AndroidRuntime(3697): at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1903)
11-28 19:53:49.422: E/AndroidRuntime(3697): at android.os.Handler.dispatchMessage(Handler.java:99)
11-28 19:53:49.422: E/AndroidRuntime(3697): at android.os.Looper.loop(Looper.java:123)
11-28 19:53:49.422: E/AndroidRuntime(3697): at android.app.ActivityThread.main(ActivityThread.java:4370)
11-28 19:53:49.422: E/AndroidRuntime(3697): at java.lang.reflect.Method.invokeNative(Native Method)
11-28 19:53:49.422: E/AndroidRuntime(3697): at java.lang.reflect.Method.invoke(Method.java:521)
11-28 19:53:49.422: E/AndroidRuntime(3697): at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit
.java:850)
11-28 19:53:49.422: E/AndroidRuntime(3697): at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:608)
11-28 19:53:49.422: E/AndroidRuntime(3697): at dalvik.system.NativeStart.main(Native Method)
11-28 19:53:49.422: E/AndroidRuntime(3697): Caused by: java.lang.IllegalArgumentException: Service not registered: jp.ex
ample.android.trivialdrivesample.util.IabHelper$1@457a5280
11-28 19:53:49.422: E/AndroidRuntime(3697): at android.app.ActivityThread$PackageInfo.forgetServiceDispatcher(Activi
tyThread.java:934)
11-28 19:53:49.422: E/AndroidRuntime(3697): at android.app.ApplicationContext.unbindService(ApplicationContext.java:
819)
11-28 19:53:49.422: E/AndroidRuntime(3697): at android.content.ContextWrapper.unbindService(ContextWrapper.java:342)
11-28 19:53:49.422: E/AndroidRuntime(3697): at jp.example.android.trivialdrivesample.util.IabHelper.dispose(IabHelpe
r.java:284)
11-28 19:53:49.422: E/AndroidRuntime(3697): at jp.example.android.trivialdrivesample.MainActivity.onDestroy(MainActi
vity.java:432)
11-28 19:53:49.422: E/AndroidRuntime(3697): at android.app.ActivityThread.performDestroyActivity(ActivityThread.java
:3463)
11-28 19:53:49.422: E/AndroidRuntime(3697): ... 11 more
エラーが発生したソースコードの部分は、
IabHelper.java
public void dispose() {
logDebug("Disposing.");
mSetupDone = false;
if (mServiceConn != null) {
logDebug("Unbinding from service.");
if (mContext != null) mContext.unbindService(mServiceConn);
mServiceConn = null;
mService = null;
mPurchaseListener = null;
}
}
です。Android 2.1 は、in-app-billing v3に対応しておらず、Serviceが立ち上がっていなかったのでunbindしようとしたときにエラーが発生しました。
そこで、下記のように修正します。
IabHelper.java
public void startSetup(final OnIabSetupFinishedListener listener) {
// If already set up, can't do it again.
if (mSetupDone) throw new IllegalStateException("IAB helper is already set up.");
// Connection to IAB service
logDebug("Starting in-app billing setup.");
mServiceConn = new ServiceConnection() {
// 省略
};
Intent serviceIntent = new Intent("com.android.vending.billing.InAppBillingService.BIND");
if (!mContext.getPackageManager().queryIntentServices(serviceIntent, 0).isEmpty()) {
// service available to handle that Intent
mContext.bindService(serviceIntent, mServiceConn, Context.BIND_AUTO_CREATE);
}
else {
// no service available to handle that Intent
if (listener != null) {
listener.onIabSetupFinished(
new IabResult(BILLING_RESPONSE_RESULT_BILLING_UNAVAILABLE,
"Billing service unavailable on device."));
}
mServiceConn = null;// 追加
}
}
一行追加することで、unbindService(mServiceConn)する直前のmServiceConnの null チェックにより、unbindServiceが呼ばれなくなるのでエラーが発生しなくなります。
ちなみに、最近サンプルコードがrev.5 になっていろいろと修正が加わっていますので、もし以前のサンプルコードを利用している場合は差分を確認することをおすすめします。
0 件のコメント:
コメントを投稿
注: コメントを投稿できるのは、このブログのメンバーだけです。