Android 应用弹出悬浮窗

这篇具有很好参考价值的文章主要介绍了Android 应用弹出悬浮窗。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

Android开发者经常遇到应用想弹出悬浮窗的操作,而且有可能还想要高层级弹窗,就像ipone的浮标touch一样。android当然也有类似的悬浮图标,比如前些年我们的流量监控提醒。

android 应用内悬浮,Android程序,android,view

 这里我们忽略UI美学,简单记录一下:

1、基本使用

它的基本使用步骤是不会变的,只是有时候我们可能根据不同需求会改变它样式的参数,首先记得在 manifests.xml 清单文件中添加权限,然后根据需要申请权限,如果是系统级应用,可以让系统工程师配置赋予我们的应用权限:

    <!-- 允许程序添加悬浮窗 -->
    <uses-permission android:name="android.permission.SYSTEM_ALERT_WINDOW" />
if (!Settings.canDrawOverlays(this)) {
            Logger.d("onCreate: canDrawOverlays false.");
            Intent intent = new Intent();
            intent.setAction(Settings.ACTION_MANAGE_OVERLAY_PERMISSION);
            startActivity(intent);
        }else {
            Logger.d("onCreate: canDrawOverlays true.");
            showWindowView();
        }

具体的怎么添加呢:

    private void showWindowView(){
         //Activity中的方法,得到窗口管理器
        mWindowManager = (WindowManager) getSystemService(Context.WINDOW_SERVICE);
        //设置悬浮窗布局属性
        WindowManager.LayoutParams mWindowLayoutParams = new WindowManager.LayoutParams();
        //设置类型,具体有哪些值可取在后面附上
    // 设置窗体显示类型
    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
        mWindowLayoutParams.type =WindowManager.LayoutParams.TYPE_APPLICATION_OVERLAY;
    } 
    else {
        mWindowLayoutParams.type = WindowManager.LayoutParams.TYPE_PHONE;
    }
        //设置行为选项,具体有哪些值可取在后面附上
        mWindowLayoutParams.flags = WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE;
        //设置悬浮窗的显示位置
        mWindowLayoutParams.gravity = Gravity.LEFT | Gravity.TOP;
//        //设置悬浮窗的横竖屏,会影响屏幕方向,只要悬浮窗不消失,屏幕方向就会一直保持,可以强制屏幕横屏或竖屏
//        mWindowLayoutParams.screenOrientation = ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE;
        //设置悬浮窗的宽度
        mWindowLayoutParams.width = WindowManager.LayoutParams.MATCH_PARENT;
        //设置悬浮窗的高度
        mWindowLayoutParams.height = 200;
        //设置悬浮窗的布局
        LinearLayout linearLayout = new LinearLayout(this);
        linearLayout.setBackgroundColor(Color.GRAY);
        TextView textView = new TextView(this);
        textView.setTextColor(getColor(R.color.white_16p));
        textView.setTextSize(32);
        textView.setGravity(Gravity.CENTER);
        textView.setText("测试浮窗");
        LinearLayout.LayoutParams layoutParams = new LinearLayout.LayoutParams(
                LinearLayout.LayoutParams.MATCH_PARENT, LinearLayout.LayoutParams.MATCH_PARENT);
        linearLayout.addView(textView, layoutParams);
        //加载显示悬浮窗
        mWindowManager.addView(linearLayout, mWindowLayoutParams);
    }

注释中提到悬浮窗只要不消失,屏幕方向就会一直保持,如果设置悬浮窗横屏,将程序退到后台时,则手机桌面也会横屏,看起来就会很不舒服,所以如果不是特定需求,我们可以在 onStart() 的时候添加悬浮窗,然后在 onStop() 方法的时候调用 WindowManager 的 removeView() 方法让其消失,就不会影响屏幕方向了。需要注意的时候不能重复添加同一个悬浮窗,否则会报  java.lang.IllegalStateException: View android.widget.LinearLayout{3284dae1 V.E..... ......I. 0,0-0,0} has already been added to the window manager的异常,所以在添加悬浮窗之前最好先判断一下该悬浮窗是否已添加:

if (linearLayout.isAttachedToWindow())

2、type 和 flags 可取值

type 可取值

应用程序窗口。
public static final int FIRST_APPLICATION_WINDOW = 1;

所有程序窗口的“基地”窗口,其他应用程序窗口都显示在它上面。     
public static final int TYPE_BASE_APPLICATION =1;
    
普通应用功能程序窗口。token必须设置为Activity的token,以指出该窗口属谁。
public static final int TYPE_APPLICATION = 2;

用于应用程序启动时所显示的窗口。应用本身不要使用这种类型。
它用于让系统显示些信息,直到应用程序可以开启自己的窗口。   
public static final int TYPE_APPLICATION_STARTING = 3; 
     
