BadTokenException 解决方案

Posted wangjie1990

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了BadTokenException 解决方案相关的知识,希望对你有一定的参考价值。

技术图片

极力推荐文章:欢迎收藏
Android 干货分享

技术图片

阅读五分钟,每日十点,和您一起终身学习,这里是程序员android

BadTokenException:

log 举例

03-12 14:55:13.734  5564  5564 E AndroidRuntime: FATAL EXCEPTION: main
03-12 14:55:13.734  5564  5564 E AndroidRuntime: Process: com.android.fmradio, PID: 5564
03-12 14:55:13.734  5564  5564 E AndroidRuntime: java.lang.RuntimeException: Error receiving broadcast Intent  act=android.intent.action.HEADSET_PLUG flg=0x40000010 (has extras)  in com.android.fmradio.FmService$FmServiceBroadcastReceiver@b3d2a03
03-12 14:55:13.734  5564  5564 E AndroidRuntime:    at android.app.LoadedApk$ReceiverDispatcher$Args.lambda$getRunnable$0(LoadedApk.java:1401)
03-12 14:55:13.734  5564  5564 E AndroidRuntime:    at android.app.-$$Lambda$LoadedApk$ReceiverDispatcher$Args$_BumDX2UKsnxLVrE6UJsJZkotuA.run(Unknown Source:2)
03-12 14:55:13.734  5564  5564 E AndroidRuntime:    at android.os.Handler.handleCallback(Handler.java:873)
03-12 14:55:13.734  5564  5564 E AndroidRuntime:    at android.os.Handler.dispatchMessage(Handler.java:99)
03-12 14:55:13.734  5564  5564 E AndroidRuntime:    at android.os.Looper.loop(Looper.java:193)
03-12 14:55:13.734  5564  5564 E AndroidRuntime:    at android.app.ActivityThread.main(ActivityThread.java:6702)
03-12 14:55:13.734  5564  5564 E AndroidRuntime:    at java.lang.reflect.Method.invoke(Native Method)
03-12 14:55:13.734  5564  5564 E AndroidRuntime:    at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:493)
03-12 14:55:13.734  5564  5564 E AndroidRuntime:    at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:911)
03-12 14:55:13.734  5564  5564 E AndroidRuntime: Caused by: android.view.WindowManager$BadTokenException: Unable to add window android.view.ViewRootImpl$W@f652dba -- permission denied for window type 2003
03-12 14:55:13.734  5564  5564 E AndroidRuntime:    at android.view.ViewRootImpl.setView(ViewRootImpl.java:851)
03-12 14:55:13.734  5564  5564 E AndroidRuntime:    at android.view.WindowManagerGlobal.addView(WindowManagerGlobal.java:356)
03-12 14:55:13.734  5564  5564 E AndroidRuntime:    at android.view.WindowManagerImpl.addView(WindowManagerImpl.java:93)
03-12 14:55:13.734  5564  5564 E AndroidRuntime:    at android.app.Dialog.show(Dialog.java:329)
03-12 14:55:13.734  5564  5564 E AndroidRuntime:    at com.android.fmradio.FmService$FmServiceBroadcastReceiver.onReceive(FmService.java:322)
03-12 14:55:13.734  5564  5564 E AndroidRuntime:    at android.app.LoadedApk$ReceiverDispatcher$Args.lambda$getRunnable$0(LoadedApk.java:1391)
03-12 14:55:13.734  5564  5564 E AndroidRuntime:    ... 8 more

产生原因

Android 8.0 之后如果要弹出系统弹窗,需要使用 TYPE_APPLICATION_OVERLAY以及
<uses-permission android:name="android.permission.SYSTEM_ALERT_WINDOW" />来进行系统弹窗,否则会报以下异常BadTokenException: Unable to add window android.view.ViewRootImpl$W@f652dba -- permission denied for window type 2003

解决方案

系统弹窗,请用TYPE_APPLICATION_OVERLAY 替换之前的Windows Type。

Dialog mFMDialog = new AlertDialog.Builder(context)
                        .setTitle(R.string.airplane_title).setMessage(R.string.airplane_message)
                        .setPositiveButton(R.string.close_FM,
                            new DialogInterface.OnClickListener() 
                                @Override
                                public void onClick(DialogInterface dialog, int which) 
                        
                                
                            
                        ).setCancelable(false).create();
                    // Android 8.0 之后弹出系统弹窗,需要使用    TYPE_APPLICATION_OVERLAY 
                    // <uses-permission android:name="android.permission.SYSTEM_ALERT_WINDOW" />
                    // 一下两个 之前常用的系统的Dialog 会报 
                    // BadTokenException: Unable to add window android.view.ViewRootImpl$W@f652dba -- permission denied for window type 2003
                    //mFMDialog.getWindow().setType(WindowManager.LayoutParams.TYPE_SYSTEM_DIALOG);
                    //mFMDialog.getWindow().setType(WindowManager.LayoutParams.TYPE_SYSTEM_ALERT);
                    mFMDialog.getWindow().setType(WindowManager.LayoutParams.TYPE_APPLICATION_OVERLAY);
                    mFMDialog.show();

参考 Google Android GO 行为变更

Google 官方链接如下:
Android 8.0 Alert 弹窗行为变更
技术图片

技术图片

至此,本篇已结束,如有不对的地方,欢迎您的建议与指正。同时期待您的关注,感谢您的阅读,谢谢!

技术图片

以上是关于BadTokenException 解决方案的主要内容,如果未能解决你的问题,请参考以下文章

Android7.1.1系统,Toast的Exception: android.view.WindowManager$BadTokenException解决

Android7.1.1系统,Toast的Exception: android.view.WindowManager$BadTokenException解决

Android7.1.1系统,Toast的Exception: android.view.WindowManager$BadTokenException解决

Android7.1.1系统,Toast的Exception: android.view.WindowManager$BadTokenException解决

Android7.1.1系统,Toast的Exception: android.view.WindowManager$BadTokenException解决

[Android]异常8-android.view.WindowManager$BadTokenException