更新记录

1.0.0(2026-11-06) 下载此版本

首次发布 1.0.0:系统悬浮窗 UTS 插件,三端独立实现,平台按需启用。

  • Android:TYPE_APPLICATION_OVERLAY 系统浮窗,上层显示授权检查与设置页跳转,支持本地 / content:// / 网络图片、拖动、点击与延时回前台。
  • iOS 15+:AVSampleBufferDisplayLayer + AVPictureInPictureController 实现图片画中画,支持换图,由系统管理位置与尺寸。
  • HarmonyOS:window.TYPE_FLOAT 系统浮窗,受限权限查询与创建 / 移动 / 显示 / 隐藏 / 销毁。
  • 统一 configure、getStatus、checkPermission、requestPermission、show、hide、destroy、update、bringToFront 九个接口与 20001–20010 错误码;默认所有平台关闭,关闭平台会销毁原生浮窗并停止后续操作。
  • H5 与小程序明确返回 20002,不伪装成页面内浮层。
  • 附完整 uni-app Vue3 示例工程、插件文档与限制说明、44 项自动化测试、MuMu Android 12 实测报告与截图。

平台兼容性

UP FloatWindow

独立实现的 UTS 系统悬浮窗插件。Android 使用系统浮窗并可尝试延时回前台,iOS 15+ 使用系统画中画展示图片帧,鸿蒙使用系统浮窗。插件 ID 为 up-floatwindow,不依赖任何商业插件或第三方 SDK。

功能对标 DCloud 插件市场的「系统悬浮窗+安卓app自动跳前台」(插件 id 30542)公开功能说明:平台按需启用、授权检查、显示/隐藏/销毁、替换本地与网络图片、调整位置、延时返回应用、查看操作结果。本插件参考的是公开功能需求,未使用其源码、界面素材或品牌。

能力与平台

平台 悬浮显示方案 返回应用 位置 / 尺寸 实现与限制
Android 5.0+(API21) WindowManager + TYPE_APPLICATION_OVERLAY(API26 以下用 TYPE_PHONE) 点击浮窗、延时回前台;Android 10+ 后台启动是否允许由系统决定 支持,单位 px 需用户授予「显示在其他应用上层」;支持拖动;本地与网络图片
iOS 15+ AVSampleBufferDisplayLayer + AVPictureInPictureController 图片画中画 点击系统画中画的返回应用按钮;不支持后台强制跳前台 不支持,由系统管理,传参会返回 20002 需要项目开启后台音频与画中画能力并重新打包自定义基座
HarmonyOS NEXT API12+ window.WindowType.TYPE_FLOAT 系统浮窗 点击浮窗由业务页面调用 bringToFront,结果受系统限制 支持(moveWindowTo / resize,系统单位) ohos.permission.SYSTEM_FLOAT_WINDOW 为受限权限,需 AGC 申请与华为签发 Profile;浮窗内页面由接入方提供
H5 / Web 无 无 无 浏览器没有跨应用系统浮窗,文档画中画只支持 video;所有操作返回 20002
微信小程序及其他小程序 无 无 无 沙箱内无系统浮窗能力;所有操作返回 20002

不提供:应用内自定义浮层组件、视频/富文本浮窗、浮窗内按钮自定义、后台保活、通知栏常驻、任意时刻强制跳前台。

功能对照

对标能力 本插件 API
按需启用 Android / 鸿蒙 / iOS configure({ platforms })
检查授权、申请或查看授权 checkPermission() / requestPermission()
显示、隐藏、销毁 show() / hide() / destroy()
替换本地图片或网络图片 update({ src }) / show({ src })
调整悬浮窗位置 update({ x, y, width, height })(Android / 鸿蒙)
五秒后返回应用 bringToFront({ delay: 5000 })(Android / 鸿蒙)
查看操作结果与清空记录 由示例页的 success / fail 日志与清空按钮提供

