权限问题,手机android版本不一样,有的Type类型你就用不了。即便你申请了悬浮权限也不给你。
一、原因 :Android版本7.1.1以上
- 除了TYPE_TOAST之外都需要申请悬浮窗的权限,否则出现:
android.view.WindowManager$BadTokenException: Unable to add window android.view.ViewRootImpl$W@8d2124d -- permission denied for this window type
at android.app.ActivityThread.handleCreateService(ActivityThread.java:2887)
at android.app.ActivityThread.-wrap4(ActivityThread.java)
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1427)
at android.os.Handler.dispatchMessage(Handler.java:102)
at android.os.Looper.loop(Looper.java:148)
at android.app.ActivityThread.main(ActivityThread.java:5417)
at java.lang.reflect.Method.invoke(Method.java)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:726)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:616)
- 以为申请权限就了事了? 不可能,还有
android.view.WindowManager$BadTokenException: Unable to add window -- window android.view.ViewRootImpl$W@363f7b1 has already been added
at android.view.ViewRootImpl.setView(ViewRootImpl.java:691)
at android.view.WindowManagerGlobal.addView(WindowManagerGlobal.java:342)
at android.view.WindowManagerImpl.addView(WindowManagerImpl.java:94)
at android.widget.Toast$TN.handleShow(Toast.java:434)
at android.widget.Toast$TN$2.handleMessage(Toast.java:345)
at android.os.Handler.dispatchMessage(Handler.java:102)
at android.os.Looper.loop(Looper.java:154)
at android.app.ActivityThread.main(ActivityThread.java:6119)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:886)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:776)
Android官方版本升级对这块权限做了不小的调整,google对其进行了管控,防止滥用应用悬浮窗造成各种干扰,影响体验。
二、问题解决
- 申请悬浮窗权限,或者使用层级较低的TYPE_PHONE悬浮窗。
if (Build.VERSION.SDK_INT > 24) {
wmParams.type = WindowManager.LayoutParams.TYPE_PHONE;
} else {
wmParams.type = WindowManager.LayoutParams.TYPE_TOAST;
}
- 系统8.0以上使用SYSTEM_ALERT_WINDOW 权限的应用
无法
再使用以下窗口类型来在其他应用和系统窗口上方显示提醒窗口:
TYPE_PHONE
TYPE_PRIORITY_PHONE
TYPE_SYSTEM_ALERT
TYPE_SYSTEM_OVERLAY
TYPE_SYSTEM_ERROR
以上类型将无法使用
应用必须使用名为 TYPE_APPLICATION_OVERLAY 的新窗口类型。
- 例如:弹框
//原来的(会报标题错误)
mDialog.getWindow().setType(WindowManager.LayoutParams.TYPE_SYSTEM_ALERT);
//修改的
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
mDialog.getWindow().setType(WindowManager.LayoutParams.TYPE_APPLICATION_OVERLAY);
} else {
mDialog.getWindow().setType(WindowManager.LayoutParams.TYPE_PHONE);
}