应用程序窗口结束。
public static final int LAST_APPLICATION_WINDOW = 99;

子窗口。子窗口的Z序和坐标空间都依赖于他们的宿主窗口。
public static final int FIRST_SUB_WINDOW = 1000;

面板窗口,显示于宿主窗口上层。
public static final int TYPE_APPLICATION_PANEL = FIRST_SUB_WINDOW;

媒体窗口,例如视频。显示于宿主窗口下层。
public static final int TYPE_APPLICATION_MEDIA  = FIRST_SUB_WINDOW+1;

应用程序窗口的子面板。显示于所有面板窗口的上层。(GUI的一般规律,越“子”越靠上)
public static final int TYPE_APPLICATION_SUB_PANEL = FIRST_SUB_WINDOW +2;

对话框。类似于面板窗口,绘制类似于顶层窗口,而不是宿主的子窗口。
public static final int TYPE_APPLICATION_ATTACHED_DIALOG = FIRST_SUB_WINDOW +3;

媒体信息。显示在媒体层和程序窗口之间,需要实现透明(半透明)效果。(例如显示字幕)
public static final int TYPE_APPLICATION_MEDIA_OVERLAY  = FIRST_SUB_WINDOW +4;

子窗口结束。( End of types of sub-windows )
public static final int LAST_SUB_WINDOW = 1999;

系统窗口。非应用程序创建。
public static final int FIRST_SYSTEM_WINDOW = 2000;

状态栏。只能有一个状态栏;它位于屏幕顶端,其他窗口都位于它下方。
public static final int TYPE_STATUS_BAR =  FIRST_SYSTEM_WINDOW;

搜索栏。只能有一个搜索栏;它位于屏幕上方。
public static final int TYPE_SEARCH_BAR = FIRST_SYSTEM_WINDOW+1;

电话窗口。它用于电话交互(特别是呼入)。它置于所有应用程序之上,状态栏之下。
public static final int TYPE_PHONE = FIRST_SYSTEM_WINDOW+2;

系统提示。它总是出现在应用程序窗口之上。
public static final int TYPE_SYSTEM_ALERT =  FIRST_SYSTEM_WINDOW +3;

锁屏窗口。
public static final int TYPE_KEYGUARD = FIRST_SYSTEM_WINDOW +4;

信息窗口。用于显示toast。
public static final int TYPE_TOAST = FIRST_SYSTEM_WINDOW +5;

系统顶层窗口。显示在其他一切内容之上。此窗口不能获得输入焦点,否则影响锁屏。
public static final int TYPE_SYSTEM_OVERLAY =  FIRST_SYSTEM_WINDOW +6;

电话优先,当锁屏时显示。此窗口不能获得输入焦点,否则影响锁屏。
public static final int TYPE_PRIORITY_PHONE =  FIRST_SYSTEM_WINDOW +7;

系统对话框。(例如音量调节框)。
public static final int TYPE_SYSTEM_DIALOG =  FIRST_SYSTEM_WINDOW +8;

锁屏时显示的对话框。
public static final int TYPE_KEYGUARD_DIALOG =  FIRST_SYSTEM_WINDOW +9;

系统内部错误提示,显示于所有内容之上。
public static final int TYPE_SYSTEM_ERROR =  FIRST_SYSTEM_WINDOW +10;

内部输入法窗口,显示于普通UI之上。应用程序可重新布局以免被此窗口覆盖。
public static final int TYPE_INPUT_METHOD =  FIRST_SYSTEM_WINDOW +11;

这个值我也不是每个都试过,所以具体效果会有什么不同不能妄言。感兴趣的可以都尝试一下。

flags 可取值

窗口之后的内容变暗。  
public static final int FLAG_DIM_BEHIND = 0x00000002; 
  
窗口之后的内容变模糊。  
public static final int FLAG_BLUR_BEHIND = 0x00000004;
  
不许获得焦点。不能获得按键输入焦点,所以不能向它发送按键或按钮事件。那些时间将发送给它后面的可以获得焦点的窗口。此选项还会设置FLAG_NOT_TOUCH_MODAL选项。设置此选项,意味着窗口不能与软输入法进行交互,所以它的Z序独立于任何活动的输入法(换句话说,它可以全屏显示,如果需要的话,可覆盖输入法窗口)。要修改这一行为,可参考FLAG_ALT_FOCUSALBE_IM选项。  
public static final int FLAG_NOT_FOCUSABLE = 0x00000008;
  
不接受触摸屏事件。  
public static final int FLAG_NOT_TOUCHABLE = 0x00000010;
  
