美文网首页android进阶
Android添加悬浮窗的一些总结

Android添加悬浮窗的一些总结

作者: handsomeslow | 来源:发表于2017-06-30 16:44 被阅读3236次

首先先了解几个知识点:

SDK版本低于7.1.1使用WindowManager.LayoutParams.TYPE_TOAST是不需要授权的,可以像平时用的toast一样展示与任何界面之上,而除了TYPE_TOAST之外都需要申请悬浮窗的权限:

悬浮窗授权

若用户并没有申请此权限而添加悬浮窗的话会有以下crash信息:

android.view.WindowManager$BadTokenException: Unable to add window android.view.ViewRootImpl$W@8d2124d -- permission denied for this window type
       at android.app.ActivityThread.handleCreateService(ActivityThread.java:2887)
       at android.app.ActivityThread.-wrap4(ActivityThread.java)
       at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1427)
       at android.os.Handler.dispatchMessage(Handler.java:102)
       at android.os.Looper.loop(Looper.java:148)
       at android.app.ActivityThread.main(ActivityThread.java:5417)
       at java.lang.reflect.Method.invoke(Method.java)
       at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:726)
       at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:616)

所以使用TYPE_TOAST的好处很明显,但是由于从7.1.1开始很多人会遇到以下crash信息:

android.view.WindowManager$BadTokenException: Unable to add window -- window android.view.ViewRootImpl$W@363f7b1 has already been added
       at android.view.ViewRootImpl.setView(ViewRootImpl.java:691)
        at android.view.WindowManagerGlobal.addView(WindowManagerGlobal.java:342)
        at android.view.WindowManagerImpl.addView(WindowManagerImpl.java:94)
        at android.widget.Toast$TN.handleShow(Toast.java:434)
        at android.widget.Toast$TN$2.handleMessage(Toast.java:345)
        at android.os.Handler.dispatchMessage(Handler.java:102)
        at android.os.Looper.loop(Looper.java:154)
        at android.app.ActivityThread.main(ActivityThread.java:6119)
        at java.lang.reflect.Method.invoke(Native Method)
        at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:886)
        at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:776)

这是由于Android限制了使用TYPE_TOAST,查看7.1.1 版本代码的变更,我们可以看到有这样的一条记录:

提交记录

Prevent apps to overlay other apps via toast windows 这句话已经说明了一切,就是试图改变TYPE_TOAST之前被滥用的现状。

所以7.1.1之后不要再使用TYPE_TOAST,改为使用TYPE_PHONE,并且需要在开启悬浮窗前必须主动申请一下权限:

      try {
            Class clazz = Settings.class;
            Field field = clazz.getDeclaredField(Settings.ACTION_MANAGE_OVERLAY_PERMISSION);

            Intent intent = new Intent(field.get(null).toString());
            intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
            intent.setData(Uri.parse("package:" + context.getPackageName()));
            context.startActivity(intent);
        } catch (Exception e) {
            GLog.e(TAG, e.getMessage());
        }

所以我们的WindowManager初始化改为了:

        WindowManager.LayoutParams wmParams = new WindowManager.LayoutParams();

        windowManager = (WindowManager) context.getSystemService(context.WINDOW_SERVICE);
        if (Build.VERSION.SDK_INT > 24) {
            wmParams.type = WindowManager.LayoutParams.TYPE_PHONE;
        } else {
            wmParams.type = WindowManager.LayoutParams.TYPE_TOAST;
        }

        wmParams.format = PixelFormat.RGBA_8888;
        //设置浮动窗口不可聚焦(实现操作除浮动窗口外的其他可见窗口的操作)
        wmParams.flags = WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE;
        //调整悬浮窗显示的停靠位置为左侧置顶
        wmParams.gravity = Gravity.LEFT | Gravity.TOP;
        // 以屏幕左上角为原点,设置x、y初始值,相对于gravity
        wmParams.x = 0;
        wmParams.y = 0;

        //设置悬浮窗口长宽数据
        wmParams.width = WindowManager.LayoutParams.WRAP_CONTENT;
        wmParams.height = WindowManager.LayoutParams.WRAP_CONTENT;

相关文章

  • Android添加悬浮窗的一些总结

    首先先了解几个知识点: SDK版本低于7.1.1使用WindowManager.LayoutParams.TYPE...

  • Android悬浮窗用法总结

    转载请注明出处:Android悬浮窗用法总结 最近项目里用到了悬浮窗,在这里做一下总结。 WindowManage...

  • Android 悬浮窗<下>

    上篇Android 悬浮窗<上>已经将Window、WindowManager做了一些简单介绍,并且将悬浮窗适配做...

  • Android 悬浮窗总结

    有两种方式实现微信等App的新消息通知效果: 一种是利用WindowManager加载布局实现(需要获取权限); ...

  • Android 悬浮窗-开箱即用

    开箱即用的 Android 悬浮窗 开箱即用的 Android 悬浮窗 FloatWindowX 1. 需要权限 ...

  • android 悬浮窗

    安卓悬浮窗的书写,我们分为几个步骤: 1.添加悬浮窗权限 2.书写悬浮窗代码,搭建悬浮窗布局 3.判断悬浮窗权限是...

  • android悬浮窗源码分析

    代码实现添加悬浮窗 分析的源码为:android 8.0 api26 关键代码:WindowManager.add...

  • Android 悬浮窗相关

    构造方法 添加view到WindowManager 显示悬浮窗 隐藏悬浮窗 广播接收,来更新悬浮窗里的值 注意 用...

  • 关于android 悬浮窗和自启动的设置, 以及获取系统的信息

    关于android 悬浮窗和自启动的设置, 以及获取系统的信息 标签(空格分隔):Android 悬浮窗 对于是否...

  • Android权限适配(二)

    本文接 Android权限适配(一) 悬浮窗权限 悬浮窗权限同样属于上文中说到的特殊权限。 悬浮窗代码的设置 要使...

网友评论

    本文标题:Android添加悬浮窗的一些总结

    本文链接:https://www.haomeiwen.com/subject/lhticxtx.html