Android不依赖Activity的全局悬浮窗实现

Android免权限悬浮窗实现:FloatingX技术解析 悬浮窗技术是Android系统UI层的重要扩展能力,通过WindowManager API实现视图叠加显示。其核心原理是通过调整窗口类型参数(如TYPE_APPLICATION_OVERLAY)控制Z轴层级,在系统级SurfaceFlinger服务中进行合成渲染。这种技术显著提升了多任务操作效率,在电商客服悬浮按钮、游戏辅助工具等场景广泛应用。传统实现需要申请SYSTEM_ALERT_WINDOW权限,而FloatingX开源库创新性地采用TYPE_PHONE和TYPE_TOAST等窗口类型组合,配合动态降 阅读详情

Android悬浮窗实现 

实现基础

Android悬浮窗实现使用WindowManager ,WindowManager介绍  

通过Context.getSystemService(Context.WINDOW_SERVICE)可以获得 WindowManager对象。

每一个WindowManager对象都和一个特定的 Display绑定。
想要获取一个不同的display的WindowManager,可以用 createDisplayContext(Display)来获取那个display的 Context,之后再使用:Context.getSystemService(Context.WINDOW_SERVICE)来获取WindowManager。
使用WindowManager可以在其他应用最上层,甚至手机桌面最上层显示窗口。
调用的是WindowManager继承自基类的addView方法和removeView方法来显示和隐藏窗口。具体见后面的实例。
 另:API 17推出了Presentation,它将自动获取display的Context和WindowManager,可以方便地在另一个display上显示窗口。
 
WindowManager实现悬浮窗需要声明权限
  首先在manifest中添加如下权限:
<!-- 显示顶层浮窗 --><uses-permission android:name="android.permission.SYSTEM_ALERT_WINDOW" />
  
  注意:在MIUI上需要在设置中打开本应用的”显示悬浮窗”开关,并且重启应用,否则悬浮窗只能显示在本应用界面内,不能显示在手机桌面上。
 

服务获取和基本参数设置

       // 获取应用的Context
        mContext = context.getApplicationContext();
        // 获取WindowManager
        mWindowManager = (WindowManager) mContext
                .getSystemService(Context.WINDOW_SERVICE);
     //参数设置:
        final WindowManager.LayoutParams params = new WindowManager.LayoutParams();
        // 类型
        params.type = WindowManager.LayoutParams.TYPE_SYSTEM_ALERT;
        // WindowManager.LayoutParams.TYPE_SYSTEM_ALERT
        // 设置flag
        int flags = WindowManager.LayoutParams.FLAG_ALT_FOCUSABLE_IM;
        // | WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE;
        // 如果设置了WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE,弹出的View收不到Back键的事件
        params.flags = flags;
        // 不设置这个弹出框的透明遮罩显示为黑色
        params.format = PixelFormat.TRANSLUCENT;
        // FLAG_NOT_TOUCH_MODAL不阻塞事件传递到后面的窗口
        // 设置 FLAG_NOT_FOCUSABLE 悬浮窗口较小时,后面的应用图标由不可长按变为可长按
        // 不设置这个flag的话,home页的划屏会有问题
        params.width = LayoutParams.MATCH_PARENT;
        params.height = LayoutParams.MATCH_PARENT;
        params.gravity = Gravity.CENTER;
点击和按键事件
  除了View中的各个控件的点击事件之外,弹窗View的消失控制需要一些处理。
  点击弹窗外部可隐藏弹窗的效果,首先,悬浮窗是全屏的,只不过最外层的是透明或者半透明的:

具体实现