当窗口可以获得焦点(没有设置 FLAG_NOT_FOCUSALBE 选项)时,仍然将窗口范围之外的点设备事件(鼠标、触摸屏)发送给后面的窗口处理。否则它将独占所有的点设备事件,而不管它们是不是发生在窗口范围内。  
public static final int FLAG_NOT_TOUCH_MODAL = 0x00000020;
  
如果设置了这个标志,当设备休眠时,点击触摸屏,设备将收到这个第一触摸事件。通常第一触摸事件被系统所消耗,用户不会看到他们点击屏幕有什么反应。  
public static final int FLAG_TOUCHABLE_WHEN_WAKING = 0x00000040;
  
当此窗口为用户可见时,保持设备常开,并保持亮度不变。  
public static final int FLAG_KEEP_SCREEN_ON = 0x00000080;
  
窗口占满整个屏幕,忽略周围的装饰边框(例如状态栏)。此窗口需考虑到装饰边框的内容。  
public static final int FLAG_LAYOUT_IN_SCREEN =0x00000100;
  
允许窗口扩展到屏幕之外。  
public static final int FLAG_LAYOUT_NO_LIMITS =0x00000200;
  
窗口显示时,隐藏所有的屏幕装饰(例如状态条)。使窗口占用整个显示区域。  
public static final int FLAG_FULLSCREEN = 0x00000400;
  
此选项将覆盖FLAG_FULLSCREEN选项,并强制屏幕装饰(如状态条)弹出。  
public static final int FLAG_FORCE_NOT_FULLSCREEN =0x00000800;
  
抖动。指 对半透明的显示方法。又称“点透”。图形处理较差的设备往往用“点透”替代Alpha混合。  
public static final int FLAG_DITHER = 0x00001000;
 
不允许屏幕截图。  
public static final int FLAG_SECURE = 0x00002000;
  
一种特殊模式,布局参数用于指示显示比例。  
public static final int FLAG_SCALED = 0x00004000;
  
当屏幕有可能贴着脸时,这一选项可防止面颊对屏幕造成误操作。  
public static final int FLAG_IGNORE_CHEEK_PRESSES = 0x00008000;
  
当请求布局时,你的窗口可能出现在状态栏的上面或下面,从而造成遮挡。当设置这一选项后,窗口管理器将确保窗口内容不会被装饰条(状态栏)盖住。  
public static final int FLAG_LAYOUT_INSET_DECOR = 0x00010000;
  
反转FLAG_NOT_FOCUSABLE选项。如果同时设置了FLAG_NOT_FOCUSABLE选项和本选项,窗口将能够与输入法交互,允许输入法窗口覆盖;如果FLAG_NOT_FOCUSABLE没有设置而设置了本选项,窗口不能与输入法交互,可以覆盖输入法窗口。  
public static final int FLAG_ALT_FOCUSABLE_IM = 0x00020000;
  
如果你设置了FLAG_NOT_TOUCH_MODAL,那么当触屏事件发生在窗口之外事,可以通过设置此标志接收到一个MotionEvent.ACTION_OUTSIDE事件。注意,你不会收到完整的down/move/up事件,只有第一次down事件时可以收到ACTION_OUTSIDE。  
public static final int FLAG_WATCH_OUTSIDE_TOUCH = 0x00040000;
  
当屏幕锁定时,窗口可以被看到。这使得应用程序窗口优先于锁屏界面。可配合FLAG_KEEP_SCREEN_ON选项点亮屏幕并直接显示在锁屏界面之前。可使用FLAG_DISMISS_KEYGUARD选项直接解除非加锁的锁屏状态。此选项只用于最顶层的全屏幕窗口。  
public static final int FLAG_SHOW_WHEN_LOCKED = 0x00080000;
  
请求系统墙纸显示在你的窗口后面。窗口必须是半透明的。  
public static final int FLAG_SHOW_WALLPAPER = 0x00100000;
  
窗口一旦显示出来,系统将点亮屏幕,正如用户唤醒设备那样。  
public static final int FLAG_TURN_SCREEN_ON = 0x00200000;
  
解除锁屏。只有锁屏界面不是加密的才能解锁。如果锁屏界面是加密的,那么用户解锁之后才能看到此窗口,除非设置了FLAG_SHOW_WHEN_LOCKED选项。  
public static final int FLAG_DISMISS_KEYGUARD = 0x00400000;
  
锁屏界面淡出时,继续运行它的动画。  
public static final int FLAG_KEEP_SURFACE_WHILE_ANIMATING =0x10000000;
  
以原始尺寸显示窗口。用于在兼容模式下运行程序。  
public static final int FLAG_COMPATIBLE_WINDOW = 0x20000000;
  
用于系统对话框。设置此选项的窗口将无条件获得焦点。  
public static final int FLAG_SYSTEM_ERROR = 0x40000000;