安装

  1. 把 up-floatwindow 目录放入项目的 uni_modules。
  2. 使用 HBuilderX 4.61+,App 端制作自定义调试基座后运行到真机;仅更新页面不会让原生能力生效。
  3. 插件不引入任何三方依赖,Android / iOS / 鸿蒙的 config.json 只有系统框架与版本声明。
  4. 在业务代码中先调用 configure 启用目标平台,默认三个平台全部关闭。

Android

插件的 app-android/AndroidManifest.xml 已声明:

  • android.permission.SYSTEM_ALERT_WINDOW(API23+ 需用户在设置页手动开启)
  • android.permission.REORDER_TASKS(把任务切回前台)
  • android.permission.INTERNET(网络图片)

宿主项目的 manifest.json 也可以重复声明这些权限(示例工程已声明)。打开悬浮窗前请保证应用处于前台;从后台首次打开可能被系统拒绝。

iOS

app-ios/Info.plist 声明 UIBackgroundModes = [audio] 与相册用途说明。接入项目还需:

  • 在 manifest.json 的 app-plus.distribute.ios 中配置 "UIBackgroundModes": ["audio"]、"deploymentTarget": "15.0";
  • 开启音频后台与画中画能力,并使用包含相应能力的签名配置重新打包自定义基座。

修改后台能力后仅热更新页面无效。网络图片建议用 https,HTTP 会受 ATS 限制。

HarmonyOS

系统浮窗是受限权限,不能通过普通授权弹窗开通。接入步骤:

  1. 在华为 AppGallery Connect 为应用申请 ohos.permission.SYSTEM_FLOAT_WINDOW,说明使用场景,以华为审核结果为准。
  2. 获批后重新生成包含该权限授权的调试 Profile(.p7b),确认包名、证书、调试设备匹配,替换 HBuilderX 鸿蒙签名配置;正式发布同样需要带授权的发布签名。
  3. 在宿主 harmony-configs/entry/src/main/module.json5 声明权限(片段,按项目实际结构合并):
{
  "module": {
    "requestPermissions": [
      {
        "name": "ohos.permission.SYSTEM_FLOAT_WINDOW",
        "reason": "$string:float_window_reason",
        "usedScene": {
          "abilities": ["EntryAbility"],
          "when": "always"
        }
      }
    ]
  }
}

若安装时提示「运行所需的权限没有签名授权」,说明 Profile 未包含该权限;不要直接删除权限声明来消除报错,否则浮窗功能不可用。

  1. 浮窗内的 ArkUI 页面由接入方提供,把页面路径传给 configure({ harmonyContentPath: 'pages/FloatContent' }),并在 resources/base/profile/main_pages.json 注册该页面。插件把图片地址写入 AppStorage 的 upFloatWindowSrc,页面用 @StorageLink 读图;点击事件里调用 bringToFront({ delay: 0 }) 请求回到应用:
@Entry
@Component
struct FloatContent {
  @StorageLink('upFloatWindowSrc') src: string = ''
  build() {
    Column() {
      Image(this.src).width('100%').height('100%').objectFit(ImageFit.Cover)
    }
    .width('100%').height('100%')
    .onClick(() => {
      // 由业务调用 bringToFront({ delay: 0 }),后台启动结果受系统限制
    })
  }
}

未配置 harmonyContentPath 时插件仍会创建并显示系统浮窗,但窗口内容为空,show 的 detail 会提示这一点。这是刻意保留的最小切片:UTS 插件不伪装成能内置宿主 ArkUI 页面资源。

API

所有异步操作都是 options 回调风格,success / fail 只会触发一次,complete 一定执行(即使前一个回调抛错)。未启用平台时所有操作统一返回 20001,不会触碰系统 API。

import {
  configure, getStatus, checkPermission, requestPermission,
  show, hide, destroy, update, bringToFront
} from '@/uni_modules/up-floatwindow';

configure(options)

同步设置平台开关与默认参数。关闭某个平台会同时销毁该平台的原生浮窗并清空状态。

