WindowManager学习笔记

使用

新建一个悬浮按钮,当app退出后,依然显示在桌面上。

public class MainActivity extends AppCompatActivity {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);

        Button floatButton = new Button(this);
        floatButton.setText("悬浮按钮");
        WindowManager.LayoutParams lp =
                new WindowManager.LayoutParams(WindowManager.LayoutParams.WRAP_CONTENT,
                        WindowManager.LayoutParams.WRAP_CONTENT,
                        0, 0, PixelFormat.TRANSPARENT);
        lp.flags = WindowManager.LayoutParams.FLAG_NOT_TOUCH_MODAL;
        lp.type = WindowManager.LayoutParams.TYPE_TOAST;
        lp.gravity = Gravity.CENTER;
        WindowManager windowManager = getWindowManager();
        windowManager.addView(floatButton, lp);

    }
}

加载view的过程

在这里插入图片描述过程参见:带你彻底理解 Window 和 WindowManager
主要过程:

View 是 Android 中的视图的呈现方式,但是 View 不能单独存在,它必须附着在 Window 这个抽象的概念上面,因此有视图的地方就有 Window。哪些地方有视图呢?Android 可以提供视图的地方有 Activity、Dialog、Toast,除此之外,还有一些依托 Window 而实现的视图,比如 PopUpWindow(自定义弹出窗口)、菜单,它们也是视图,有视图的地方就有 Window,因此 Activity、Dialog、Toast 等视图都对应着一个 Window。

异常

1、权限问题

android.view.WindowManager$BadTokenException: Unable to add window android.view.ViewRootImpl$W@6e96dd7 -- permission denied for this window type

一看就是权限问题(问题发生在我的华为手机上,不是所有手机都会报错),

lp.type = WindowManager.LayoutParams.TYPE_SYSTEM_ALERT;

当type使用TYPE_SYSTEM_ALERT时,需要系统权限,但是使用动态权限去申请悬浮窗权限,发现并没有如期弹出请求悬浮窗权限的窗口,需要我们手动来开启:

if (Build.VERSION.SDK_INT >= 23) {
    if (!Settings.canDrawOverlays(this)) {
        Intent intent = new Intent(Settings.ACTION_MANAGE_OVERLAY_PERMISSION,
                Uri.parse("package:" + getPackageName()));
        startActivityForResult(intent, 1);
    }
}

还有一种解决方案就是改变type,

lp.type = WindowManager.LayoutParams.TYPE_TOAST;

这样就不需要系统权限了。

参考

带你彻底理解 Window 和 WindowManager
Android无需权限显示悬浮窗, 兼谈逆向分析app

发布了216 篇原创文章 · 获赞 91 · 访问量 25万+

猜你喜欢

转载自blog.csdn.net/yu75567218/article/details/88315326