add window android.view.ViewRootImpl$W@fa525bc -- permission denied for window type 2003
程序员文章站
2022-05-03 17:57:25
问题详情:android.view.windowmanager$badtokenexception
unable to add window android.view.viewrootimpl$w@...
问题详情:android.view.windowmanager$badtokenexception
unable to add window android.view.viewrootimpl$w@fa525bc -- permission denied for window type 2003
先说下这个坑出现的原因吧,这个问题经测试只有在android8.0才会出现,所以这个问题出现的原因是我们没有悬浮窗权限以及指定的windowmanager窗口类型有误。
这里要解释一下:android 8.0我们要弹出一个dialog时,不要设置
windowmanager.layoutparams.type为windowmanager.layoutparams.type_system_alert,?
而是要设置为:windowmanager.layoutparams.type_application_overlay
代码如下:
windowmanager.layoutparams lp = dialog.getwindow().getattributes(); lp.width = (int) (display.getwidth() - width); //设置宽度 //窗口类型 if (build.version.sdk_int >= build.version_codes.o) { lp.type = windowmanager.layoutparams.type_application_overlay; } else { lp.type = windowmanager.layoutparams.type_system_alert; } dialog.getwindow().setattributes(lp); dialog.show();
故:我们要在设置窗口类型的时候判断是否为8.0及以上,然后进行不同的设置。
注意:设置窗口类型一定要在dialog调用show()方法之前。
此外,我们还需要在androidmanifest.xml中添加权限:
如果是android 8.0系统,需要我们动态授权悬浮窗权限,代码如下:
@targetapi(build.version_codes.o) protected boolean requestdrawoverlays() { if (!settings.candrawoverlays(mcontext)) { showmsg("使用本应用需要您开启悬浮窗权限,请前往设置。"); intent intent = new intent(settings.action_manage_overlay_permission, uri.parse("package:" + mcontext.getpackagename())); startactivityforresult(intent, constant.overlay_permission_req_code); return false; } return true; }
@override protected void onactivityresult(int requestcode, int resultcode, intent data) { super.onactivityresult(requestcode, resultcode, data); switch (requestcode) { case constant.overlay_permission_req_code: if (requestdrawoverlays()) { //允许悬浮窗 } break; } }
到此已经ok了,第一次入坑,记录一下。