暂时记录一下吧,遇到的时候方便查一下。当然,这些实际上Android开发者官网源码里都能看到。文章来源地址https://www.toymoban.com/news/detail-602809.html

到了这里,关于Android 应用弹出悬浮窗的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • Android NestedScrollView悬浮固定顶部

    项目中有页面涉及到多个元素组 需要NestedScrollView包裹来上下滑动 接到需求 一些标题在滑动到顶部时需要置顶 我之前做过关于Android Behavior之ViewPager+Fragment+RecyclerView实现吸顶效果 大概就是这种效果 只不过这次是随意的组件 比如 TextView 或布局组件 RelativeLayout 等 废话不多说来

    2024年01月24日
    浏览(41)
  • 【Android入门到项目实战-- 11.1】—— 实现悬浮按钮

            悬浮按钮是悬浮于界面之上,滑动屏幕时按钮不会跟随屏幕移动,它是Design Support库中提供的一个控件,这个控件可以帮助我们轻松实现悬浮按钮效果。         下面实现一个发布的悬浮按钮。        由于需要用到floatingActionButton,所以先导入,可参考这篇文

    2024年02月13日
    浏览(41)
  • Android 点击悬浮窗后台启动Activity问题及方案

    背景:开启悬浮窗,当app进入后台后,点击悬浮窗进入固定页面 问题:当app在后台运行时,点击悬浮窗,以下代码不能拉起app,经排查,部门手机需要开启后台弹出界面权限 如图  不同的机型这个权限的名称也不相同,要开启此权限,要跳转的界面也不同,所以需要获取不同机型的此页面路

    2024年02月11日
    浏览(41)
  • 保护您的Android应用程序:Android应用程序安全一览

    我们都知道Android是为所有人设计的——开放、面向开发者、面向用户,这种开放性为今天和明天的移动技术提供了很多便利。然而,开放性也带来了需要妥善处理的安全风险。 安全是我们所有人都关注的重要问题。无论是我们的个人数据、电子邮件、电话号码、凭证、服务

    2024年02月03日
    浏览(69)
  • android 12后WindowManager事件穿透类型悬浮窗无效问题

    笔记: 项目需要将一个悬浮窗WindowManager仅显示view给用户看,不可操作,将触摸事件穿透到后面的窗口。WindowManager.LayoutParams代码如下 在android12以下的机型中测试都没问题,触摸事件可以穿透悬浮窗。但在android 12机型测试时,触摸事件无法穿透悬浮窗了。 查了android开发者官

    2024年02月13日
    浏览(49)
  • 【Android -- 开源库】推荐一个全局悬浮窗的框架(FloatWindow)

    在日常开发中,我们可能需要实现全局悬浮窗的需求: 点击悬浮窗图标可以跳转到一个固定的 Activity A; 用户在 app 内的任一 Activity 里都能看到悬浮窗(除了 Activity A) 悬浮窗可以关闭,可以拖动,拖动过程中松手可以自动吸附到屏幕边缘。 支持拖动,提供自动贴边等动画 内

    2024年02月15日
    浏览(46)
  • Android - 使用GSY实现视频播放和画中画悬浮窗

    0. 现完成功能: 悬浮窗区分横屏竖屏两种尺寸 悬浮窗可以在页面上随意拖动 在播放视频时按返回键/Home键/离开当前页时触发开启 悬浮窗显示在退到后台/在应用内/桌面 带播放进度开启悬浮窗,带播放进度回到应用内页面 权限:每次开启前判断有无权限,没权限并且请求过

    2023年04月11日
    浏览(34)
  • Android入门教程||Android 架构||Android 应用程序组件

    Android 操作系统是一个软件组件的栈,在架构图中它大致可以分为五个部分和四个主要层。 在所有层的最底下是 Linux - 包括大约115个补丁的 Linux 3.6。它提供了基本的系统功能,比如进程管理,内存管理,设备管理(如摄像头,键盘,显示器)。同时,内核处理所有 Linux 所擅

    2024年02月13日
    浏览(42)
  • 【Android笔记98】Android小案例之APP应用程序管理(获取已安装应用、卸载应用)

    这篇文章,主要介绍Android小案例之APP应用程序管理(获取已安装应用、卸载应用)。 目录 一、应用管理APP小案例 1.1、运行效果 1.2、使用技术 1.3、案例代码

    2024年02月02日
    浏览(50)
  • Android12(S)授权弹窗被悬浮窗遮挡导致无法点击问题分析

    在测试过程中发现,部分情况下当应用请求权限时,权限授予弹窗中的选项无法点击,有时候又可以。点击其他区域发现是可以正常响应,获取按键事件,发现触摸是有正常上报事件的,所以可以排除是触摸失灵导致。 既然是权限授予弹窗无法点击,那么我们就去找权限管理

    2024年02月11日
    浏览(36)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包