小知识,大挑战!本文正在参与“程序员必备小知识”创作活动。

关于作者

众所周知,人生是一个漫长的流程,不断克服困难,不断反思前进的过程。在这个过程中会产生很多对于人生的质疑和思考,apple于是我决定将自己的思考,经验和故事全部分享出来,以此寻找共鸣!!!

专注于Android/Unity和各种游戏开发技巧,approve以及各种资源分享(网站、工具、素材、源码、游戏等)

欢迎关注公众号工资超过5000怎么扣税【空名先生】获取更多资源和交流!

前提

WindowManageappstorer 悬浮窗大家应该经常用了,在这咱不说他的具体实现,也不谈他的源码分析。

主要探讨权限适配,层级介绍,还有可能的Bug。

Android 悬浮窗层级/WindowManager Type限制适配

实践过程

层级

悬浮层本质上是将view送给WindowMandroid下载anager去玩,它将view设置不同类型,也就appear有了不同的层级(z轴)展示,不一样的价钱不一样的服务。

总体来说有应用窗口(APPLICATION_WIN龚俊DOW)、子窗口(SUB_WINDOW)、系统窗口(SYSTEM_WINDOW)三种类型,应用窗口z轴范围是1~99,子窗口的程序员那么可爱电视剧免费观看范围是1001~1999,系统窗口是(2000~2999)。

来做个全套:

Android 悬浮窗层级/WindowManager Type限制适配

Android 悬浮窗层级/WindowManager Type限制适配
看起来一目了然啊,我当初以为拿到这个我就可以实现很多解释不清楚的效果,能上天了,但是an工商银行droid再一次证明它可以 啪APP啪 打你脸,让你叫爸爸。

Android 悬浮窗层级/WindowManager Type限制适配
比如:权限问题,手机android版本不一样,有的Type类型你就用不产品定位了。不带悬念的,即便你申请了appear悬浮权限也不给你。

Android版本7.1.1以上

除了TYP龚俊E_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对其进行了管控,防止滥用应用悬浮窗造成各种干扰,影响体验。

解决问题

  1. 申请悬浮窗权限,或者使用层级较低的TYPE_PHONE悬浮窗。
 if (Build.VERSION.SDK_INT > 24) {
     wmParams.type = WindowManager.LayoutParams.TYPE_PHONE;
   } else {
     wmParams.type = WindowManager.LayoutParams.TYPE_TOAST;
 }
  1. 系统8.0以上使用SYSTEM_ALERT_WINDOW 权限的应用无法再使用以下窗口类型来application在其他应用和系统窗口上方显示提醒窗口:

    • TYP程序员是做什么的E_PHONE
    • TYPE_PRIORITY_PHONE
    • TYPE_SYSTEM_ALERT
    • TYPE_SYSTEM_OVERLAY
    • TYPE_SYSTEM_ERROR
  2. 相反,应用APP必须使用名为 TYPE_APPLICATION_OVERLAY 的新google窗口类型。

  3. 将build.gradle 的sdk版本不超过7.0

  4. 想到更好的实现方式,之后找产品或者设计怼回去

其他

作者:小空和小芝中的小空

转载说明-务必注明来源:芝麻粒儿 的个人主页 – 专栏 – ()

欢迎点赞收藏留言