鸿蒙 ArkTS 隐私模式防护:系统级截屏/录屏拦截方案
文章目录前言️ 核心机制窗口级隐私保护防护链路 状态驱动的双页面切换普通页面currentTab 0敏感页面currentTab 1切换逻辑⏱️ 生命周期自动防护️ 手动控制与状态监控手动开关状态展示 防护日志完整代码 设计亮点与最佳实践总结前言这段代码实现了一个完整的隐私模式防护方案核心利用 HarmonyOS 的setWindowPrivacyModeAPI在敏感页面自动开启系统级截屏/录屏拦截防止用户敏感数据被泄露。️ 核心机制窗口级隐私保护与权限管理不同隐私模式不需要用户授权而是由应用主动告知系统窗口管理器WM“这个窗口的内容不允许被截屏或录屏捕获”。开启后截屏/录屏只会得到黑屏或系统拦截提示。防护链路代码中的FlowSection清晰展示了四个关键步骤步骤操作说明1声明权限ohos.permission.PRIVACY_WINDOW2getLastWindow获取当前 UIAbility 的主窗口实例3setWindowPrivacyMode(true)通知 WM 禁止截屏/录屏4生命周期绑定敏感页onPageShow开启 /onPageHide关闭 状态驱动的双页面切换代码通过 Tab 切换模拟了两个页面场景直观展示隐私模式的按需开关策略。普通页面currentTab 0BuilderNormalPageSection(){// 未启用隐私模式截屏/录屏可正常捕获Text(此页面未启用隐私模式系统截屏和录屏可正常捕获窗口内容。)}适用于首页、商品列表等非敏感场景用户可正常截屏分享。敏感页面currentTab 1BuilderSensitivePageSection(){// 隐私模式保护中截屏/录屏将被拦截this.SensitiveRow(银行卡号,SENSITIVE_CARD_NO)this.SensitiveRow(身份证号,SENSITIVE_ID_MASKED)this.SensitiveRow(账户余额,SENSITIVE_BALANCE)}展示银行卡号、身份证号、账户余额等敏感信息进入此页时自动开启防护。切换逻辑privateswitchTab(index:number):void{this.currentTabindexif(index1){PrivacyModeService.enable(切换至敏感页)// 进入敏感页 → 开启防护}else{PrivacyModeService.disable(切换至普通页)// 回到普通页 → 关闭防护}}⏱️ 生命周期自动防护除了手动切换代码还通过页面生命周期实现自动化的隐私防护这是生产环境中最推荐的做法。onPageShow():void{if(this.currentTab1){PrivacyModeService.enable(敏感页 onPageShow)// 页面可见时开启}}onPageHide():void{PrivacyModeService.disable(页面 onPageHide)// 页面隐藏时关闭}这确保了即使用户通过其他方式如系统多任务切换进入敏感页面防护也能自动生效。️ 手动控制与状态监控手动开关ControlSection提供了一个 Toggle 开关允许开发者在调试时手动控制隐私模式Toggle({type:ToggleType.Switch,isOn:this.privacyEnabled}).onChange((on:boolean){if(on){PrivacyModeService.enable(手动 Toggle)}else{PrivacyModeService.disable(手动 Toggle)}})状态展示HeaderSection实时展示防护状态防护中绿色标签#4ADE80表示隐私模式已启用状态文字根据privacyEnabled显示绿色已启用或黄色未启用窗口信息显示窗口 ID 和当前触发场景方便调试定位 防护日志LogSection记录每一次隐私模式的开关操作包括时间戳、触发层级和详细信息ForEach(this.logs,(item:PrivacyLogItem){Column({space:2}){Text([${item.time}]${item.layer})// 如 [19:25:00] SERVICEText(item.message)// 如 隐私模式已开启: 切换至敏感页}})这些日志对于排查为什么某个页面没有被保护或隐私模式是否被意外关闭等问题非常关键。完整代码import{common}fromkit.AbilityKitimport{PrivacyBridge,PrivacyModeService}from../privacy/PrivacyModeServiceimport{PrivacyLogItem,SENSITIVE_BALANCE,SENSITIVE_CARD_NO,SENSITIVE_ID_MASKED}from../privacy/PrivacyModeTypesEntryComponentstructPrivacyModeDemo{StorageLink(privacyEnabled)privacyEnabled:booleanfalseStorageLink(privacyStatus)privacyStatus:stringStorageLink(privacyWindowId)privacyWindowId:number0StorageLink(activeScene)activeScene:stringStorageLink(privacyLogs)logs:PrivacyLogItem[][]StorageLink(demoMode)demoMode:booleanfalseStatecurrentTab:number0private context:common.UIAbilityContextthis.getUIContext().getHostContext()ascommon.UIAbilityContextaboutToAppear():void{PrivacyModeService.bindContext(this.context)PrivacyModeService.disable(应用启动)}onPageShow():void{if(this.currentTab1){PrivacyModeService.enable(敏感页 onPageShow)}}onPageHide():void{PrivacyModeService.disable(页面 onPageHide)}build(){Scroll(){Column({space:12}){this.HeaderSection()this.TabSection()if(this.currentTab0){this.NormalPageSection()}else{this.SensitivePageSection()}this.ControlSection()this.FlowSection()this.LogSection()}.width(100%).padding(16)}.width(100%).height(100%).backgroundColor(#0F172A)}BuilderHeaderSection(){Column({space:6}){Row({space:8}){Text(隐私模式防护).fontSize(20).fontWeight(FontWeight.Bold).fontColor(#F8FAFC)if(this.privacyEnabled){Text(防护中).fontSize(11).fontColor(#4ADE80).padding({left:6,right:6,top:2,bottom:2}).backgroundColor(#14532D).borderRadius(4)}}Text(setWindowPrivacyMode · 系统级截屏/录屏拦截).fontSize(12).fontColor(#94A3B8)Text(this.privacyStatus).fontSize(11).fontColor(this.privacyEnabled?#4ADE80:#FBBF24)Text(窗口 ID:${this.privacyWindowId}· 场景:${this.activeScene}).fontSize(10).fontColor(#64748B)}.width(100%).alignItems(HorizontalAlign.Start)}BuilderTabSection(){Row({space:8}){Button(普通页面).fontSize(12).layoutWeight(1).backgroundColor(this.currentTab0?#1D4ED8:#334155).onClick((){this.switchTab(0)})Button(敏感页面).fontSize(12).layoutWeight(1).backgroundColor(this.currentTab1?#7F1D1D:#334155).onClick((){this.switchTab(1)})}.width(100%)}BuilderNormalPageSection(){Column({space:8}){Text(公开内容区).fontSize(14).fontColor(#E2E8F0)Text(此页面未启用隐私模式系统截屏和录屏可正常捕获窗口内容。).fontSize(12).fontColor(#94A3B8)Text(适合首页、商品列表等非敏感场景。).fontSize(11).fontColor(#64748B)}.width(100%).padding(12).backgroundColor(#1E293B).borderRadius(10)}BuilderSensitivePageSection(){Column({space:10}){Row({space:6}){Text().fontSize(16)Text(敏感信息区隐私模式保护).fontSize(14).fontWeight(FontWeight.Medium).fontColor(#FCA5A5)}this.SensitiveRow(银行卡号,SENSITIVE_CARD_NO)this.SensitiveRow(身份证号,SENSITIVE_ID_MASKED)this.SensitiveRow(账户余额,SENSITIVE_BALANCE)Text(真机测试进入此页后尝试截屏/录屏应得到黑屏或系统拦截提示。).fontSize(11).fontColor(#FDE68A)}.width(100%).padding(12).backgroundColor(#450A0A).borderRadius(10).border({width:1,color:#7F1D1D})}BuilderSensitiveRow(label:string,value:string){Row(){Text(label).fontSize(12).fontColor(#FECACA).width(72)Text(value).fontSize(14).fontWeight(FontWeight.Medium).fontColor(#F8FAFC).layoutWeight(1)}.width(100%)}BuilderControlSection(){Column({space:8}){Row(){Text(手动开关).fontSize(13).fontColor(#E2E8F0)Blank()Toggle({type:ToggleType.Switch,isOn:this.privacyEnabled}).onChange((on:boolean){if(on){PrivacyModeService.enable(手动 Toggle)}else{PrivacyModeService.disable(手动 Toggle)}})}.width(100%)Button(刷新窗口状态).width(100%).fontSize(12).onClick((){PrivacyModeService.refreshStatus()})}.width(100%).padding(12).backgroundColor(#172554).borderRadius(10)}BuilderFlowSection(){Column({space:6}){Text(防护链路).fontSize(13).fontColor(#E2E8F0)this.FlowRow(1,声明权限,ohos.permission.PRIVACY_WINDOW)this.FlowRow(2,getLastWindow,获取当前 UIAbility 主窗口)this.FlowRow(3,setWindowPrivacyMode(true),通知 WM 禁止截屏/录屏)this.FlowRow(4,生命周期,敏感页 onPageShow 开 / onPageHide 关)}.width(100%).padding(12).backgroundColor(#1E293B).borderRadius(10)}BuilderLogSection(){Column({space:6}){Row(){Text(防护日志).fontSize(13).fontColor(#E2E8F0)Blank()Text(${this.logs.length}条).fontSize(12).fontColor(#38BDF8)}.width(100%)if(this.logs.length0){Text(切换至敏感页面或打开开关…).fontSize(12).fontColor(#64748B)}else{ForEach(this.logs,(item:PrivacyLogItem){Column({space:2}){Text([${item.time}]${item.layer}).fontSize(11).fontColor(#F472B6)Text(item.message).fontSize(11).fontColor(#CBD5E1)}.width(100%).alignItems(HorizontalAlign.Start)},(item:PrivacyLogItem)item.id)}}.width(100%).padding(12).backgroundColor(#1E293B).borderRadius(10)}BuilderFlowRow(index:string,title:string,detail:string){Row({space:10}){Text(index).fontSize(12).fontColor(#38BDF8).width(20)Column({space:2}){Text(title).fontSize(12).fontColor(#E2E8F0)Text(detail).fontSize(11).fontColor(#64748B)}.alignItems(HorizontalAlign.Start).layoutWeight(1)}.width(100%)}privateswitchTab(index:number):void{this.currentTabindexif(index1){PrivacyModeService.enable(切换至敏感页)}else{PrivacyModeService.disable(切换至普通页)}}} 设计亮点与最佳实践最小权限原则隐私模式仅在展示敏感信息时开启普通页面保持正常避免过度防护影响用户体验如用户想截屏分享商品。双重保障既有 Tab 切换时的主动开关又有onPageShow/onPageHide的生命周期兜底防止遗漏。服务层封装所有操作通过PrivacyModeService统一调度UI 层只负责展示和触发逻辑清晰、易于维护。全局状态同步使用StorageLink将privacyEnabled等状态提升到AppStorage确保任何页面都能感知当前防护状态。总结这段代码是 HarmonyOS 应用中敏感信息保护的标准实现模板。通过setWindowPrivacyMode这一系统级 API配合页面生命周期的自动管理构建了一个可靠、可控的隐私防护方案。对于金融、医疗、政务等涉及敏感数据的应用来说这是合规和安全的基本要求。