很多地方用到悬浮窗口,但是android现在做了很多限制,禁止悬浮窗口的滥用,尤其是系统权限的窗口基本不予支持,以下是介绍应用内部悬浮窗口不需要任何系统权限的
1 显示一个悬浮窗
// wm = (WindowManager)getApplicationContext().getSystemService(Context.WINDOW_SERVICE);
wm = getWindowManager();
wmParams = new WindowManager.LayoutParams();
// wmParams.type = WindowManager.LayoutParams.TYPE_SYSTEM_ALERT;
wmParams.format= PixelFormat.TRANSPARENT;//设置图片格式,效果为背景透明
wmParams.flags= WindowManager.LayoutParams.FLAG_NOT_TOUCH_MODAL
| WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE
| WindowManager.LayoutParams.FLAG_FULLSCREEN
| WindowManager.LayoutParams.FLAG_TRANSLUCENT_NAVIGATION; //窗口被虚拟按键遮挡问题
wmParams.gravity = Gravity.RIGHT|Gravity.BOTTOM;
wmParams.x = (int)(6*Utils.getScreenDensity());
wmParams.y = (int)(8*Utils.getScreenDensity());
wmParams.width = (int)(FloatScanView.FLOATVIEW_W * Utils.getScreenDensity()); //初始化窗口大小为设置按钮大小
wmParams.height = (int)((FloatScanView.FLOATVIEW_H + FloatScanView.h_bottom ) * Utils.getScreenDensity());
上面的第一行被屏蔽的代码可以看到通过getSystemService(Context.WINDOW_SERVICE)
拿到WindowManager,但是通过这种方式获取WindowManager会导致小米手机等部分手机需要系统权限,而我们只是需要做一个应用内部的悬浮窗口,不需要设置任何相关权限,所以可以直接通过Activity下的getWindowManager();函数得到WindowManager,并且也不需要设置窗口类型type。
2 说到窗口类型 window.type,上面的应用窗口是不需要这个type设置
下面介绍常用的几个系统级别的TYPE:
WindowManager.LayoutParams.TYPE_SYSTEM_PHONE: 而它是非应用窗口,需要系统权限
WindowManager.LayoutParams.TYPE_SYSTEM_ALERT: 和TYPE_SYSTEM_PHONE类似,都要系统权限
WindowManager.LayoutParams.TYPE_SYSTEM_TOAST: 可以绕过系统权限检查,但是API25以上直接禁止用户使用TYPE_TOST创建悬浮窗,而且一些小米的系统修改WindowManager的代码,导致该系统在这个type下不能显示悬浮窗
参考文章https://www.imooc.com/article/38964
参考文章https://blog.csdn.net/forLittleBlue/article/details/59563755
总而言之就是不建议开发系统权限的窗口,android限制越来越严格,针对系统级别的后面的API都做了限制