configure({
  platforms: { android: true, ios: true, harmony: false },
  src: '/storage/emulated/0/Pictures/a.png',
  width: 240,
  height: 240,
  x: 40,
  y: 120,
  bringToFrontOnClick: true,
  harmonyContentPath: 'pages/FloatContent'
});
字段 类型 默认值 说明
platforms { android?, ios?, harmony? } 全部 false 按需启用;只对当前运行平台的开关生效
src string 空 默认图片地址,show() 可覆盖
width / height number 240 64–1024 的整数,单位 px;iOS 仅用作图片帧尺寸
x / y number 0 -10000–10000 的整数;iOS 忽略
bringToFrontOnClick boolean true Android 点击浮窗时是否尝试回前台
harmonyContentPath string 空 鸿蒙浮窗内容页路径

非法字段被忽略而不是抛异常;show() 时才会对实际使用的参数做完整校验。

getStatus()

同步返回 { platform, enabled, permission, state, pipAvailable, errMsg }。state 为 none / hidden / shown;permission 为 granted / denied / unknown / unsupported。

checkPermission(options)

  • Android:Settings.canDrawOverlays,返回是否已授予上层显示权限。
  • iOS:AVPictureInPictureController.isPictureInPictureSupported(),返回设备与能力是否可用。
  • 鸿蒙:checkAccessTokenSync 查询受限权限是否已由签名授予。
  • Web / 小程序:20002。

success 参数为 { granted, status, detail, errMsg }。

requestPermission(options)

  • Android:跳转 ACTION_MANAGE_OVERLAY_PERMISSION 设置页;返回应用后必须重新调用 checkPermission,插件不会伪造授权结果。已授权时直接成功。
  • iOS:无运行时授权弹窗,成功并提示需在项目中开启后台音频与画中画能力。
  • 鸿蒙:已授权则成功,否则返回 20010 并提示走 AGC 受限权限流程。

show(options)

