最近项目做android O的适配的时候,在以前运行很好的悬浮窗界面却在android O及以上的版本中出现报错
android.view.WindowManager$BadTokenException: Unable to add window android.view.ViewRootImpl$W@7c6708 -- permission denied for window type 2007
下面我们来看看怎么解决这个问题。
1、为什么出现这个错误
这是因为android O对悬浮窗的设计做了一些修改,在使用
android.permission.SYSTEM_ALERT_WINDOW
权限的应用无法再使用以下窗口类型来在其他应用和系统窗口上显示悬浮窗:
-
WindowManager.LayoutParams.TYPE_PRIORITY_PHONE
-
WindowManager.LayoutParams.TYPE_PHONE
-
WindowManager.LayoutParams.TYPE_SYSTEM_ERROR
-
WindowManager.LayoutParams.TYPE_SYSTEM_ALERT
-
WindowManager.LayoutParams.TYPE_SYSTEM_OVERLAY
当在android O及以上版本使用以上窗口类型时就会出现窗口类型权限被拒绝的报错,那我们要使用悬浮窗该如何解决这个问题了?
2、怎样解决
在android O及以上版本中,google为我们新增了
WindowManager.LayoutParams.TYPE_APPLICATION_OVERLAY
的新窗口类型来实现悬浮窗的效果,其他地方和以前版本一样。使用
WindowManager.LayoutParams.TYPE_APPLICATION_OVERLAY
窗口类型时,需要记住新窗口类型的以下特性:
-
应用的悬浮窗始终显示在状态栏和输入法等关键系统窗口的下面
-
系统可以移动使用
WindowManager.LayoutParams.TYPE_APPLICATION_OVERLAY
窗口类型的悬浮窗或者调整其大小,以改善屏幕显示效果
-
通过打开通知栏,用户可以访问设置来阻止应用显示使用
WindowManager.LayoutParams.TYPE_APPLICATION_OVERLAY
窗口类型的悬浮窗
总之,在android O以及以上版本要是用悬浮窗功能,你需要把悬浮窗的type设置成
WindowManager.LayoutParams.TYPE_APPLICATION_OVERLAY
就可以了
最近项目做android O的适配的时候,在以前运行很好的悬浮窗界面却在android O及以上的版本中出现报错android.view.WindowManager$BadTokenException: Unable to add window android.view.ViewRootImpl$W@7c6708 -- permission denied for window type 2007下
现在有很多应用都有
悬浮窗
功能,直播类应用的小窗播放,安全类应用的加速球等等,其实现方式都是通过
Window
Manager.addView()来添加的,最近公司也要求在产品中加入小窗功能,在此记录一下开发中遇到的问题。
为什么有些应用可以不请求
悬浮窗
权限就显示
悬浮窗
这个问题在这两篇文章(
Android
无需权限显示
悬浮窗
, 兼谈逆向分析app,
Android
悬浮窗
TYPE
_TOAST小结: 源码分析
[
Android
Bug]
Android
:
permission
denied
for
window
type
2038 using
网上很多解决方法说要根据SDK的版本调整LayoutParams.
type
。
解决方法类似于:
int LAYOUT_FLAG;
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
LAYOUT_FLAG =
Window
Manager.LayoutParams.
TYPE
_APPLICATION_OVER
如果在代码中设置
Window
Manager.LayoutParams对象的
type
属性
时
,
使用
了划线的常量会
报错
,因为在你这个API版本不支持不建议你
使用
经测试 API 28 开发
悬浮窗
可用的
type
是
Window
Manager.LayoutParams.
TYPE
_APPLICATION_OVERLAY
将
type
属性设置成这个常量即可
在开发过程中,遇到弹出AlertDialog
时
,会报异常
permission
denied
for
window
type
2038,这其实是由于终端
Android
版本不同所需要的权限不同而导致的。
就拿我这次碰到的情况来说,我在判断是否打开了“显示在其他应用的上层”权限
时
加了:
get
Window
().set
Type
(
Window
Manager.LayoutParams.
TYPE
_APPLICATION_OVERLAY);
结果在
8.0
,9.0的机器上实验...
自定义了一个
悬浮窗
,在服务中启动了
悬浮窗
,错误内容如下。
Unable to create service com.example.xhj.RocketService:
android
.view.
Window
Manager$BadTokenException:
Unable to add
window
android
.view.ViewRootImpl$W@6d959e1
--
permission
denied
for
window
typ
首先说明下问题:
android
中添加
悬浮窗
问题权限受拒解决
解决方法一(在
android
6.0以下有效):
在清单配置中添加以下两条权限并将targetSdkVersion设置为23以下,或者将模拟器版api版本调至23以下即可解决此权限受拒问题
android
:name="
android
.
permission
.SYSTEM_ALERT_
WINDOW
" />
android
:name
在
Android
O之前的系统中申请了该权限后,再给对应的
window
设置
Window
Manager.LayoutParams params = new
Window
Manager.LayoutParams();
params.
type
=
Window
Manager.LayoutParams.
TYPE
_PHONE;
Android
6.0以上
使用
Window
nManager实现
悬浮窗
会出现如图错误信息,这个是因为在
Android
6.0以上我们需要去打开授权应用ACTION_MANAGE_OVERLAY_
PERMISSION
权限才可以正常
使用
悬浮窗
。@Override
protected void onCreate(Bundle savedInstanceState) {
super.onC
// 设置窗体显示类型
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
layoutParams.
type
=
Window
Manager.LayoutParams.
TYPE
_APPLICATION_OVERLAY;
报错
内容:
Caused by:
android
.view.
Window
Manager$BadTokenException: Unable to add
window
android
.view.ViewRootImpl$W@4035b5b --
permission
denied
for
window
type
2003
at
android
.view.ViewRootImpl.setView(Vi...