欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  移动技术

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了,第一次入坑,记录一下。