package com.robert.floatingwindow;
import android.content.Context;
import android.graphics.PixelFormat;
import android.graphics.Rect;
import android.view.Gravity;
import android.view.KeyEvent;
import android.view.LayoutInflater;
import android.view.MotionEvent;
import android.view.View;
import android.view.View.OnKeyListener;
import android.view.View.OnTouchListener;
import android.view.WindowManager;
import android.view.View.OnClickListener;
import android.view.WindowManager.LayoutParams;
import android.widget.Button;
/**
* 弹窗辅助类
*
* @ClassName WindowUtils
*
*
*/
public class WindowUtils {
    private static final String LOG_TAG = "WindowUtils";
    private static View mView = null;
    private static WindowManager mWindowManager = null;
    private static Context mContext = null;
    public static Boolean isShown = false;
    /**
     * 显示弹出框
     *
     * @param context
     * @param view
     */
    public static void showPopupWindow(final Context context) {
        if (isShown) {
            LogUtil.i(LOG_TAG, "return cause already shown");
            return;
        }
        isShown = true;
        LogUtil.i(LOG_TAG, "showPopupWindow");
        // 获取应用的Context
        mContext = context.getApplicationContext();
        // 获取WindowManager
        mWindowManager = (WindowManager) mContext
                .getSystemService(Context.WINDOW_SERVICE);
        mView = setUpView(context);
        final WindowManager.LayoutParams params = new WindowManager.LayoutParams();
        // 类型
        params.type = WindowManager.LayoutParams.TYPE_SYSTEM_ALERT;
        // WindowManager.LayoutParams.TYPE_SYSTEM_ALERT
        // 设置flag
        int flags = WindowManager.LayoutParams.FLAG_ALT_FOCUSABLE_IM;
        // | WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE;
        // 如果设置了WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE,弹出的View收不到Back键的事件
        params.flags = flags;
        // 不设置这个弹出框的透明遮罩显示为黑色
        params.format = PixelFormat.TRANSLUCENT;
        // FLAG_NOT_TOUCH_MODAL不阻塞事件传递到后面的窗口
        // 设置 FLAG_NOT_FOCUSABLE 悬浮窗口较小时,后面的应用图标由不可长按变为可长按
        // 不设置这个flag的话,home页的划屏会有问题
        params.width = LayoutParams.MATCH_PARENT;
        params.height = LayoutParams.MATCH_PARENT;
        params.gravity = Gravity.CENTER;
        mWindowManager.addView(mView, params);
        LogUtil.i(LOG_TAG, "add view");
    }
    /**
     * 隐藏弹出框
     */
    public static void hidePopupWindow() {
        LogUtil.i(LOG_TAG, "hide " + isShown + ", " + mView);
        if (isShown && null != mView) {
            LogUtil.i(LOG_TAG, "hidePopupWindow");
            mWindowManager.removeView(mView);
            isShown = false;
        }
    }
    private static View setUpView(final Context context) {
        LogUtil.i(LOG_TAG, "setUp view");
        View view = LayoutInflater.from(context).inflate(R.layout.popupwindow,
                null);
        Button positiveBtn = (Button) view.findViewById(R.id.positiveBtn);
        positiveBtn.setOnClickListener(new OnClickListener() {
            @Override
            public void onClick(View v) {
                LogUtil.i(LOG_TAG, "ok on click");
                // 打开安装包
                // 隐藏弹窗
                WindowUtils.hidePopupWindow();
            }
        });
        Button negativeBtn = (Button) view.findViewById(R.id.negativeBtn);
        negativeBtn.setOnClickListener(new OnClickListener() {
            @Override
            public void onClick(View v) {
                LogUtil.i(LOG_TAG, "cancel on click");
                WindowUtils.hidePopupWindow();
            }
        });
        // 点击窗口外部区域可消除
        // 这点的实现主要将悬浮窗设置为全屏大小,外层有个透明背景,中间一部分视为内容区域
        // 所以点击内容区域外部视为点击悬浮窗外部
        final View popupWindowView = view.findViewById(R.id.popup_window);// 非透明的内容区域
        view.setOnTouchListener(new OnTouchListener() {
            @Override
            public boolean onTouch(View v, MotionEvent event) {
                LogUtil.i(LOG_TAG, "onTouch");
                int x = (int) event.getX();
                int y = (int) event.getY();
                Rect rect = new Rect();
                popupWindowView.getGlobalVisibleRect(rect);
                if (!rect.contains(x, y)) {
                    WindowUtils.hidePopupWindow();
                }
                LogUtil.i(LOG_TAG, "onTouch : " + x + ", " + y + ", rect: "
                        + rect);
                return false;
            }
        });
        // 点击back键可消除
        view.setOnKeyListener(new OnKeyListener() {
            @Override
            public boolean onKey(View v, int keyCode, KeyEvent event) {
                switch (keyCode) {
                case KeyEvent.KEYCODE_BACK:
                    WindowUtils.hidePopupWindow();
                    return true;
                default:
                    return false;
                }
            }
        });
        return view;
    }
}