show({
  src: 'https://example.com/a.png',
  x: 40,
  y: 120,
  width: 240,
  height: 240,
  onClick: () => console.log('浮窗被点击'),
  success: res => console.log(res.operation, res.state, res.detail),
  fail: err => console.error(err.errCode, err.errMsg)
});
字段 类型 说明
src string 覆盖默认图片;本地绝对路径(可带 file://)、content:// 或 http(s) 地址
width / height number 64–1024 整数;iOS 传这些字段会返回 20002
x / y number -10000–10000 整数;iOS 传这些字段会返回 20002
bringToFrontOnClick boolean 覆盖 configure 的默认值
onClick () => void 浮窗被点击时触发;进程被系统回收后不保证

隐藏后再次 show 会复用已创建的浮窗:state 从 hidden 回到 shown。建议在应用前台调用,再切换到后台。图片解码在工作线程完成,主线程只做视图操作;加载失败返回 20006,系统拒绝添加视图返回 20010。

hide(options) / destroy(options)

hide 仅隐藏视图(Android 置为 GONE,iOS 停止 PiP,鸿蒙调用 hideWindow),可再次 show;destroy 释放视图、监听器与音频会话,之后必须重新 show。销毁一个未创建的浮窗在 Android / iOS 仍返回成功(幂等),鸿蒙对 update / hide 返回 20005。

update(options)

至少提供 src、width、height、x、y 中的一项,未提供或为 null 的字段保持不变。

  • Android:换图、调整尺寸与位置;拖动产生的新位置可被再次覆盖。
  • iOS:只允许 src;任何几何参数返回 20002。
  • 鸿蒙:换图写入 AppStorage(业务页面的 @StorageLink 自动刷新),尺寸与位置需成对提供。

bringToFront(options)

bringToFront({ delay: 5000, success: () => {}, fail: err => console.log(err.errCode) });

delay 为 0–60000 的整数,默认 5000。Android / 鸿蒙在延时结束后尝试用已有任务或 startAbility 回到前台;Android 10+ 与鸿蒙对后台启动有限制,失败返回 20009,是否允许由系统决定,业务不得假定必定成功或必定失败。MuMu Android 12 实测在持有可见系统浮窗时可以成功返回(code 0);部分厂商 ROM 会拒绝。iOS 固定返回 20002,只能由用户点击系统画中画的返回按钮。

错误码

错误对象包含 errSubject: 'up-floatwindow'、errCode、带操作名前缀的 errMsg。

错误码 说明
20001 平台未启用,需先 configure
20002 当前平台不支持此操作
20003 未获得悬浮窗授权或画中画不可用
20004 参数不正确
20005 悬浮窗尚未创建或已销毁
20006 图片加载失败
20007 悬浮窗初始化或显示失败
20008 系统版本或设备能力不支持
20009 返回应用被系统限制
20010 操作被系统或签名授权拒绝

图片与隐私

  • 本地图片:BitmapFactory.decodeFile / UIImage(contentsOfFile:);content:// 走 ContentResolver;file:// 前缀会被去掉。
  • 本地路径必须是应用可读的:Android 10+ 分区存储下,直接传 /sdcard/Pictures/xxx.png 这类公共目录路径应用无权读取,会返回 20006(MuMu 实测确认)。请用应用沙箱路径(如 _doc/ 转换后的绝对路径)或 content:// URI。
  • 网络图片:原生层直接下载并解码,超时 8 秒(Android);不经过任何服务端,不上传、不写系统相册。加载失败返回 20006。
  • App 静态资源路径(如 /static/logo.png)不是设备上的文件路径,需先保存为本地文件再传入。
  • 插件不采集数据、不含广告、不申请通讯录或位置权限。

生命周期与并发

  • 平台开关、默认参数与生命周期状态保存在各自平台目录的模块单例中,不跨进程共享。
  • 同一平台只维护一个浮窗实例;重复 show 会更新同一个视图,不会叠加。
  • 回调是一次性的,complete 在 success / fail 之后执行;调用者回调抛异常不会被吞掉或转换成插件错误。
  • 从设置页返回、应用切前后台、设备旋转后,请重新调用 checkPermission() 与 getStatus()。

验证与限制

仓库内的自动化测试验证的是公共契约、平台开关与各语言桥接行为;本机另用 HBuilderX 自带 kotlinc 编译了 Kotlin 桥、用 @dcloudio/uts 转译了 App-Android UTS 入口,均通过。这些都不能替代 Swift / ArkTS 编译、自定义基座制作与真机授权验收。CLI 的 H5/小程序编译只说明降级入口可构建,不代表 APK/IPA/HAP 已验证。完整结果与真机清单见 验收说明。

原生端没有保证的能力不会被写成「已支持」:后台强制跳前台、iOS 浮窗位置自定义、鸿蒙浮窗内置页面、Web/小程序系统浮窗均明确标注为不支持或需宿主配合。

技术与来源

  • Android:系统 WindowManager / Settings / BitmapFactory,无三方 SDK。
  • iOS:AVKit / AVFoundation / CoreMedia / CoreImage 系统框架。
  • 鸿蒙:@kit.ArkUI 的 window、@kit.AbilityKit 的权限与能力接口。
  • 插件代码沿用仓库 MIT 声明;未复制对标插件的源码或素材。

隐私、权限声明

1. 本插件需要申请的系统权限列表:

Android: SYSTEM_ALERT_WINDOW、REORDER_TASKS、INTERNET;iOS: 后台音频(audio)与画中画能力,选择相册图片时需要相册权限;鸿蒙: ohos.permission.SYSTEM_FLOAT_WINDOW 受限权限(需华为签发授权)

2. 本插件采集的数据、发送的服务器地址、以及数据用途说明:

插件不采集、不上传图片;网络图片由业务传入的 URL 直接下载,仅在本机解码显示

3. 本插件是否包含广告,如包含需详细说明广告表达方式、展示频率:

无

许可协议

MIT License

Copyright (c) 2026 ultra-ui

Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.

暂无用户评论。