当前位置: 首页 > news >正文

HarmonyOS SnapshotUtil 窗口截图与系统截屏监听:snapshot() 和 onSnapshotListener 详解

文章目录

    • 背景
      • 方法总览
      • snapshot():截取主窗口
      • onSnapshotListener:监听系统截屏事件
      • 完整监听开关实现
      • 使用注意事项
      • SnapshotUtil 功能总结
      • 写在最后

背景

近期发现一款很有意思的HarmonyOS 三方库, 地址 @pura/harmony-utils(V1.4.0) , 作者是"桃花镇童长老", 我这里也是直接通过该作者公布的源码进行案例编写进行,写了到目前写了一部分demo ,感觉确实很有帮助,这里呢也是开始写一个系列的演示demo 供大家参考。如有帮助可以在OpenHarmony中进行下载安装进行使用哦

案例demo导航展示

↓↓↓↓↓↓接下来言归正传 ↓↓↓↓
前两篇讲了组件级截图(get()createFromBuilder),这篇来讲两个更"高级"的功能:

  1. snapshot():截取整个应用窗口
  2. onSnapshotListener():监听用户的系统截屏操作(用户按下截图键时你能收到通知)

方法总览

snapshot():截取主窗口

snapshot()不需要指定组件 id,它直接截取整个应用窗口的内容,返回PixelMap

this.Btn('snapshot() 截取主窗口','#E74C3C',()=>{SnapshotUtil.snapshot().then(pm=>{this.addLog(`snapshot() → PixelMap${pm.getPixelBytesNumber()}bytes`);}).catch((e:Error)=>{this.addLog(`snapshot() Error:${e.message}`);});})

用法和get()类似,也是返回 Promise,在.then()里拿到PixelMap

注意snapshot()截取的是应用窗口内容,系统状态栏、导航栏通常不在截图范围内,具体取决于系统版本和窗口配置。

onSnapshotListener:监听系统截屏事件

这个功能比较特别——它不是让你主动截图,而是监听用户使用系统截图功能(按音量键+电源键,或者三指滑动)的行为。

应用场景:

  • 聊天应用提示"对方对本页面进行了截图"
  • 敏感内容页面的截图提醒
  • 截图后自动弹出分享对话框

开启监听

privatesnapshotListener:VoidCallback=()=>{this.addLog('[系统截图事件] 检测到截屏操作!');};// 开启截屏监听SnapshotUtil.onSnapshotListener(this.snapshotListener);this.isListening=true;this.addLog('onSnapshotListener() 已开启截图监听,请按下截图键触发...');

注意snapshotListener定义在组件的成员变量里,是一个VoidCallback类型的函数。必须保存这个函数引用,后面取消监听时需要用到同一个引用。

关闭特定监听

// 取消指定的监听(传入之前保存的 listener 引用)SnapshotUtil.removeSnapshotListener(this.snapshotListener);this.isListening=false;this.addLog('removeSnapshotListener(callback) 已关闭截图监听');

关闭所有监听

// 不传参数,关闭所有截屏监听SnapshotUtil.removeSnapshotListener();this.isListening=false;this.addLog('removeSnapshotListener() 已关闭所有截图监听');

完整监听开关实现

@StateisListening:boolean=false;privatesnapshotListener:VoidCallback=()=>{this.addLog('[系统截图事件] 检测到截屏操作!');};// UI 部分Row({space:8}){Button(this.isListening?'关闭监听':'开启监听').layoutWeight(1).height(40).fontSize(14).fontColor('#fff').backgroundColor(this.isListening?'#E74C3C':'#27AE60').borderRadius(8).onClick(()=>{if(this.isListening){SnapshotUtil.removeSnapshotListener(this.snapshotListener);this.isListening=false;this.addLog('removeSnapshotListener(callback) 已关闭截图监听');}else{SnapshotUtil.onSnapshotListener(this.snapshotListener);this.isListening=true;this.addLog('onSnapshotListener() 已开启截图监听,请按下截图键触发...');}})Button('removeSnapshotListener() 关闭所有').layoutWeight(1).height(40).fontSize(13).fontColor('#fff').backgroundColor('#F39C12').borderRadius(8).onClick(()=>{SnapshotUtil.removeSnapshotListener();this.isListening=false;this.addLog('removeSnapshotListener() 已关闭所有截图监听');})}// 状态指示器Row({space:8}){Circle({width:10,height:10}).fill(this.isListening?'#2ECC71':'#BDC3C7')Text(this.isListening?'截图监听中...':'截图监听未开启').fontSize(13).fontColor(this.isListening?'#27AE60':'#999')}

这个实现有个小细节值得学:用@State isListening: boolean来控制按钮文字和颜色,监听开启时按钮变红色显示"关闭监听",没开启时显示绿色"开启监听"。这种"状态驱动 UI"的写法是 ArkTS 的标准范式。

使用注意事项

1. Listener 引用要保存

onSnapshotListener注册的 listener 和removeSnapshotListener取消时,必须是同一个函数引用。如果每次都传匿名函数,就没法精确取消:

// ❌ 错误:每次 onClick 都创建新的匿名函数,removeSnapshotListener 找不到原来那个SnapshotUtil.onSnapshotListener(()=>{console.log('截图了');});// 之后这样取消是无效的,因为引用不同SnapshotUtil.removeSnapshotListener(()=>{console.log('截图了');});// ✅ 正确:保存引用privatemyListener:VoidCallback=()=>{console.log('截图了');};SnapshotUtil.onSnapshotListener(this.myListener);// 取消时用同一个引用SnapshotUtil.removeSnapshotListener(this.myListener);

2. 记得在页面销毁时取消监听

如果你在页面里开启了截屏监听,记得在aboutToDisappear()生命周期里取消:

aboutToDisappear(){SnapshotUtil.removeSnapshotListener(this.snapshotListener);}

不取消的话,页面销毁了 listener 还在,可能导致内存泄漏或回调到已销毁的组件。

SnapshotUtil 功能总结

方法功能返回值
get(id)异步截取指定 id 的组件Promise<PixelMap>
get(id, options)异步截取,支持缩放等选项Promise<PixelMap>
getSync(id)同步截取指定 id 的组件PixelMap
getSync(id, options)同步截取,支持等待渲染完成PixelMap
createFromBuilder(fn, delay, check)离屏渲染并截图Promise<PixelMap>
snapshot()截取整个应用窗口Promise<PixelMap>
onSnapshotListener(cb)注册系统截屏监听void
removeSnapshotListener(cb?)取消截屏监听void

写在最后

截屏监听这个功能在国内社交应用里特别常见——聊天消息截图提醒几乎是标配。onSnapshotListener让你在 HarmonyOS 上实现这个功能变得很简单,几行代码搞定。

记住要保存 listener 引用,记住页面销毁时取消监听,就没什么坑了。

http://www.jsqmd.com/news/918809/

相关文章:

  • 创业者必看:柳州螺蛳粉技术培训哪家靠谱?实力全测评 - 资讯纵览
  • 树莓派Pico与BMP180传感器:从I2C通信到微型气象站搭建实践
  • 5分钟实战:draw.io桌面版深度构建指南,从源码到跨平台安装包
  • SmolLM2-1.7B-Instruct部署优化:NPU与CPU环境下的性能调优技巧
  • 灵达科技亮相天津智博会,存储互联+高速互联双赛道
  • 告别密密麻麻!ECharts饼图图例太多怎么优雅分页?scroll配置全解析
  • 提升用户体验:gh_mirrors/li/live2d_demo事件触发与交互设计指南
  • 2026南充瑜伽普拉提培训机构深度评测报告 - 资讯纵览
  • 三步轻松备份微信聊天记录:你的数字记忆保险箱 [特殊字符]️
  • ControlNet-XS with Stable Diffusion XL完全指南:从安装到生成高质量图像的简单教程
  • xss-filters实战教程:保护HTML数据与属性的10个最佳实践
  • 186、运动控制中的行业应用:无人机飞控
  • 三协议合一:如何用LuckyLilliaBot打造你的全能QQ机器人助手
  • ACE-Step 1.5 XL Turbo商业授权指南:合法合规使用AI生成音乐的终极攻略
  • 鸣潮自动化工具终极指南:如何实现后台智能战斗与资源收集
  • 基于ESP8266与PI算法的公交车智能限速系统设计与实现
  • DLSS Swapper技术架构深度解析:跨平台游戏DLSS文件管理系统的实现原理
  • 别再让远处的模型糊成一片了!在Unity/UE4里正确开启Mipmap的保姆级教程
  • 日喀则本地专业防水TOP5靠谱推荐:家里漏水不用愁,免费上门不求人。本地最新防水企业资讯:专业师傅持证上门,收费透明无隐藏收费,质保5-10年,售后有保障 - 企业资讯
  • SANA-WM模型架构深度解析:2.6B参数扩散变换器的设计哲学
  • 如何零成本将3D视频变2D?VR-Reversal让你告别VR设备也能享受沉浸体验
  • 房地产AI合规红线清单(含住建部新规+GDPR+生成式AI备案要求),错过即停用
  • 紧急通知:NIST AI RMF 1.1已强制要求部署文档包含风险溯源字段——Gemini文档编写的最后72小时合规补救方案
  • CatPPT部署实战:从本地环境到云端服务的完整配置指南
  • 西安本地专业防水TOP5靠谱推荐:家里漏水不用愁,免费上门不求人。本地最新防水企业资讯:专业师傅持证上门,收费透明无隐藏收费,质保5-10年,售后有保障 - 企业资讯
  • 别再手动调顶点!Unity程序化生成Mesh的5个实战场景(附完整代码)
  • Cowabunga Lite 终极指南:免越狱iOS深度定制完整解决方案
  • Fetch GitHub Hosts终极指南:免费快速解决GitHub访问难题
  • 终极Windows驱动管理指南:如何用Driver Store Explorer彻底解决系统卡顿问题
  • 基于Arduino与蓝牙的移动抓取机器人:从硬件集成到App控制全解析