讨论广场 问答详情
折叠屏上想开悬浮窗,`window` 接口调用一直失败
bug菌¹ 2026-11-02 16:37:29
赞 54 评论 分享
鸿蒙问答专区

想做一个"小窗继续播放"的功能,调 window.createWindow 开悬浮窗,一直抛错。是我权限不够还是折叠屏不支持?

 

坐标和尺寸我用的是 windowRect,这个有讲究吗?

赞 54 评论 分享
写回答
全部评论(4)

折叠屏上开悬浮窗失败,最高频的三个原因,按命中率排:

一、调用时机:createWindow 必须在 windowStage 就绪后调用——在 aboutToAppear 等页面早期生命周期里调,windowStage 还没就绪会直接失败。正确姿势是在 EntryAbility 的 onWindowStageCreate 里创建,或页面通过 getContext 拿到上下文且 windowStage 加载完成后再操作。

二、权限与设备策略:1)应用需要悬浮窗权限——设置里确认该应用的悬浮窗开关已打开;2)折叠屏展开态(大屏)上部分系统版本对第三方悬浮窗的尺寸、数量有策略限制,折叠态能开展开态失败的话,先怀疑设备策略。

三、参数问题:createWindow 的 type 必须是支持的类型(TYPE_FLOAT 等),name 不能重复(重复创建同名窗口会失败),尺寸不能超屏。展开态屏幕变大后,硬编码的窗口尺寸参数如果超界也会失败。

排查建议:把 createWindow 的 err 打出来看具体码——401 参数错、1300002 窗口已存在、1300003 系统服务异常,错误码不同修法不同。另外折叠态切换时窗口需要监听尺寸变化重新布局,不是一次性创建完事。

一句话收束:时机(windowStage 就绪后)、权限(悬浮窗开关)、参数(类型/重名/尺寸)三个方向查,错误码会告诉你具体是哪个。

赞
2026-11-03 23:25:19

可以打印错误码和创建参数:TYPE_FLOAT 需 SYSTEM_FLOAT_WINDOW 权限,201优先查授权,401查参数,801查能力支持,1300001查重复创建;

不能仅凭折叠屏就判断不支持。windowRect 的坐标、宽高是 px,写入默认使用 vp 的布局属性前要转换;开合后重新读取,别复用旧尺寸。

赞
2026-11-03 12:45:45
2 楼

悬浮窗(自由窗口)能力对普通应用是受限的,先确认三件事:

① 能力层级

窗口模式谁能用
全屏、分屏普通应用(声明 supportWindowMode 即可)
悬浮窗(自己创建独立小窗)通常需要系统应用权限,普通应用不可用
应用内"画中画"效果用 PiPWindow/Window 的 PIP 模式(部分场景可用)
系统级全局画中画需系统权限

先确认你的目标能不能走"应用内小窗 + 悬浮抽屉"这条更实际的路:

// 用 Stack 在应用窗口内做一个可拖拽的小窗,不需要系统能力
Stack({ alignContent: Alignment.BottomEnd }) {
  this.MainContent()
​
  if (this.showFloat) {
    Column() {
      this.MiniPlayer()
    }
    .width(200)
    .height(120)
    .backgroundColor('#333')
    .borderRadius(12)
    .margin({ right: 16, bottom: 16 })
    .gesture(PanGesture().onActionUpdate((e) => {
      this.floatX += e.offsetX
      this.floatY += e.offsetY
    }))
  }
}

② 如果是系统应用/已获权限,创建窗口的正确姿势

import { window } from '@kit.ArkUI'
​
const win = await window.createWindow({
  name: 'float_win',
  windowType: window.WindowType.TYPE_FLOAT,
  ctx: context
})
​
// 尺寸不要用像素,用 vp 换算
await win.resize(vp2px(320), vp2px(480))
​
// 位置:折叠屏要基于"当前窗口可用区域"算,不能假设 (0,0) 是左上角
await win.moveWindowTo(vp2px(40), vp2px(80))
​
await win.setUIContent('pages/FloatPage')
await win.showWindow()

③ 常见失败原因排序

报错原因排查
无窗口权限是否为系统应用 / 是否申请了对应权限
窗口类型不支持TYPE_FLOAT 在小屏/折叠态可能被拒绝
尺寸超限超出 maxWindowWidth 等约束
未在 UIAbility 上下文调用必须传 Ability 的 context

④ 折叠屏特有:悬浮窗在小屏(折叠态)上往往被系统转成全屏或分屏。要在 windowSizeChange 里做降级处理:小屏收起为底部迷你条,展开后再恢复浮窗。

给产品的替代方案:用"应用内悬浮球 + 迷你播放条" 实现 90% 的价值,开发成本低一个数量级,还不受系统限制。真要做全局小窗,那通常是系统应用或视频类白名单应用的战场。

1
2026-11-03 09:52:00

折叠屏上开悬浮窗失败,最高频的三个原因,按命中率排:

一、调用时机:createWindow 必须在 windowStage 就绪后调用——在 aboutToAppear 等页面早期生命周期里调,windowStage 还没就绪会直接失败。正确姿势是在 EntryAbility 的 onWindowStageCreate 里创建,或页面通过 getContext 拿到上下文且 windowStage 加载完成后再操作。

二、权限与设备策略:1)应用需要悬浮窗权限——设置里确认该应用的悬浮窗开关已打开;2)折叠屏展开态(大屏)上部分系统版本对第三方悬浮窗的尺寸、数量有策略限制,折叠态能开展开态失败的话,先怀疑设备策略。

三、参数问题:createWindow 的 type 必须是支持的类型(TYPE_FLOAT 等);name 不能重复(重复创建同名窗口直接报错);窗口尺寸不能超屏——展开态屏幕变大后,硬编码的尺寸参数一般不会超,但折叠态和展开态切换时窗口需要监听尺寸变化重新布局,不是一次性创建完事。

排查建议:把 createWindow 的 err 完整打出来看错误码——参数错误、窗口已存在、系统服务异常对应不同修法;再确认 API 版本(window 模块部分接口有版本门槛)。

一句话收束:时机(windowStage 就绪后)、权限(悬浮窗开关)、参数(类型/重名/尺寸)三个方向查,createWindow 的错误码会告诉你具体是哪个。

赞
2026-11-02 23:13:20