更新记录
1.0.38(2026-09-16)
- 修复 Android 兼容运行环境中,全屏应用内悬浮窗收起键盘时,页面高度恢复较慢、短暂露出底层页面的问题。
- 升级后无需修改页面样式、安全区配置或调用代码;需要重新制作并安装 Android 自定义基座或正式安装包,仅更新页面资源不会生效。
1.0.37(2026-09-15)
- 修复 Android 兼容运行环境中,全屏应用内悬浮窗首次弹出键盘时,页面顶部可能短暂下移的问题。
- 修复通过 H5 文件选择控件拍照或选择图片后返回页面时,悬浮窗可能下沉、底部显示不完整的问题。
- 升级后无需修改文件选择控件、调用代码或页面安全区配置;需要重新制作并安装 Android 自定义基座或正式安装包,仅更新页面资源不会生效。iOS 与原生 Harmony HAP 无需因此重新打包。
1.0.36(2026-09-14)
- 修复 Android 兼容运行环境中,全屏及整屏尺寸应用内悬浮窗弹起键盘后顶部下移、收起后底部可能留出缺口的问题。
- 升级后无需调整
safeTop、页面样式或调用参数;需要重新制作并安装 Android 自定义基座或正式安装包,仅更新页面资源不会生效。iOS 与原生 Harmony HAP 无需因此重新打包。
平台兼容性
uni-app(4.84)
| Vue2 | Vue3 | Chrome | Safari | app-vue | app-nvue | Android | iOS | 鸿蒙 |
|---|---|---|---|---|---|---|---|---|
| √ | √ | × | × | √ | √ | √ | √ | √ |
| 微信小程序 | 支付宝小程序 | 抖音小程序 | 百度小程序 | 快手小程序 | 京东小程序 | 鸿蒙元服务 | QQ小程序 | 飞书小程序 | 小红书小程序 | 快应用-华为 | 快应用-联盟 |
|---|---|---|---|---|---|---|---|---|---|---|---|
| × | × | - | - | - | - | - | - | - | - | - | - |
uni-app x(4.84)
| Chrome | Safari | Android | iOS | 鸿蒙 | 微信小程序 |
|---|---|---|---|---|---|
| × | × | √ | √ | √ | × |
lizhao-float-window
lizhao-float-window 是面向 uni-app / uni-app x 的原生悬浮窗与视频画中画插件。它可以在 App 内显示悬浮按钮、网页或业务面板,也可以在 Android 上创建跨应用悬浮窗,并提供 H5 双向通信、拖拽定位、全屏切换、网页媒体和运行诊断能力。
如果只是第一次接入,建议先打开一个应用内小窗;确认基础能力正常后,再按本文顺序启用 Android 跨应用悬浮、H5 交互或系统画中画。
Android 支持应用内悬浮、跨应用悬浮和系统画中画;iOS、Harmony 支持应用内悬浮和系统画中画,但不支持跨应用悬浮。Web 和小程序不支持真实悬浮窗能力。
这个插件能解决什么问题
- 在 App 页面内显示悬浮球、客服入口、播放器或业务面板。
- 在 Android 离开 App 后继续显示工具窗、播放状态或快捷操作。
- 让悬浮 H5 页面与 App 双向传递订单、表单、客服和播放器事件。
- 让可信 H5 选择文件、拍照,或使用摄像头和麦克风。
- 将网络视频、本地视频切换到系统画中画。
- 支持拖拽、边缘吸附、位置记忆、大小切换和自适应全屏。
- 查询权限、窗口状态和诊断信息,定位无法打开、内容未就绪或消息发送失败等问题。
支持平台
| 平台 | 支持情况 | 主要能力 | 是否需要包含插件的原生包 |
|---|---|---|---|
| App Android | 支持 | 应用内悬浮、跨应用悬浮、系统画中画、H5 通信、文件选择、摄像头和麦克风。 | 需要 |
| App iOS | 部分支持 | 应用内悬浮、系统画中画、H5 通信、系统文件选择、摄像头和麦克风;不支持跨应用悬浮。 | 需要 |
| App Harmony | 部分支持 | 应用内悬浮、系统画中画、H5 通信、系统文件选择、本地及网络视频;不支持跨应用悬浮和网页摄像头/麦克风采集。 | 需要 |
| Web/H5 | 不支持 | 可查询能力并显示不支持提示,不创建悬浮窗。 | 不需要 |
| 微信小程序 | 不支持 | 可查询能力并显示不支持提示,不创建悬浮窗。 | 不需要 |
| 支付宝小程序 | 不支持 | 可查询能力并显示不支持提示,不创建悬浮窗。 | 不需要 |
同一套 App 业务代码可以先调用 getCapabilities(),再根据 inApp、overlay、pip、h5Bridge、webMediaCapture 等字段决定是否显示对应入口。
先选择接入方式
| 你的需求 | 推荐方式 | 是否需要 Android 系统悬浮权限 | 建议起点 |
|---|---|---|---|
| 页面内显示悬浮按钮或面板 | mode: 'inApp' |
否 | 先运行下方快速开始 |
| Android 离开 App 后仍显示 | mode: 'overlay' |
是 | 先检查权限,再打开跨应用悬浮窗 |
| 自动铺满应用可用区域 | sizePreset: 'fullscreen' |
inApp 不需要 |
先用应用内模式验证布局 |
| H5 与 App 交换业务消息 | H5 消息 API | 取决于悬浮模式 | 先使用插件提供的本地 H5 |
| H5 选择文件或拍照 | 标准文件输入 | 取决于悬浮模式 | 先查询 webFileChooser |
| H5 使用摄像头或麦克风 | 允许访问设备的 HTTPS 网站来源 + webMediaPermissions |
取决于悬浮模式 | 先确认页面地址和所需能力 |
| 视频进入系统小窗 | 画中画 API | 否 | 先查询 capabilities.pip |
| 排查打开、权限或内容问题 | 状态与诊断 API | 否 | 导出当前运行信息 |
下载与导入
- 在插件市场选择“使用 HBuilderX 导入插件”。
- 确认项目中存在完整的
uni_modules/lizhao-float-window目录,不要只复制内部源码目录或修改插件目录名。 - 只从插件根目录导入 API。
uni-app 导入
// 普通 uni-app 页面只从插件根目录导入。
import {
getCapabilities,
openFloatWindow,
closeFloatWindow
} from '@/uni_modules/lizhao-float-window'
uni-app x 导入
// <script setup lang="uts"> 中使用相同的根目录导入方式。
import {
getCapabilities,
openFloatWindow,
closeFloatWindow
} from '@/uni_modules/lizhao-float-window'
后续示例使用两端同名 API 和参数。首次接入,或更新说明明确包含原生能力变更时,需要重新制作并安装对应平台的自定义基座或正式安装包;纯文档和页面资源更新不需要重新制作。
快速开始:打开第一个应用内悬浮窗
应用内悬浮不需要 Android 系统悬浮窗权限,适合第一次验证插件是否已经正确导入。
import {
getCapabilities,
openFloatWindow,
closeFloatWindow
} from '@/uni_modules/lizhao-float-window'
// 第一步:先确认当前平台支持应用内悬浮。
getCapabilities({
success(capabilities) {
if (!capabilities.inApp) {
console.log('当前平台不支持应用内悬浮', capabilities.restrictedReason)
return
}
// 第二步:打开插件自带的本地页面,不受网络状态影响。
openFloatWindow({
mode: 'inApp',
content: {
type: 'localAsset',
value: 'uni_modules/lizhao-float-window/static/bridge-demo.html',
bridgeName: 'LizhaoFloatWindow'
},
sizePreset: 'small',
dragEnabled: true,
edgeSnap: true,
success(res) {
console.log('应用内悬浮窗打开成功', res)
},
fail(err) {
console.log('应用内悬浮窗打开失败', err)
}
})
},
fail(err) {
console.log('读取悬浮窗能力失败', err)
}
})
// 页面离开或业务结束时主动关闭。
// closeFloatWindow({})
看到小窗后,可以继续选择下面的业务模块。若只需要应用内悬浮按钮,到这里已经完成最小接入。
按业务模块使用
模块一:让 Android 悬浮窗显示在其他应用上方
适合客服入口、播放状态、快捷工具等离开 App 后仍需显示的场景。该模式只支持 Android,并且必须由使用者在系统设置中授予“显示在其他应用上层”权限。
import {
checkOverlayPermission,
openOverlayPermissionSettings,
openFloatWindow,
updateFloatWindow
} from '@/uni_modules/lizhao-float-window'
// 由“打开跨应用悬浮窗”按钮调用。
function openAndroidOverlay(): void {
checkOverlayPermission({
success(permission) {
if (!permission.granted) {
// 当前函数来自明确的按钮操作,可以引导使用者进入设置页。
if (permission.canOpenSettings) {
openOverlayPermissionSettings({})
}
return
}
openFloatWindow({
mode: 'overlay',
// 默认释放输入法焦点,避免影响其他 App 输入。
focusMode: 'passthrough',
content: {
type: 'url',
value: 'https://www.dcloud.io'
},
sizePreset: 'medium',
dragEnabled: true,
edgeSnap: true,
rememberPosition: true,
keepInScreen: true,
success(res) {
console.log('Android 跨应用悬浮窗打开成功', res)
},
fail(err) {
console.log('Android 跨应用悬浮窗打开失败', err)
}
})
}
})
}
// 在悬浮窗已经打开后,由“开始输入”按钮调用。
function enableFloatWindowInput(): void {
updateFloatWindow({ focusMode: 'interactive' })
}
// 输入结束后释放焦点,避免影响其他 App。
function releaseFloatWindowInput(): void {
updateFloatWindow({ focusMode: 'passthrough' })
}
从设置页返回 App 后,应再次调用 checkOverlayPermission(),确认 granted=true 再打开。overlay 默认使用 passthrough,适合不影响其他 App 的输入;悬浮页需要输入时再切换为 interactive。inApp 默认使用 interactive。
模块二:调整大小、全屏、位置和吸附方式
适合悬浮球、业务卡片、全屏看板,以及需要记住使用者拖拽位置的场景。
import {
setFloatWindowSizePreset,
setFloatWindowSize,
setFloatWindowPosition,
getFloatWindowPosition,
updateFloatWindow
} from '@/uni_modules/lizhao-float-window'
// 由“全屏”按钮调用,只完成一个目标。
function useFullscreen(): void {
setFloatWindowSizePreset({
preset: 'fullscreen',
success(res) {
console.log('已切换为自适应全屏', res)
}
})
}
// 由“自定义尺寸”按钮调用。
function useCustomCardSize(): void {
setFloatWindowSize({
size: { width: 300, height: 180 }
})
}
// 由“移动窗口”按钮调用;移动成功后再读取坐标。
function moveFloatWindow(): void {
setFloatWindowPosition({
position: { x: 20, y: 120 },
success() {
getFloatWindowPosition({
success(position) {
console.log('当前悬浮窗坐标', position)
}
})
}
})
}
// 由“记住位置”开关调用。
function enablePlacementPreferences(): void {
updateFloatWindow({
edgeSnap: true,
rememberPosition: true,
keepInScreen: true,
edgePadding: 16
})
}
fullscreen 会铺满当前应用的安全可用区域,并随横竖屏或窗口尺寸变化更新;它不会覆盖状态栏、刘海或系统导航区域,并且在全屏状态下不响应拖拽。自定义 width / height 只接受数字,Android 使用 px、iOS 使用 pt、Harmony 使用 vp。
Android 应用内模式下,自定义 size 的宽、高均覆盖当前完整窗口且 keepInScreen: true 时,窗口会从左上角对齐,键盘开合保持窗口位置稳定。自定义尺寸仍保留传入值;需要随横竖屏或窗口大小自动适配时,使用 fullscreen。
首次打开时如已有键盘且无法确定完整窗口尺寸,会保留普通自定义窗口的定位方式;收起键盘后重新设置 size 或重新打开悬浮窗,可重新计算对齐位置。
模块三:监听交互并动态切换内容
适合点击悬浮球打开业务页、记录拖拽坐标,或在远程页面与本地页面之间切换。
import {
onMove,
offMove,
onClick,
offClick,
setFloatWindowContent
} from '@/uni_modules/lizhao-float-window'
onMove({
listener(event) {
console.log('悬浮窗移动到', event.x, event.y)
}
})
onClick({
listener(event) {
console.log('悬浮窗被点击', event)
}
})
setFloatWindowContent({
content: {
type: 'url',
value: 'https://www.dcloud.io'
},
success(res) {
console.log('悬浮窗内容切换成功', res)
}
})
// 在页面卸载钩子中调用,不要在注册后立即执行。
function cleanupFloatWindowListeners(): void {
offMove({})
offClick({})
}
常用内容类型为远程网页 url 和应用资源 localAsset。localFile 不是通用网页路径,当前对外保证仅用于 Harmony 应用自己的视频文件。
模块四:让 H5 与 App 双向传递消息
适合订单提交、客服会话、播放器状态同步和表单操作。推荐先使用插件提供的本地 H5 验证通信顺序。
import {
onH5Message,
offH5Message,
openFloatWindow,
sendMessageToH5
} from '@/uni_modules/lizhao-float-window'
// 先订阅,再打开页面,避免漏掉 H5 初始化消息。
onH5Message({
listener(message) {
console.log('App 收到 H5 消息', message)
}
})
openFloatWindow({
mode: 'inApp',
content: {
type: 'localAsset',
value: 'uni_modules/lizhao-float-window/static/bridge-demo.html',
bridgeName: 'LizhaoFloatWindow'
},
success() {
sendMessageToH5({
event: 'appGreeting',
data: { text: '你好,H5' },
requestId: 'req-app-001',
success(result) {
console.log('消息已交给当前 H5 页面', result)
}
})
}
})
// 页面卸载时取消监听。
// offH5Message({})
H5 侧通过桥对象发送 JSON 字符串,并监听固定事件接收 App 消息:
window.LizhaoFloatWindow.postMessage(JSON.stringify({
event: 'submitOrder',
data: { orderNo: 'DEMO-001' },
requestId: 'req-h5-001'
}))
window.addEventListener('lizhaoFloatWindowMessage', function (event) {
console.log('H5 收到 App 消息', event.detail)
})
远程 H5 必须使用 HTTPS,并配置精确 Origin,例如 allowedOrigins: ['https://example.com']。Origin 只能包含协议、域名和可选端口,不能包含路径、查询、片段、通配符或 Token。单条序列化消息最大 256 KB;派发成功只表示消息已交给当前页面,不代表 H5 业务已经处理完成。
模块五:让 H5 选择文件、拍照或使用音视频设备
文件选择与拍照
H5 继续使用标准文件输入,不需要调用私有上传 API:
<!-- 相册单选或多图选择 -->
<input id="gallery" type="file" accept="image/*" multiple />
<!-- 优先请求系统拍照,具体入口由当前系统文件选择界面决定 -->
<input id="camera" type="file" accept="image/*" capture="environment" />
<script>
document.querySelector('#gallery').addEventListener('change', function (event) {
const files = Array.from(event.target.files || [])
console.log('本次选择图片数量', files.length)
})
</script>
Android 支持标准文件选择、拍照和多图返回;iOS、Harmony 保留系统默认文件选择界面。接入前可以读取 webFileChooser,不要把它和摄像头/麦克风实时采集能力混为一类。
摄像头和麦克风
Android、iOS 的可信 H5 可以按精确 HTTPS Origin 申请摄像头和麦克风。系统权限已经允许时,仍然需要在本次 content 中配置网页媒体白名单:
import { openFloatWindow } from '@/uni_modules/lizhao-float-window'
openFloatWindow({
mode: 'inApp',
content: {
type: 'url',
value: 'https://rtc.example.com/room',
allowedOrigins: ['https://rtc.example.com'],
webMediaPermissions: ['camera', 'microphone']
},
success(res) {
console.log('音视频 H5 已打开', res)
},
fail(err) {
console.log('音视频 H5 打开失败', err)
}
})
webMediaPermissions未配置或为空时,插件会拒绝全部网页媒体采集。- 只使用一种设备时,可以只配置
['camera']或['microphone']。 - 媒体采集不要求
bridgeName;只有页面还需要和 App 收发业务消息时才配置消息桥。 - 页面位于 iframe 内时,父页面还需要设置
allow="camera; microphone"。 - Harmony 当前
webMediaCapture=false,不要在该平台展示网页摄像头或麦克风入口。
Android H5 自动播放
Android 悬浮网页默认要求用户手势后再播放媒体。确有自动播放需求时,可以在打开页面前设置:
import { setMediaPlaybackRequiresUserGesture } from '@/uni_modules/lizhao-float-window'
setMediaPlaybackRequiresUserGesture({
required: false,
success(res) {
console.log('Android 媒体播放手势策略已设置', res)
},
fail(err) {
console.log('当前平台不支持该设置', err)
}
})
required 的安全默认值为 true。打开悬浮网页前设置时,返回的 appliedToCurrentWebView=false 表示配置已保存,将用于下一次创建;网页已经打开并成功应用时返回 true。该方法只支持 Android,其他平台返回 9015001。它不会自动重试之前已经失败的 play(),也不能替代摄像头和麦克风的 webMediaPermissions 配置。
模块六:让视频进入系统画中画
适合课程、直播和视频播放。调用前先确认 capabilities.pip=true,并把真实视频内容标记为 isVideoStream: true。
import {
getCapabilities,
enterPictureInPicture,
exitPictureInPicture
} from '@/uni_modules/lizhao-float-window'
getCapabilities({
success(capabilities) {
if (!capabilities.pip) {
console.log('当前设备不支持系统画中画')
return
}
enterPictureInPicture({
content: {
type: 'url',
value: 'https://qiniu-web-assets.dcloud.net.cn/unidoc/zh/wap2appvsnative.mp4',
isVideoStream: true
},
success(res) {
console.log('已进入系统画中画', res)
},
fail(err) {
console.log('进入系统画中画失败', err)
}
})
}
})
// 业务结束时退出画中画。
// exitPictureInPicture({})
Android 需要 Android 8.0 及以上,并且设备与当前 App 页面都允许画中画。iOS、Harmony 也以当前设备的 capabilities.pip 为准。普通网页、图片和业务卡片不能伪装成画中画成功,应继续使用应用内悬浮或 Android 跨应用悬浮。
模块七:在 Harmony 播放本地或鉴权视频
Harmony 除统一进入/退出能力外,还支持应用资源视频、应用自己目录中的 MP4、带请求头的网络视频、Home 自动进入和播放控制。
本地与鉴权视频
import { enterPictureInPicture } from '@/uni_modules/lizhao-float-window'
// 播放随应用发布的视频。
enterPictureInPicture({
content: {
type: 'localAsset',
value: 'uni_modules/lizhao-float-window/static/pip-test.mp4',
isVideoStream: true
}
})
// 播放需要临时请求凭据的网络视频。
enterPictureInPicture({
content: {
type: 'url',
value: 'https://example.com/protected.mp4',
headers: {
Authorization: 'Bearer <由业务安全获取的临时凭据>'
},
isVideoStream: true
}
})
下载后的视频可以使用 localFile,但当前对外保证仅接受 Harmony 当前应用自己 files/cache/temp 目录内的普通 MP4;不支持任意系统绝对路径、目录、符号链接或跨应用文件。不要把长期 Token、密钥或生产凭据写入页面、README 或代码仓库。
Home 自动进入与播放控制
import {
preparePictureInPicture,
cancelPictureInPicturePreparation,
playPictureInPicture,
pausePictureInPicture,
seekPictureInPicture,
getPictureInPicturePlaybackState
} from '@/uni_modules/lizhao-float-window'
// 先准备媒体;使用者按 Home 后由系统自动进入画中画。
preparePictureInPicture({
content: {
type: 'localAsset',
value: 'uni_modules/lizhao-float-window/static/pip-test.mp4',
isVideoStream: true
},
startPositionMs: 1000,
loop: true,
progressIntervalMs: 500,
autoEnterOnHome: true,
success(state) {
console.log('画中画已准备', state)
}
})
playPictureInPicture({ success: state => console.log('播放状态', state) })
pausePictureInPicture({ success: state => console.log('暂停状态', state) })
seekPictureInPicture({
positionMs: 10000,
success: state => console.log('跳转后状态', state)
})
getPictureInPicturePlaybackState({
success: state => console.log('当前画中画状态', state)
})
// 页面离开且尚未进入画中画时,可以取消准备态。
// cancelPictureInPicturePreparation({})
直播流不支持跳转,返回状态中的 seekable=false。Home 自动进入、播放、暂停、跳转和统一状态查询当前只支持 Harmony;其他平台会返回明确不支持。
模块八:查询状态并收集诊断信息
适合判断窗口是否已经打开、当前是否可见,或排查权限、内容加载、网页媒体和消息通信问题。
import {
getCapabilities,
getFloatWindowState,
getFloatWindowDiagnostics
} from '@/uni_modules/lizhao-float-window'
getCapabilities({
success(res) {
console.log('当前平台能力', res)
}
})
getFloatWindowState({
success(res) {
console.log('当前悬浮窗状态', res)
}
})
getFloatWindowDiagnostics({
success(res) {
console.log('当前运行诊断', res)
}
})
诊断结果可能包含当前窗口、页面 Origin、权限和最近错误摘要。提供给技术支持前,请先确认其中没有业务不希望对外提供的信息。
完整示例
- uni-app 完整示例
- uni-app x 完整示例
- 插件目录
static/bridge-demo.html:H5 与 App 双向通信示例。 - 插件目录
static/pip-test.mp4:本地视频画中画示例。
完整示例覆盖应用内与 Android 跨应用悬浮、大小和位置、拖拽、内容切换、H5 通信、网页媒体、系统画中画、播放控制和诊断。业务页面仍应只从插件根目录导入 API。
常用 API 与配置
API 用途总览
| 模块 | 常用 API | 用途 |
|---|---|---|
| 能力判断 | getCapabilities |
接入前读取当前平台的悬浮、PiP、H5 桥、媒体采集和文件选择能力。 |
| 悬浮窗生命周期 | openFloatWindow、updateFloatWindow、closeFloatWindow |
打开、动态更新和关闭悬浮窗。 |
| 显示与层级 | showFloatWindow、hideFloatWindow、bringFloatWindowToFront |
控制显隐和应用内层级。 |
| 位置与尺寸 | setFloatWindowPosition、getFloatWindowPosition、setFloatWindowSize、setFloatWindowSizePreset |
调整坐标、自定义尺寸或切换尺寸预设。 |
| 拖拽 | setFloatWindowDragEnabled、onMove、offMove |
控制拖拽并监听坐标。 |
| 内容切换 | setFloatWindowContent |
在远程 URL、本地 HTML 和受支持的本地媒体之间切换。 |
| Android 播放策略 | setMediaPlaybackRequiresUserGesture |
控制 Android 悬浮网页是否必须由用户手势触发媒体播放。 |
| H5 双向通信 | onH5Message、sendMessageToH5、offH5Message |
H5 与 App 交换结构化业务事件。 |
| 内容事件 | onContentEvent、offContentEvent |
监听页面加载和系统画中画内容事件。 |
| 系统画中画 | enterPictureInPicture、exitPictureInPicture |
在当前设备支持时进入或退出系统画中画。 |
| Harmony 画中画控制 | preparePictureInPicture、cancelPictureInPicturePreparation、playPictureInPicture、pausePictureInPicture、seekPictureInPicture、getPictureInPicturePlaybackState |
预准备、Home 自动进入、播放控制和状态查询。 |
| 权限与诊断 | checkOverlayPermission、openOverlayPermissionSettings、getFloatWindowState、getFloatWindowDiagnostics |
检查 Android 跨应用悬浮权限并获取运行状态或诊断信息。 |
| 点击事件 | onClick、offClick |
监听或取消悬浮窗点击事件。 |
为兼容已经接入的项目,插件仍保留 open / setConfig / close / show / hide / toFront / setPosition / getPosition / setSize / setDragEnable / setShowPattern / setContent 等别名。新项目建议使用上表中的完整 API 名称。
通用回调
| 参数 | 类型 | 必填 | 说明 | 默认值 | 可选参数 |
|---|---|---|---|---|---|
success |
function | 否 | 当前 API 按平台规则确认成功时触发。 | 无 | 无 |
fail |
function | 否 | 参数、权限、平台能力或系统操作失败时触发。 | 无 | 无 |
complete |
function | 否 | 调用结束后触发,成功或失败都会执行。 | 无 | 无 |
打开与更新参数
openFloatWindow(options) 使用完整参数;updateFloatWindow(options) 使用同名可选字段动态更新已经打开的窗口。
| 参数 | 类型 | 必填 | 说明 | 默认值 | 可选参数 |
|---|---|---|---|---|---|
options |
OpenFloatWindowOptions | 是 | 打开悬浮窗的参数对象。 | 无 | 下列字段 |
options.mode |
FloatWindowMode | 否 | 悬浮模式;业务进入画中画建议使用专用画中画 API。 | Android 为 overlay,iOS/Harmony 为 inApp |
inApp / overlay / pip |
options.focusMode |
FloatWindowFocusMode | 否 | Android 焦点模式;overlay 默认释放输入法焦点。 |
按模式选择 | passthrough / interactive |
options.content |
FloatWindowContent | 是 | 页面或媒体内容。 | 无 | 见下表 |
options.position |
FloatWindowPosition | 否 | 初始坐标。 | 平台默认位置 | { x, y } |
options.size |
FloatWindowSize | 否 | custom 预设使用的自定义尺寸。 |
平台默认尺寸 | { width, height } |
options.sizePreset |
FloatWindowSizePreset | 否 | 尺寸预设。 | medium |
small / medium / large / custom / fullscreen |
options.dragEnabled |
boolean | 否 | 是否允许拖拽。 | true |
true / false |
options.edgeSnap |
boolean | 否 | 拖拽结束后是否吸附边缘。 | false |
true / false |
options.rememberPosition |
boolean | 否 | 是否记忆本次运行期间的最后坐标。 | false |
true / false |
options.keepInScreen |
boolean | 否 | 是否修正到当前可见区域。 | true |
true / false |
options.edgePadding |
number | 否 | 吸附和可见区域修正边距。 | 12 |
大于等于 0 |
options.visible |
boolean | 否 | 打开后是否立即显示。 | true |
true / false |
options.success |
function | 否 | 窗口真实打开后触发。 | 无 | 无 |
options.fail |
function | 否 | 打开失败时触发。 | 无 | 无 |
options.complete |
function | 否 | 调用结束后触发。 | 无 | 无 |
内容参数 FloatWindowContent
| 参数 | 类型 | 必填 | 说明 | 默认值 | 可选参数 |
|---|---|---|---|---|---|
type |
FloatWindowContentType | 是 | 内容来源。 | 无 | url / localAsset / localFile |
value |
string | 是 | HTTP(S) URL、应用资源路径或受支持的应用文件路径;启用远程消息桥或媒体采集时必须使用 HTTPS。 | 无 | 无 |
headers |
object / UTSJSONObject | 否 | 受支持网络媒体的请求头,字段值必须为字符串。 | 无 | 无 |
isVideoStream |
boolean | 否 | 是否为视频流;画中画内容必须为 true。 |
false |
true / false |
bridgeName |
string | 否 | 启用 H5 双向通信的合法 JavaScript 标识符。 | 无 | 最长 64 字符 |
allowedOrigins |
string[] | 否 | 远程 H5 的精确 HTTPS Origin 白名单。 | 无 | 例如 https://example.com |
webMediaPermissions |
FloatWindowWebMediaPermission[] | 否 | Android/iOS 可信 H5 可请求的媒体能力;空数组拒绝全部采集。 | [] |
camera / microphone |
userAgentSuffix |
string | 否 | 可选的网页 User-Agent 后缀。 | 无 | 无 |
uni-app 可为 headers 传普通对象,uni-app x 使用 UTSJSONObject。localFile 当前对外保证仅用于 Harmony 画中画,并且只接受当前应用自己 files/cache/temp 目录内的普通 MP4。webFileChooser 与 webMediaCapture 是两种不同能力:前者对应标准文件输入,后者对应摄像头和麦克风实时采集。
位置与尺寸
| 参数 | 类型 | 必填 | 说明 | 默认值 | 可选参数 |
|---|---|---|---|---|---|
position.x |
number | 是 | 水平方向坐标。 | 无 | 无 |
position.y |
number | 是 | 垂直方向坐标。 | 无 | 无 |
size.width |
number | 是 | 自定义宽度。 | 无 | Android 为 px、iOS 为 pt、Harmony 为 vp |
size.height |
number | 是 | 自定义高度。 | 无 | Android 为 px、iOS 为 pt、Harmony 为 vp |
preset |
FloatWindowSizePreset | 是 | 切换预设尺寸。 | 无 | small / medium / large / custom / fullscreen |
画中画参数
| 参数 | 类型 | 必填 | 说明 | 默认值 | 可选参数 |
|---|---|---|---|---|---|
enterPictureInPicture.content |
FloatWindowContent | 否 | 视频来源,isVideoStream 必须为 true;未传时复用当前视频内容,没有可复用内容则失败。 |
当前视频内容 | url / localAsset / localFile |
preparePictureInPicture.content |
FloatWindowContent | 是 | Harmony 预准备的视频来源,isVideoStream 必须为 true。 |
无 | url / localAsset / localFile |
startPositionMs |
number | 否 | 点播起播位置。 | 0 |
大于等于 0 |
loop |
boolean | 否 | 是否循环点播媒体;直播流不适用。 | false |
true / false |
progressIntervalMs |
number | 否 | 点播进度事件间隔。 | 1000 |
250-5000 毫秒 |
autoEnterOnHome |
boolean | 否 | Harmony 预准备后,按 Home 是否自动进入系统画中画。 | true |
true / false |
positionMs |
number | Harmony 跳转时是 | 点播跳转目标位置。 | 无 | 大于等于 0 |
H5 消息参数
| 参数 | 类型 | 必填 | 说明 | 默认值 | 可选参数 |
|---|---|---|---|---|---|
event |
string | 是 | 非空业务事件名。 | 无 | 无 |
data |
any | 否 | 可序列化的业务数据。 | null |
无 |
requestId |
string | 否 | 用于关联一组业务请求和响应;插件不会自动等待或解析响应。 | 无 | 无 |
listener |
function | 订阅时是 | H5 发往 App 的持续消息监听器。 | 无 | 无 |
主要返回值
SetMediaPlaybackRequiresUserGestureResult
| 字段 | 类型 | 说明 |
|---|---|---|
required |
boolean | 当前保存的 Android 媒体播放手势要求;默认 true。 |
appliedToCurrentWebView |
boolean | 是否已经应用到当前打开的悬浮网页;false 表示已保存供下一次打开使用。 |
FloatWindowCapabilities
| 字段 | 类型 | 说明 |
|---|---|---|
supported |
boolean | 当前平台是否支持插件的真实原生能力。 |
platform |
string | 当前平台名称。 |
inApp |
boolean | 是否支持应用内悬浮。 |
overlay |
boolean | 是否支持跨应用悬浮。 |
pip |
boolean | 是否支持系统画中画。 |
draggable |
boolean | 是否支持拖拽。 |
resizable |
boolean | 是否支持运行时调整尺寸。 |
edgeSnap |
boolean | 是否支持边缘吸附。 |
positionMemory |
boolean | 是否支持位置记忆。 |
safeAreaCorrection |
boolean | 是否支持安全区域修正。 |
keyboardAvoidance |
boolean | 浮窗输入框是否会随系统键盘避让并在隐藏后恢复。 |
webContent |
boolean | 是否支持网页内容。 |
localAssetContent |
boolean | 是否支持应用资源内容。 |
h5Bridge |
boolean | 是否支持 H5 与 App 双向通信。 |
bridgeOriginAllowlist |
boolean | 是否支持按 HTTPS Origin 限制远程消息桥。 |
webMediaCapture |
boolean | 是否支持可信 H5 摄像头和麦克风采集。 |
webFileChooser |
boolean | 是否支持标准文件输入。 |
requiresOverlayPermission |
boolean | 当前平台使用跨应用 overlay 能力时是否需要系统悬浮权限。 |
requiresCustomBase |
boolean | 是否需要包含插件的自定义基座或原生包。 |
restrictedReason |
string(可选) | 当前平台受限原因。 |
FloatWindowState
| 字段 | 类型 | 说明 |
|---|---|---|
opened |
boolean | 悬浮窗是否已经打开。 |
visible |
boolean | 悬浮窗当前是否可见。 |
mode |
FloatWindowMode | 当前模式。 |
focusMode |
FloatWindowFocusMode(可选) | Android 当前焦点模式。 |
dragEnabled |
boolean | 是否允许拖拽。 |
edgeSnap |
boolean | 是否开启边缘吸附。 |
rememberPosition |
boolean | 是否开启位置记忆。 |
keepInScreen |
boolean | 是否保持在可见区域。 |
edgePadding |
number | 当前边缘留白。 |
position |
FloatWindowPosition | 当前坐标。 |
size |
FloatWindowSize | 当前尺寸。 |
sizePreset |
FloatWindowSizePreset | 当前尺寸预设。 |
content |
FloatWindowContent | null | 当前内容;未打开时可为空。 |
OverlayPermissionResult
| 字段 | 类型 | 说明 |
|---|---|---|
platform |
string | 当前平台。 |
granted |
boolean | 是否已经获得 Android 跨应用悬浮权限。 |
requiresOverlayPermission |
boolean | 当前平台是否需要该权限。 |
canOpenSettings |
boolean | 是否可以打开系统设置页。 |
settingsUri |
string(可选) | Android 可用的设置页地址。 |
packageName |
string(可选) | Android 应用包名。 |
restrictedReason |
string(可选) | 平台限制说明。 |
FloatWindowDiagnosticsResult
| 字段 | 类型 | 说明 |
|---|---|---|
platform |
string | 当前平台。 |
state |
FloatWindowState | 当前悬浮窗运行态。 |
overlayPermission |
OverlayPermissionResult | Android 跨应用悬浮权限快照。 |
webViewReady |
boolean | 网页容器是否已经就绪。 |
windowAttached |
boolean | 原生窗口是否已经附着。 |
layoutReady |
boolean | 布局是否已经可用。 |
listenerStatus |
FloatWindowListenerStatus | 拖拽、点击和内容监听器注册状态。 |
bridgeEnabled |
boolean | 当前内容是否启用了消息桥。 |
bridgeReady |
boolean | 当前消息桥是否可以收发消息。 |
bridgeName |
string | null | 当前桥对象名称。 |
currentOrigin |
string | null | 当前页面 Origin。 |
allowedOrigins |
string[] | 当前生效的远程 HTTPS Origin 白名单。 |
webMediaPermissions |
string[] | 当前允许的网页媒体能力。 |
mediaPermissionPending |
boolean | 当前是否存在待处理的网页媒体权限请求。 |
cameraPermissionGranted |
boolean | App 是否获得摄像头系统权限。 |
microphonePermissionGranted |
boolean | App 是否获得麦克风系统权限。 |
lastMediaError |
string | null | 最近媒体错误摘要。 |
lastBridgeError |
string | null | 最近桥接错误摘要。 |
requiresCustomBase |
boolean | 是否需要包含插件的自定义基座或原生包。 |
sdkInt |
number(可选) | Android 系统 API 级别。 |
restrictedReason |
string(可选) | 平台限制说明。 |
PictureInPicturePlaybackState
| 字段 | 类型 | 说明 |
|---|---|---|
prepared |
boolean | 媒体和系统画中画是否已经准备。 |
active |
boolean | 系统画中画窗口是否活动。 |
autoEnterOnHome |
boolean | 是否允许按 Home 自动进入。 |
playerState |
string | 当前播放器状态。 |
sourceType |
FloatWindowContentType | null | 当前媒体来源类型。 |
isLive |
boolean | 当前媒体是否为直播流。 |
playing |
boolean | 当前媒体是否正在播放。 |
seekable |
boolean | 当前媒体是否允许跳转。 |
positionMs |
number | 当前播放位置,单位毫秒。 |
durationMs |
number | 当前媒体时长,直播或未知时为 0。 |
loop |
boolean | 是否循环点播媒体。 |
progressIntervalMs |
number | 进度事件间隔,单位毫秒。 |
H5 消息返回值
| 字段 | 类型 | 说明 |
|---|---|---|
delivered |
boolean | App 消息是否已经交给当前 H5 页面。 |
bytes |
number | 序列化后消息的 UTF-8 字节数。 |
targetOrigin |
string | null | 本次派发的目标 Origin。 |
event |
string | H5 发往 App 的业务事件名。 |
data |
any | H5 发往 App 的业务数据。 |
requestId |
string | null | 请求关联标识。 |
sourceOrigin |
string | null | 消息来源 Origin。 |
isMainFrame |
boolean | null | 是否来自主页面。 |
timestamp |
number | App 接收消息的毫秒时间戳。 |
事件
悬浮窗事件
| 监听 API | 返回内容 | 取消监听 |
|---|---|---|
onMove |
拖拽后的 x / y / timestamp。 |
offMove |
onClick |
点击位置和时间。 | offClick |
onContentEvent |
页面加载或系统画中画内容事件。 | offContentEvent |
onH5Message |
H5 发往 App 的结构化业务消息。 | offH5Message |
页面卸载时应调用对应的 off... API,避免重复订阅。
Harmony 页面事件
| 事件名 | 说明 |
|---|---|
controllerAttached |
网页控制器已经和悬浮内容关联。 |
pageBegin |
主页面开始加载。 |
pageEnd |
主页面加载完成。 |
pageError |
主页面加载失败。 |
Harmony 系统画中画事件
| 事件名 | 说明 |
|---|---|
pipPreparing |
正在准备视频和系统画中画。 |
pipPrepared |
已准备,可等待 Home 自动进入或继续控制。 |
pipStarted |
系统画中画已进入。 |
pipPlaying |
视频正在播放。 |
pipPaused |
视频已暂停。 |
pipProgress |
返回点播进度快照。 |
pipSeeked |
点播媒体已完成跳转。 |
pipRestored |
已从系统画中画恢复到主应用。 |
pipStopped |
系统画中画已关闭。 |
pipError |
系统画中画准备、播放或控制失败。 |
错误码
| 错误码 | 含义 | 常见场景 |
|---|---|---|
9015001 |
当前平台或能力不支持。 | Web、小程序调用原生能力,或调用平台专属 API。 |
9015002 |
参数或内容不合法。 | 参数为空,URL、路径或请求头格式错误。 |
9015003 |
Android 跨应用悬浮权限未授予。 | 打开 overlay 前没有完成系统授权。 |
9015004 |
悬浮窗尚未打开。 | 在打开前调用更新、显隐、位置等 API。 |
9015005 |
当前操作状态冲突。 | 重复打开、画中画正在处理,或当前状态不允许取消、播放、暂停、跳转。 |
9015006 |
当前平台不允许请求的模式。 | iOS、Harmony 请求 Android 跨应用悬浮。 |
9015007 |
媒体来源、格式或当前媒体控制不支持。 | 画中画内容无效、直播流跳转、媒体不可播放。 |
9015008 |
原生系统操作失败。 | 窗口、播放器或系统画中画调用失败。 |
9015009 |
当前操作忙。 | 画中画正在处理其他操作。 |
9015010 |
当前内容容器或消息桥不可用。 | 网页容器尚未创建或已经释放。 |
9015011 |
可信 Web 配置不合法。 | 桥名、Origin 或 webMediaPermissions 非法。 |
9015012 |
当前页面未获得桥接授权。 | 没有启用桥,或页面不在获批范围。 |
9015013 |
H5 消息桥尚未就绪。 | 页面未加载完成或已经离开可信 Origin。 |
9015014 |
H5 消息格式无效。 | event 为空或数据无法序列化。 |
9015015 |
H5 消息过大。 | UTF-8 序列化后超过 256 KB。 |
9015016 |
App 向 H5 派发失败。 | 原生派发过程失败。 |
常见问题
第一次接入应该先测试什么
先调用 getCapabilities(),再用 inApp + localAsset + small 打开最小悬浮窗。该流程不需要 Android 跨应用悬浮权限,最适合检查插件是否已经正确导入,以及当前安装包是否包含插件能力。
Android 全局悬浮窗为什么打不开或返回 9015003
先调用 checkOverlayPermission()。未授权时,让使用者点击按钮进入系统设置页;返回 App 后重新检查,只有 granted=true 才打开 overlay。插件不会静默开启系统权限。
iOS 或 Harmony 能否在离开 App 后继续显示普通悬浮窗
不能。两者支持应用内悬浮和系统允许的视频画中画,不支持 Android 式跨应用普通悬浮窗。请根据 capabilities.overlay 和 capabilities.pip 决定是否展示入口。
Android 悬浮页能点击,但输入框为什么不弹键盘
overlay 默认使用 passthrough,用于避免影响其他 App 的输入。悬浮页需要输入时调用 updateFloatWindow({ focusMode: 'interactive' });输入完成后可切回 passthrough。inApp 默认允许输入。插件支持键盘自动避让,底部输入框获得焦点后会平稳移动到键盘上方,键盘关闭后恢复原有页面大小;可通过 keyboardAvoidance 判断当前平台是否支持。
fullscreen 为什么没有覆盖状态栏、刘海或系统导航区域
fullscreen 的含义是铺满当前应用的安全可用区域,并随窗口尺寸变化更新,不是覆盖系统界面的物理屏幕全屏。全屏状态下位置固定,也不响应拖拽。
系统已经允许摄像头和麦克风,H5 为什么仍无法获取设备
系统权限只是其中一层。当前 content 还必须配置最终页面的精确 HTTPS allowedOrigins,并在 webMediaPermissions 中列出页面实际请求的 camera、microphone。空配置按安全默认值拒绝全部媒体采集;iframe 还需要相应的 allow 属性。
H5 与 App 消息为什么返回 9015012、9015013 或 9015015
9015012:当前页面没有启用桥,或页面已离开允许的 Origin。9015013:页面还没有加载完成,消息桥尚未就绪。9015015:消息序列化后超过 256 KB。
同时检查 bridgeName 是否为合法标识符、远程页面是否使用精确 HTTPS Origin、event 是否为非空字符串。
Android H5 自动播放为什么仍被阻止
先在打开悬浮网页前调用 setMediaPlaybackRequiresUserGesture({ required: false })。如果之前的 play() 已经被浏览器拒绝,设置成功后仍要由 H5 重新发起播放。该设置只支持 Android,也不负责摄像头或麦克风授权。
网页或视频为什么无法进入系统画中画
画中画只用于真实视频。先确认 capabilities.pip=true,并在内容中传入 isVideoStream: true。Android 还要求 Android 8.0 及以上且当前 App 页面允许画中画;普通网页和业务卡片应使用悬浮窗模式。
localFile 可以传任意本地路径吗
不可以。当前对外保证中,localFile 只支持 Harmony 画中画,并且文件必须是当前应用自己目录中的 MP4。随应用发布的视频使用 localAsset;任意系统绝对路径、目录、符号链接和跨应用文件均不支持。
文件选择和摄像头实时采集是同一个能力吗
不是。webFileChooser 对应标准 <input type="file">;webMediaCapture 对应网页实时使用摄像头和麦克风。应分别读取能力并按业务显示入口。
升级插件后为什么行为仍和旧安装包一致
该插件包含原生能力。首次接入,或更新说明明确包含原生能力变更时,需要重新制作并安装对应平台的自定义基座或正式安装包;纯文档和页面资源更新不需要重新制作。
注意事项
- 远程 H5 只允许精确 HTTPS Origin;消息必须包含非空
event,单条最大 256 KB,插件不提供任意 JavaScript 执行能力。 - 网页媒体权限按最小需要配置;长期 Token、密钥和生产凭据不得写入页面、README 或代码仓库。
- 页面卸载时应取消持续监听,业务结束时应关闭悬浮窗或退出画中画,避免重复回调和资源占用。
- 诊断结果可能包含当前页面 Origin、权限状态和最近错误摘要,对外提供前应先检查内容。
- App 端首次接入,或更新说明明确包含原生能力变更时,需要重新制作并安装对应平台的自定义基座或正式安装包;纯文档和页面资源更新不需要重新制作。
作者系列 UTS 插件
以下为已在 DCloud 插件市场上架的作者系列 UTS 插件,可按业务场景组合使用。未列出的插件表示当前未确认公开市场页,后续上架后再补充。
| 插件 | 能力方向 | 插件市场 |
|---|---|---|
lizhao-nfc-pro |
NFC 标签读写、NDEF、IsoDep 与诊断 | 查看插件 |
lizhao-float-window |
悬浮窗、画中画、权限与诊断 | 查看插件 |
lizhao-device-id |
设备标识、隐私策略与诊断 | 查看插件 |
lizhao-scan-pro |
原生扫码、连续扫码、相册识别 | 查看插件 |
lizhao-choose-file |
原生文件选择、上传、进度与取消 | 查看插件 |
lizhao-bg-audio |
背景音频播放、队列、倍速与事件 | 查看插件 |
lizhao-smart-tts |
系统 TTS、云端合成、听书方案 | 查看插件 |
lizhao-share-plus |
系统分享、远程文件下载后分享 | 查看插件 |
lizhao-sqlite-pro |
原生 SQLite、迁移、备份与诊断 | 查看插件 |
lizhao-icon-pro |
SVG 图标组件、多主题与缓存 | 查看插件 |
lizhao-cast-screen |
DLNA 投屏、AirPlay 路由入口 | 查看插件 |
lizhao-call-kit |
电话、短信、通讯录原生能力 | 查看插件 |
lizhao-app-keepalive |
应用保活、唤醒、自愈与报告 | 查看插件 |
lizhao-doc-corrector |
文档扫描、矫正、增强与识别 | 查看插件 |
lizhao-emu-detect |
模拟器环境检测、风险评分与证据 | 查看插件 |
lizhao-gallery-pro |
相册媒体分页、筛选、缩略图与导出 | 查看插件 |
lizhao-video-thumb |
视频封面、批量取帧与 Base64 返回 | 查看插件 |
lizhao-ble |
BLE 扫描、连接、读写、通知与自动重连 | 查看插件 |
lizhao-sse-pro |
SSE、Line、JSONL 与 Raw 流式请求 | 查看插件 |
lizhao-pdf-pro |
PDF 阅读、签批、真实写回与页面处理 | 查看插件 |
lizhao-serial-port |
路径串口、USB 串口、多会话收发与诊断 | 查看插件 |
lizhao-wechat-kit |
微信登录、分享、支付、小程序与客服 | 查看插件 |
lizhao-video-editor |
视频裁剪、压缩、取帧与 FFmpeg/FFprobe | 查看插件 |
lizhao-vpn-pro |
企业 VPN、IKEv2、安全接入与脱敏诊断 | 查看插件 |

收藏人数:
购买源码授权版(
试用
赞赏(0)
下载 6486
赞赏 5
下载 12608981
赞赏 1949
赞赏
京公网安备:11010802035340号