
本文是关于针对Android WindowManager悬浮窗行为变化的总结。
官方参考
WindowManager
public interface WindowManager
implements ViewManager
android.view.WindowManager
示例
首先创建一个简单的WindowManager悬浮窗,具体代码如下:
1 | package com.shoewann.windowmanager; |
上面的代码简单易懂,这里就不再进行解释了。
最后不要忘记了,在AndroidManifest.xml添加所需要的权限。
1 | <uses-permission android:name="android.permission.SYSTEM_ALERT_WINDOW" /> |
行为变化
SDK < Android M
以上的示例代码,在这种情况下(比如Kitkat 4.4)的设备上现在就已经可以成功创建出一个系统悬浮窗了。
运行,效果图如下
SDK >= Android M
到了Android M 之后的设备,也就是targetSdkVersion要指定23(及其以上),程序就会崩溃,抛出如下异常信息:
1 | E/AndroidRuntime: FATAL EXCEPTION: main |
参考:SYSTEM_ALERT_WINDOW
Note: If the app targets API level 23 or higher, the app user must explicitly grant this permission to the app through a permission management screen. The app requests the user’s approval by sending an intent with action ACTION_MANAGE_OVERLAY_PERMISSION. The app can check whether it has this authorization by calling Settings.canDrawOverlays().
官方的解释是,如果你的应用程序目标API等级为23或者更高版本,在使用SYSTEM_ALERT_WINDOW权限时,需要先调用Settings.canDrawOverlays()来判断一下是否允许创建悬浮窗,如果允许的话就可以创建了,不允许的话还要发送一个action值为ACTION_MANAGE_OVERLAY_PERMISSION的Intent来让用户同意创建悬浮窗。
针对该行为变化,对上面的示例代码进行了修改,添加权限请求,以兼容Android M:
1 | package com.shoewann.windowmanager; |
运行,效果图如下
SDK >= Android O
到了Android O 的设备运行上面在M上二次修改的动态请求权限的代码,程序抛出运行时异常,随后崩溃,这又是为什么呢?
1 | E/AndroidRuntime: FATAL EXCEPTION: main |
查阅Android Oreo官方文档,Alert windows行为变化
应用程序使用SYSTEM_ALERT_WINDOW权限时,不再支持如下窗口类型在其他应用和系统窗口之上显示警告窗口了:
- TYPE_PHONE
- TYPE_PRIORITY_PHONE
- TYPE_SYSTEM_ALERT
- TYPE_SYSTEM_OVERLAY
- TYPE_SYSTEM_ERROR
应用必须使用一个被叫做TYPE_APPLICATION_OVERLAY类型的新窗口类型替代。
当使用TYPE_APPLICATION_OVERLAY类型的窗口为你的应用程序去显示警告窗口,请记住新窗口的如下特征:
- 一个应用程序的警告窗口总是显示在系统窗口之下,比如状态栏和输入法。
- 系统能够移除和重置窗口大小,使用TYPE_APPLICATION_OVERLAY类型的窗口去提高屏幕演示
- 通过打开通知栏窗帘,用户能够访问设置去屏蔽一个应用通过TYPE_APPLICATION_OVERLAY窗口类型去显示警告窗口的显示
针对该行为变化,对上面的示例代码进行了修改,以兼容Android O:
更改TYPE_PHONE为TYPE_APPLICATION_OVERLAY
1 | - params.type = WindowManager.LayoutParams.TYPE_PHONE; |
运行,效果图如下
以上就是简单的对Android WindowManager悬浮窗行为变化的简单总结。如有不足,欢迎指正,谢谢。