OH_AVScreenCapture 无法采集输入法悬浮窗?窗口排除与采集范围实战
·
OH_AVScreenCapture 无法采集输入法悬浮窗?窗口排除与采集范围实战
前言
屏幕采集(OH_AVScreenCapture)在做录屏、直播、协同标注类应用时是刚需。开发者常遇到一个困惑:「我采集了整个屏幕,为什么软键盘的候选词/悬浮窗不在画面里?能不能把它也采进去?」这涉及 HarmonyOS 的窗口采集范围与隐私窗口排除策略。本文给出配置代码,并讲清哪些窗口能采、哪些被系统强制排除。
问题描述
- 调用
OH_AVScreenCapture录屏,回放时发现输入法(IME)候选词悬浮窗、键盘悬浮窗完全没出现; - 用
OH_AVScreenCapture_SetWindowSelection指定窗口后,普通应用窗口能精准采集,但 IME 窗口依旧缺席; - 怀疑是自己
captureMode/dataType配错,反复改OH_AVScreenCapture_Config无效; - 想「只录某个窗口」,结果录出来是整个屏幕。
根因不在你的配置,而在系统的隐私窗口排除规则 + 采集模式选择。
细节解析
-
两类采集模式:
OH_Screen_Capture_Surface/INTRA模式:采集整屏或指定显示,输出到Surface或VirtualScreen;- 是否包含某些系统窗口由
windowSelection控制。
-
隐私窗口默认被排除:出于安全,系统对以下窗口默认不采集:输入法窗口(含候选词、键盘悬浮窗)、系统状态栏/导航栏、密码输入框、锁屏、以及标记为
PRIVACY的窗口。这是平台级策略,不是配置能绕过的。 -
OH_AVScreenCapture_SetWindowSelection控制的是「要采集哪些可见窗口」:它用WindowSelection(选择模式 + 窗口 ID 列表)决定采集范围。可以「采集全部可见窗口(排除隐私窗)」或「只采集指定的若干窗口」。即便你显式把 IME 窗口 ID 加进白名单,系统仍会因隐私策略屏蔽 IME 内容——所以你会看到「指定了但就是采不到」。 -
正确姿势:
- 想要「常规录屏(不含键盘)」:默认即可,无需额外配置;
- 想要「只录某个应用窗口」:用
WindowSelection选WINDOW_SELECTION_BY_ID并填目标窗口 ID 列表; - 想要「键盘也出现在画面里」:系统不允许采集 IME 隐私窗口,只能引导用户用物理键盘或把输入区做成应用内自定义输入框(属于你自己 App 的窗口,可采)。
示例代码
C 侧配置(采集指定窗口,IME 仍被排除):
#include <multimedia/screen_capture/av_screen_capture.h>
OH_AVScreenCapture *capture = OH_AVScreenCapture_Create();
OH_AVScreenCapture_Config config;
config.captureMode = OH_SCREEN_CAPTURE_MODE_SURFACE;
config.dataType = OH_SCREEN_CAPTURE_DATA_TYPE_VIDEO;
config.videoInfo.windowId = 0; // 0 表示整屏
config.videoInfo.windowRect = (OH_Rect){0, 0, 0, 0}; // 全屏
config.audioInfo.micSwitch = false;
config.audioInfo.innerSwitch = false;
OH_AVScreenCapture_Init(capture, &config);
// 选择「只采集指定窗口」(IME 即便加入也会被隐私策略屏蔽)
OH_AVScreenCapture_WindowSelection selection;
selection.selectionMode = OH_WINDOW_SELECTION_BY_ID;
uint64_t ids[] = { targetWindowId }; // 你的业务窗口 ID
selection.windowIds = ids;
selection.windowCount = 1;
OH_AVScreenCapture_SetWindowSelection(capture, &selection);
OH_AVScreenCapture_Start(capture);
ArkTS 侧拿窗口 ID(用于「只录本应用窗口」):
import { window } from '@kit.ArkUI';
// 在 UIAbility 里获取当前窗口 ID
const win = await window.getLastWindow(this.context);
const id: number = win.getWindowProperties().id; // 传给 native 作为 targetWindowId
关键修正:
- 输入法候选词/键盘悬浮窗是隐私窗口,平台强制排除,任何配置都采不到——这不是 bug,别在
Config上死磕; SetWindowSelection用来选「采集哪些可见窗口」(全屏 / 指定窗口),不是用来「解锁隐私窗」;- 若业务确需「输入内容出现在录屏里」,把输入控件做成应用内自定义组件(属于你自己的窗口,可采),而非依赖系统 IME;或用外接物理键盘;
- 排查顺序:确认
captureMode/dataType正确 → 用WindowSelection选窗口 → 接受 IME 不可采的事实 → 需要就改产品设计。
总结
OH_AVScreenCapture默认排除隐私窗口,IME(键盘/候选词悬浮窗)即属此类,系统级不可采集;OH_AVScreenCapture_SetWindowSelection控制采集范围(整屏 or 指定窗口 ID),无法突破隐私策略;- 想「键盘进画面」:用应用内自定义输入框(自身窗口可采)或物理键盘,而非系统 IME;
- 录指定窗口:用
OH_WINDOW_SELECTION_BY_ID+ 目标windowId,从window.getWindowProperties().id获取。
更多推荐



所有评论(0)