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

需要添加权限

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() {

    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);
            }
        }

        windowManager.addView(button,params)
    }
}

posted @ 2021-01-31 22:08  c-若曦  阅读(1983)  评论(0)    收藏  举报