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 になっていろいろと修正が加わっていますので、もし以前のサンプルコードを利用している場合は差分を確認することをおすすめします。
2013/11/28
2013/11/22
「android.view.WindowManager$BadTokenException: Unable to add window -- 」エラーの対処
Androidアプリを制作中、Thread()を利用してshowDialog(int id)でダイアログを表示した場合、Activityが既に変わっていると下記のエラーが表示されました。
android.view.WindowManager$BadTokenException: Unable to add window -- token android.os.BinderProxy@42d617b8 is not valid; is your activity running?
at android.view.ViewRootImpl.setView(ViewRootImpl.java:589)
at android.view.WindowManagerImpl.addView(WindowManagerImpl.java:326)
at android.view.WindowManagerImpl.addView(WindowManagerImpl.java:224)
at android.view.WindowManagerImpl$CompatModeWrapper.addView(WindowManagerImpl.java:149)
at android.view.Window$LocalWindowManager.addView(Window.java:547)
at android.app.Dialog.show(Dialog.java:285)
at android.app.Activity.showDialog(Activity.java:3052)
at android.app.Activity.showDialog(Activity.java:3002)
at jp.sample.SampleActivity.showReviewDialog(SampleActivity.java:98)
at android.os.Handler.handleCallback(Handler.java:615)
at android.os.Handler.dispatchMessage(Handler.java:92)
at android.os.Looper.loop(Looper.java:213)
at android.app.ActivityThread.main(ActivityThread.java:4786)
at java.lang.reflect.Method.invokeNative(Native Method)
at java.lang.reflect.Method.invoke(Method.java:511)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:789)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:556)
at dalvik.system.NativeStart.main(Native Method)
そこで、対象のActivityが終了しているかどうかチェックを行うことで対応できます。
if ( isFinishing() == false ) {
showDialog( DIALOG_ID );
}
ちなみに、showDialog() は、@Deprecated になっているので注意が必要です。
■参考サイト
progressdialog - Android: "BadTokenException: Unable to add window; is your activity running?" at showing dialog in PreferenceActivity - Stack Overflow
Android: android.view.WindowManager$BadTokenException & Android – Displaying Dialogs From Background Threads
android.view.WindowManager$BadTokenException: Unable to add window -- token android.os.BinderProxy@42d617b8 is not valid; is your activity running?
at android.view.ViewRootImpl.setView(ViewRootImpl.java:589)
at android.view.WindowManagerImpl.addView(WindowManagerImpl.java:326)
at android.view.WindowManagerImpl.addView(WindowManagerImpl.java:224)
at android.view.WindowManagerImpl$CompatModeWrapper.addView(WindowManagerImpl.java:149)
at android.view.Window$LocalWindowManager.addView(Window.java:547)
at android.app.Dialog.show(Dialog.java:285)
at android.app.Activity.showDialog(Activity.java:3052)
at android.app.Activity.showDialog(Activity.java:3002)
at jp.sample.SampleActivity.showReviewDialog(SampleActivity.java:98)
at android.os.Handler.handleCallback(Handler.java:615)
at android.os.Handler.dispatchMessage(Handler.java:92)
at android.os.Looper.loop(Looper.java:213)
at android.app.ActivityThread.main(ActivityThread.java:4786)
at java.lang.reflect.Method.invokeNative(Native Method)
at java.lang.reflect.Method.invoke(Method.java:511)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:789)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:556)
at dalvik.system.NativeStart.main(Native Method)
そこで、対象のActivityが終了しているかどうかチェックを行うことで対応できます。
if ( isFinishing() == false ) {
showDialog( DIALOG_ID );
}
ちなみに、showDialog() は、@Deprecated になっているので注意が必要です。
■参考サイト
progressdialog - Android: "BadTokenException: Unable to add window; is your activity running?" at showing dialog in PreferenceActivity - Stack Overflow
Android: android.view.WindowManager$BadTokenException & Android – Displaying Dialogs From Background Threads
2013/11/21
「ドライバー \Driver\WUDFRd を読み込めませんでした。」が発生したら・・・
ブルースクリーンが発生した際のエラーIRQL_NOT_LESS_OR_EQUALを解決するために、イベントビューアーの管理イベントから、エラーが起きたタイミングで発生していた
警告 2013/11/21 16:39:11 Kernel-PnP 219 (212)
デバイス USB\VID_147E&PID_2016\6&3af1eaa2&0&3 のドライバー \Driver\WUDFRd を読み込めませんでした。
をひとまず解決することにしました。(注:まだ未解決の記事です。)
を行いました。
はてさて、これで解決するのかしばらく様子見です。
■2013/11/22追記
変わらずブルースクリーンが発生し(このときはMEMORY_MANAGEMENT)、
警告 2013/11/22 12:52:28 Kernel-PnP 219 (212)
デバイス USB\VID_147E&PID_2016\6&3af1eaa2&0&3 のドライバー \Driver\WUDFRd を読み込めませんでした。
が発生しました。
警告 2013/11/21 16:39:11 Kernel-PnP 219 (212)
デバイス USB\VID_147E&PID_2016\6&3af1eaa2&0&3 のドライバー \Driver\WUDFRd を読み込めませんでした。
をひとまず解決することにしました。(注:まだ未解決の記事です。)
日記という名の不定記 のサイトを参考に
- スタートメニューの「ファイル名を指定して実行」でservices.mscを入力する。
- 一覧から、Windows Driver Foundation - User-mode Driver Frameworkを探してWクリックする。
- スタートアップの種類を「手動」から「自動」に変更する。
を行いました。
はてさて、これで解決するのかしばらく様子見です。
■2013/11/22追記
変わらずブルースクリーンが発生し(このときはMEMORY_MANAGEMENT)、
警告 2013/11/22 12:52:28 Kernel-PnP 219 (212)
デバイス USB\VID_147E&PID_2016\6&3af1eaa2&0&3 のドライバー \Driver\WUDFRd を読み込めませんでした。
が発生しました。
登録:
投稿 (Atom)