关于WindowManager.addView(view,params)的一些坑

需要添加权限

<uses-permission android:name="android.permission.SYSTEM_ALERT_WINDOW" />

android6.0之后就需要动态获取了

if (!Settings.canDrawOverlays( this)) {
    val intent =  Intent(Settings.ACTION_MANAGE_OVERLAY_PERMISSION,
            Uri.parse("package:" + getPackageName()));
    startActivityForResult(intent, 10);
}

此时你可能会报

Unable to add window android.view.ViewRootImpl$W@6c5ccb7 -- the specified window type 0 is not valid

这是parmas.type没有赋值

stickoerverflow一下,有人说

layoutParams.type = WindowManager.LayoutParams.TYPE_SYSTEM_ERROR;可以解决问题

但是我报了Unable to add window android.view.ViewRootImpl$W@6c5ccb7 -- permission denied for window type 2010

这个不奇怪,因为我发现WindowManager.LayoutParams.TYPE_SYSTEM_ERROR已经被google弃用

查看一下WindowManager.LayoutParams.TYPE_SYSTEM_ERROR的源码

/**
 * Window type: internal system error windows, appear on top of
 * everything they can.
 * In multiuser systems shows only on the owning user's window.
 * @deprecated for non-system apps. Use {@link #TYPE_APPLICATION_OVERLAY} instead.
 */
@Deprecated
public static final int TYPE_SYSTEM_ERROR       = FIRST_SYSTEM_WINDOW+10;

很快就找到了替代品WindowManager.LayoutParams.TYPE_APPLICATION_OVERLAY

完美解决问题,

我的android环境是android.Q的版本 ,希望对大家有帮助,最后附上我的demo

class MainActivity : AppCompatActivity() {
<p>   override fun onCreate(savedInstanceState: Bundle?) {
       super.onCreate(savedInstanceState)
       setContentView(R.layout.activity_main)
       val button = Button(this)
       button.text = "112345"
       val params = WindowManager.LayoutParams(WindowManager.LayoutParams.WRAP_CONTENT,
               WindowManager.LayoutParams.WRAP_CONTENT, 0, 0, PixelFormat.TRANSLUCENT)
       params.flags = (WindowManager.LayoutParams.FLAG_NOT_TOUCH_MODAL
                      or WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE
                      or WindowManager.LayoutParams.FLAG_SHOW_WHEN_LOCKED)
       params.gravity = Gravity.LEFT or Gravity.TOP
       params.x = 100
       params.y = 300
       val windowManager = this.getSystemService(Context.WINDOW_SERVICE) as WindowManager
       params.type = WindowManager.LayoutParams.TYPE_SYSTEM_ERROR;
       if (Build.VERSION.SDK_INT >= 23) {
           if (!Settings.canDrawOverlays( this)) {
               val intent =  Intent(Settings.ACTION_MANAGE_OVERLAY_PERMISSION,
                       Uri.parse("package:" + getPackageName()));
               startActivityForResult(intent, 10);
           }
       }</p>
<p>       windowManager.addView(button,params)
   }
}