Android 全局悬浮窗
1.在Androidmanifest.xml添加权限
<uses-permission android:name="android.permission.SYSTEM_OVERLAY_WINDOW" />
2.创建悬浮窗
val daeMon = LayoutInflater.from(this).inflate(R.layout.view, null, true)
val windowManager = getSystemService(WINDOW_SERVICE) as WindowManager
val layoutParams = WindowManager.LayoutParams().apply {
width = WindowManager.LayoutParams.WRAP_CONTENT height = WindowManager.LayoutParams.WRAP_CONTENT //设置type type = if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) { //26及以上必须使用TYPE_APPLICATION_OVERLAY @deprecated TYPE_PHONE WindowManager.LayoutParams.TYPE_APPLICATION_OVERLAY } else { WindowManager.LayoutParams.TYPE_PHONE } //设置flags,点击不能穿透 flags = WindowManager.LayoutParams.FLAG_NOT_TOUCH_MODAL or WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE //点击穿透悬浮窗flag //WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE or WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE gravity = Gravity.START or Gravity.TOP //安卓12以上悬浮窗使用TYPE_APPLICATION_OVERLAY则不能穿透,需要把alpha设置0.8f才能,至于0.8这个值是目前测试所有机型可以使用的, // 可以使用android.hardware.input.InputManager.getMaximumObscuringOpacityForTouch()获取 alpha = 0.8f } //将View添加到屏幕上 windowManager.addView(daeMon, layoutParams)
关于安卓12适配,源码有这段话,可以自行查看
悬浮全屏适配:
flags 点击穿透
WindowManager.LayoutParams.FLAG_NOT_TOUCH_MODAL or WindowManager.LayoutParams.FLAG_LAYOUT_NO_LIMITS or WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS
or WindowManager.LayoutParams.FLAG_FULLSCREEN
or WindowManager.LayoutParams.FLAG_LAYOUT_IN_SCREEN
or WindowManager.LayoutParams.FLAG_HARDWARE_ACCELERATED
flags 点击穿透
NOT_EDITABLE(WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE or WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE or WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS
or WindowManager.LayoutParams.FLAG_FULLSCREEN
or WindowManager.LayoutParams.FLAG_LAYOUT_IN_SCREEN
or WindowManager.LayoutParams.FLAG_LAYOUT_NO_LIMITS);
如果若需要适配虚拟导航栏可以添加以下代码收起
然后在创建LayoutParams添加如下
systemUiVisibility = View.SYSTEM_UI_FLAG_HIDE_NAVIGATION or View.SYSTEM_UI_FLAG_IMMERSIVE
最后一个技巧:
部分手机在后台时候如果电池优化设置了限制进程会给杀掉,在有悬浮窗权限前提下,可以添加一个1像素或者几像素完全透明可以点击穿透的悬浮窗