欢迎扫描二维码,关注公众账号



Android悬浮窗权限深度解析:从TYPE_APPLICATION_OVERLAY到SYSTEM_ALERT_WINDOW 在Android开发中,窗口管理系统通过WindowManager.LayoutParams的type属性定义不同层级的显示界面,其中系统级窗口如悬浮窗需要特殊权限。其核心原理在于Android权限模型的演进,特别是SYSTEM_ALERT_WINDOW权限从普通权限转变为危险权限后,应用必须动态请求用户授权。这一机制的技术价值在于平衡了功能实现与系统安全,防止恶意应用滥用悬浮窗干扰用户。常见的应用场景包括全局快捷操作、后台服务状态显示等需要覆盖在其他应用之上的界面。针对开发中常见的“permission 阅读详情

相关推荐

Android窗口容器机制解析:从悬浮窗被遮挡问题看WindowContainer层级管理

在Android系统开发中,窗口管理是一个核心且复杂的技术领域。其底层原理基于树形结构的容器化组织方式,通过WindowContainer这一抽象概念实现窗口的分组、排序和层级管理。这种设计模式的价值在于能够高效协调多个窗口的显示、焦点和动画,确保系统UI的稳定性和用户体验的一致性。在实际应用场景中,开发者常会遇到悬浮窗被系统弹窗遮挡、窗口层级错乱等问题,这往往源于对容器层级体系的理解不足。本文以Android T(Android 13)为例,深入剖析WindowContainer的树形结构与责任链机制,揭

weixin_30787531的博客 347

怎么实现android 全局悬浮窗

【代码】怎么实现android 全局悬浮窗。

yanwenyuan0304的专栏 2654

Android窗口参数全解析:从LayoutParams到悬浮窗实战

在Android应用开发中,窗口系统是构建用户界面的核心基础,它通过一系列精密的参数控制着视觉元素的层级、位置和行为。理解窗口参数的工作原理,关键在于掌握WindowManager.LayoutParams这一核心类,它定义了窗口的身份、交互特性和几何属性。从技术价值来看,精确控制窗口参数不仅能实现丰富的UI效果,更是解决悬浮窗、对话框等高级交互场景中常见问题的关键。例如,通过合理设置type参数(如TYPE_APPLICATION_OVERLAY)和flags组合(如FLAG_NOT_FOCUSABLE

weixin_29172963的博客 259

Android 非activity下弹出对话框AlertDialog,例如adapter类中

在adapter类中要弹出确认框,是需要设置系统级别的对话框,要给对话框添加属性为 WindowManager.LayoutParams.TYPE_SYSTEM_ALERT 需要在AndroidManifest.xml中添加权限 <uses-permissionandroid:name="android.permission.SYSTEM_ALERT_WINDOW"/> 下面是具体代码 AlertDialog alertDialog = new AlertDialog.Buil..

lnc2003的专栏 1242

实现Android全屏悬浮窗口

需要注意的是,从Android 6.0(API级别23)开始,悬浮窗口权限需要用户在应用设置中手动授权。因此,在应用中使用悬浮窗口功能时,你需要引导用户进行相应的权限授权操作。然后,我们设置了悬浮窗口的参数,包括窗口的宽度、高度、类型等。至此,我们已经完成了Android全屏悬浮窗口的实现。当你运行应用时,你将看到一个全屏的悬浮窗口显示在屏幕上。方法,我们启动了FloatingWindowService,从而实现了悬浮窗口的显示。在布局文件中,你可以添加自己所需的界面元素,例如按钮、文本框等。

持续更新 990

Android kotlin全局悬浮窗全屏功能和锁屏页面全屏悬浮窗功能一

在进行app应用开发中,在实现某些功能中要求实现悬浮窗功能,分为应用内悬浮窗 ,全局悬浮窗和 锁屏页面悬浮窗功能 等,接下来就来实现这些悬浮窗全屏功能,首选看下第一部分功能实现

安卓兼职framework和app工程师的博客 2013

Android 不依赖activity的全局悬浮窗实现

Android悬浮窗实现  实现基础 Android悬浮窗实现使用WindowManager ,WindowManager介绍   通过Context.getSystemService(Context.WINDOW_SERVICE)可以获得 WindowManager对象。 每一个WindowManager对象都和一个特定的 Display绑定。 想要获取一个不同的display

qq_28273051的博客 2万+

PerfectFloatWindow:android全局悬浮窗,目前已经适配华为,小米,vivo,oppo,一加,三星,魅族,索尼,LG,IQOO,努比亚,中兴,金立,360,锤子等目前是市面上所有机型兼容android4.1至android11版本,支持androidX

PerfectFloatWindow Android悬浮窗,绝对是目前相关悬浮窗开源库最完美的适配方案。目前已经适配华为,小米,vivo,oppo,一加,三星,魅族,索尼,LG,IQOO,努比亚,中兴,金立,360,锤子等目前是市面上主流机型包括非主流机型,兼容4.4以上包括android11版本。调用方便,配置少,后续会新增更多功功能,绝对满足你的定制化需求 特性 支持悬浮窗内容自定义 内部已处理权限校验,以及设置页面跳转 支持builder模式,方便动态配置 支持悬浮窗手势滑动 适配vivo,oppo等第三方权限管理器跳转 支持应用内以及应用外全局弹窗 权限开启弹窗支持用户自定义 1.初始化悬浮窗控件 //定义悬浮窗助手 floatHelper = FloatClient.Builder() .with(this)

Java安卓如何添加悬浮窗_不依赖于Activity的Android全局悬浮窗的实现

前言当我们在手机上使用360安全卫士时,手机屏幕上时刻都会出现一个小浮动窗口,点击该浮动窗口可跳转到安全卫士的操作界面,而且该浮动窗口不受其他activity的覆盖影响仍然可见(多米音乐也有相关的和主界面交互的悬浮小窗口)。那么这种不受Activity界面影响的悬浮窗口是怎么实现的呢?Android悬浮窗实现实现基础Android悬浮窗实现使用WindowManagerWindowManager介...

weixin_29159613的博客 781

保姆级教程:从WOS下载文献到Citespace出图,手把手搞定科研可视化(附避坑指南)

本文提供从WOS下载文献到Citespace出图的完整科研可视化指南,涵盖数据采集、清洗、环境配置和可视化优化全流程。特别分享WOS检索技巧、数据清洗方法和Citespace参数设置,帮助科研新手高效生成专业图谱,避开常见技术陷阱。

weixin_29311017的博客 171

DeepSeek与豆包无缝对接:5分钟搞定智能周报自动化(附完整代码)

本文详细介绍了如何利用DeepSeek与豆包API,快速搭建一个智能周报自动化系统。通过整合豆包平台的工作流数据,并调用DeepSeek大模型进行深度分析与内容生成,该系统能在5分钟内自动抓取、分析多源信息,并生成结构清晰、富有洞察力的团队周报,显著提升工作效率。

weixin_29029995的博客 491

Android实现顶层全局窗口,不依赖于Activity的Android全局悬浮窗的实现

前言当我们在手机上使用360安全卫士时,手机屏幕上时刻都会出现一个小浮动窗口,点击该浮动窗口可跳转到安全卫士的操作界面,而且该浮动窗口不受其他activity的覆盖影响仍然可见(多米音乐也有相关的和主界面交互的悬浮小窗口)。那么这种不受Activity界面影响的悬浮窗口是怎么实现的呢?Android悬浮窗实现实现基础Android悬浮窗实现使用WindowManagerWindowManager介...

weixin_30317869的博客 1970

GEO数据库数据下载方法总结

#GEO数据下载 GEO是生信分析经常用到的数据库。经常需要从中获取表达矩阵,平台信息,meta信息等,本博文总结了几种下载GEO数据的方法,各有优劣,实际应用过程中自行选择适合自己的。 ##方法一:直接从浏览器中下载 以数据集GSE1001为例, 可以直接点击“Series Matrix Files”获取该样本txt格式的表达谱数据,一般我们认为这种处理过的表达谱数据是没有问题的,当然,具体情况具体分析。 打开下载的文件可以看到许多“#”开头的行,这些是注释信息,一般关注这些注释信息中的“data pr

sakoko_的博客 4万+

android悬浮窗不被后台,不依赖于Activity的Android全局悬浮窗的实现

前言当我们在手机上使用360安全卫士时,手机屏幕上时刻都会出现一个小浮动窗口,点击该浮动窗口可跳转到安全卫士的操作界面,而且该浮动窗口不受其他activity的覆盖影响仍然可见(多米音乐也有相关的和主界面交互的悬浮小窗口)。那么这种不受Activity界面影响的悬浮窗口是怎么实现的呢?Android悬浮窗实现实现基础Android悬浮窗实现使用WindowManagerWindowManager介...

weixin_39912368的博客 1944

【Matlab 传感器布局优化】基于群智能算法的wsn覆盖优化研究

本文主要是对同构和异构传感器在指定空间内的布局进行优化,以最大覆盖率为目标,使用了DBO/SCA/WOA/SSA/NOA等启发式算法,在100x100的空间内,对30,100,200个传感器进行优化,得到最优的布局位置和对应覆盖率。

u013367499的博客 1818

ABtest描述统计功效

我们在面试数据分析时,常常会问到如何确定样本量的问题,会有一个指标:统计功效(power),或者是1-β 统计功效会影响实验的可信度,甚至会影响实验所需的样本量,要了解统计功效,首先要理解两类统计错误 假如我们做了一个AB实验,且两组用户的数据均值为μ1和μ2,我们会有两个初始假设: H0:两个实验组的数据没有差别(μ1=μ2),这个假设也叫“零假设”,也叫原假设 H1:两个实验组之间的数据存在差别(μ1≠μ2),这个假设也叫“非零假设”,也叫备择假设 定义两类错误: 实验本身没有效应,但我们觉

qq_38134556的博客 896

Android全屏悬浮窗画布,不依赖于Activity的Android全局悬浮窗的实现

前言当我们在手机上使用360安全卫士时,手机屏幕上时刻都会出现一个小浮动窗口,点击该浮动窗口可跳转到安全卫士的操作界面,而且该浮动窗口不受其他activity的覆盖影响仍然可见(多米音乐也有相关的和主界面交互的悬浮小窗口)。那么这种不受Activity界面影响的悬浮窗口是怎么实现的呢?Android悬浮窗实现实现基础Android悬浮窗实现使用WindowManagerWindowManager介...

weixin_39922374的博客 1290

通过miniconda conda安装jupyer的时候报错: InvalidArchiveError(“Error with archive

摘要:本文针对Windows系统使用Conda时出现的InvalidArchiveError错误(文件路径过长或压缩包损坏),提供了解决方案。建议以管理员身份运行PowerShell并执行命令启用长路径支持(LongPathsEnabled),然后重启电脑或终端。作者通过该方法成功解决了jupyter安装问题。附有错误截图和解决后的成功截图。

猿小白的博客 782

Android全局性弹框

不依赖具体activity弹出全局性弹窗 PopUpWindow使用详解(一)——基本使用(启舰启舰启舰啊哈哈哈哈) PopupWindow与Dialog的区别

Hogwarts 1923

Python 爬虫实战:在房天下抓取房产信息,分析房价走势

通过本次 Python 爬虫实战,我们成功地从房天下爬取了房产信息,并进行了存储、处理、分析和可视化展示。在这个过程中,我们不仅掌握了爬虫技术的基本应用,还学会了如何对动态加载的数据进行处理和分析。然而,本次爬虫任务也存在一些局限性,例如仅爬取了部分区域的房产数据,且未对房产的图片和视频内容进行分析。在未来的工作中,我们可以进一步优化爬虫程序,爬取更多区域的房产数据,并深入分析房产的多媒体内容、用户行为模式等,为购房者和房地产从业者提供更有价值的数据支持。

u014481728的博客 1366

基于BQ25895RTWR的锂电池充电管理硬件设计

BQ25895 是一款适用于单节锂离子电池和锂聚合物电池的高度集成型 5A 开关模式电池充电管理和系统电源路径管理器件。此类器件支持高输入电压快速充电。低阻抗电源路径对开关模式运行效率进行了优化、缩短了电池充电时间并延长了放电阶段的电池使用寿命。• 移动电源、移动 Wi-Fi 热点。• 便携式互联网器件。

corlin6688的博客 1085

android悬浮窗口的实现

转自:http://blog.csdn.net/stevenhu_223/article/details/8504058 当我们在手机上使用360安全卫士时,手机屏幕上时刻都会出现一个小浮动窗口,点击该浮动窗口可跳转到安全卫士的操作界面,而且该浮动窗口不受其他activity的覆盖影响仍然可见(多米音乐也有相关的和主界面交互的悬浮小窗口)。那么这种不受Activity界面影响的悬浮窗口是怎么

LiteHeaven的专栏 769

lwip-2.0.3

lwip是瑞典计算机科学院(SICS)的Adam Dunkels 开发的一个小型开源的TCP/IP协议栈。实现的重点是在保持TCP协议主要功能的基础上减少对RAM 的占用。

【Android面试】窗口机制专题

android窗口机制

studyForMokey的博客 490

华为的C语言编程规范.pdf

华为技术有限公司内部技术规范。本规范制定了编写C语言程序的基本原则、规则和建议。从代码的清晰、简洁、可测试、安全、程序效率、可移植各个方面对C语言编程作出了具体指导。

Data-Structures-and-Algorithm-Analysis-in-Java.pdf

作者: Weiss, Mark A. 出版社: Addison Wesley Data Structures and Algorithm Analysis in Java is an “advanced algorithms” book that fits between traditional CS2 and Algorithms Analysis courses. In the old ACM Curriculum Guidelines, this course was known as CS7. This text is for readers who want to learn good programming and algorithm analysis skills simultaneously so that they can develop such programs with the maximum amo...

在Service中使用FloatMenu:实现应用外全局悬浮菜单的完整步骤

FloatMenu是一个功能强大的Android悬浮窗菜单库,它允许开发者在应用内或应用外创建灵活的悬浮菜单。本指南将详细介绍如何在Service中集成FloatMenu,实现即使应用退出后仍能在全局显示的悬浮菜单功能,非常适合需要后台持续交互的应用场景。 ## 为什么选择在Service中使用FloatMenu? 在Service中集成FloatMenu具有以下优势: - **全局显示**:

gitblog_01073的博客 858

大中型超市收银系统(可直接运行)

光步前台收银系统系统功能:商品销售、商品退货、挂单、收银员权限、会员销售、单品取消、整单取消、商品查询、脱机销售、脱机数据上传,基本资料下载,开钱箱、小票打印、收款结算,支持多币种付款方式(现金、储值卡、礼券、微信等),支持多种促销。运行环境:.net 4.0登陆信息用户名:1001 密码:123456内置商品信息,商品编码可输入00001000 - 00010000,测试效果相关功能键F5 结算 F9挂单 F11商品查询 F8退货 Insert单品取消 Del整单取消 F12开钱箱F2 会员 Ctrl+Z退出系统 Home 锁屏 相关源码待公开

判断本应用是不是在前台

最近有个需求,在应用中增加一个全局的悬浮球,拟采用Toast方式实现,但Toast是系统级Alert。 应用后台运行时也会显示在桌面上,因此需要在每个Activity的生命周期中判断当前应用还在不在栈顶(用户可见、正在运行)。 先贴上实现代码吧,代码有项目依赖,如果有人需要的话拿去把依赖去掉就好了。 定义一个基类,所有Activity都需要继承这个基类。重写onResume( )实现

晨旭猿的小屋 663
上一篇: 算法系列(十一)BASE64算法实现和使用说明
下一篇: JAVA并发编程(二)内置锁和对象共享
robert_chao
博客等级 码龄15年 265粉丝 119原创
评论 2
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值