前言
欢迎加入开源鸿蒙跨平台社区:https://openharmonycrossplatform.csdn.net
secure_application 支持五个平台:Android、iOS、Web、Windows、OpenHarmony。每个平台的隐私保护机制都不一样------有的能从系统层面阻止截屏,有的只能靠遮挡来"假装"保护。这篇把五个平台的实现方案、能力边界、代码差异做一个全面的横向对比。
做跨平台开发的同学应该会觉得这篇比较有参考价值。
一、五平台能力矩阵
1.1 核心能力对比

1.2 保护强度评级
| 平台 | 评级 | 说明 |
|---|---|---|
| Android | ⭐⭐⭐⭐⭐ | 系统级截屏/录屏防护 + Flutter 遮罩 |
| OpenHarmony | ⭐⭐⭐⭐⭐ | 系统级截屏/录屏防护 + Flutter 遮罩 |
| iOS | ⭐⭐⭐⭐ | 原生模糊遮挡 + Flutter 遮罩,但无法阻止截屏 |
| Windows | ⭐⭐⭐ | Flutter 遮罩 + 最小化检测,无截屏防护 |
| Web | ⭐⭐ | Flutter 遮罩 + 可见性检测,无截屏防护 |
💡 Android 和 OpenHarmony 并列第一,因为它们都提供了系统级的截屏/录屏防护。iOS 虽然不能阻止截屏,但原生模糊遮挡在应用切换器中的效果很好。
二、原生实现方式对比
2.1 核心 API
| 平台 | 核心 API | 类型 |
|---|---|---|
| Android | Window.addFlags(FLAG_SECURE) |
同步 |
| iOS | UIVisualEffectView + 生命周期 |
同步 |
| OpenHarmony | Window.setWindowPrivacyMode(bool) |
异步 |
| Web | document.addEventListener('visibilitychange') |
事件 |
| Windows | WM_SIZE / WM_POWERBROADCAST 消息 |
消息循环 |
2.2 实现语言
| 平台 | 语言 | 文件 |
|---|---|---|
| Android | Kotlin | SecureApplicationPlugin.kt |
| iOS | Swift | SecureApplicationPlugin.swift |
| OpenHarmony | ArkTS | SecureApplicationPlugin.ets |
| Web | Dart | secure_application_web.dart |
| Windows | C++ | SecureApplicationPlugin.cpp |
2.3 代码量对比
| 平台 | 行数 | 复杂度 |
|---|---|---|
| Android | ~120 | 低 |
| iOS | ~100 | 中 |
| OpenHarmony | ~234 | 中高 |
| Web | ~50 | 低 |
| Windows | ~80 | 低 |
OpenHarmony 的代码量最多,因为它实现了双重检测机制(窗口事件 + 生命周期回调)。
三、Android vs OpenHarmony 深度对比
3.1 隐私模式开关
kotlin
// Android
activity.window.addFlags(LayoutParams.FLAG_SECURE) // 开启
activity.window.clearFlags(LayoutParams.FLAG_SECURE) // 关闭
typescript
// OpenHarmony
await win.setWindowPrivacyMode(true) // 开启
await win.setWindowPrivacyMode(false) // 关闭
| 维度 | Android | OpenHarmony |
|---|---|---|
| 同步/异步 | 同步 | 异步 |
| 错误反馈 | 无 | Promise reject |
| 窗口获取 | activity.window(同步) | getLastWindow(异步) |
| 权限要求 | 无 | PRIVACY_WINDOW(可选) |
3.2 应用切换检测
kotlin
// Android:Activity 生命周期
override fun onActivityPaused(activity: Activity) {
if (secured) channel?.invokeMethod("lock", null)
}
typescript
// OpenHarmony:窗口事件 + 应用生命周期(双重)
win.on('windowEvent', (eventType) => {
if (eventType === WINDOW_INACTIVE) { ... }
});
applicationContext.on('applicationStateChange', {
onApplicationBackground: () => { ... }
});
3.3 上下文获取
kotlin
// Android:需要 ActivityAware
class Plugin : FlutterPlugin, ActivityAware {
override fun onAttachedToActivity(binding: ActivityPluginBinding) {
activity = binding.activity
}
}
typescript
// OpenHarmony:不需要 AbilityAware
class Plugin implements FlutterPlugin {
onAttachedToEngine(binding: FlutterPluginBinding) {
this.context = binding.getApplicationContext();
}
}
四、iOS 的独特方案
4.1 原生模糊视图
iOS 是唯一需要创建原生 UI 元素来遮挡内容的平台:
swift
// 创建模糊视图
let blurEffect = UIBlurEffect(style: .light)
let blurView = UIVisualEffectView(effect: blurEffect)
blurView.frame = UIScreen.main.bounds
window.addSubview(blurView)
4.2 延迟移除机制
swift
// 回到前台后延迟移除
DispatchQueue.main.asyncAfter(deadline: .now() + 0.5) {
self.removeBlurView()
}
其他平台都不需要这个延迟。iOS 需要是因为原生模糊视图必须等 Flutter 渲染完成后才能移除,否则会短暂露出内容。
4.3 iOS 独有的问题
| 问题 | 原因 | 其他平台是否有 |
|---|---|---|
| 闪烁问题 | 原生遮罩移除和 Flutter 遮罩显示之间的间隙 | ❌ |
| 延迟参数调优 | nativeRemoveDelay 需要根据设备性能调整 | ❌ |
| 模糊样式选择 | light/dark/extraLight 等 | ❌ |
五、Web 平台的限制
5.1 可见性检测
dart
// Web 端实现
html.document.addEventListener('visibilitychange', (event) {
if (html.document.hidden ?? false) {
// 页面不可见 → 通知锁定
channel.invokeMethod('lock', null);
}
});
5.2 Web 平台的能力边界
| 能力 | 支持 | 说明 |
|---|---|---|
| 检测页面可见性 | ✅ | visibilitychange 事件 |
| 模糊遮罩 | ✅ | Flutter Web 的 BackdropFilter |
| 截屏防护 | ❌ | 浏览器无法阻止截屏 |
| 录屏防护 | ❌ | 浏览器无法阻止录屏 |
| 标签切换检测 | ✅ | visibilitychange |
| 浏览器最小化检测 | ✅ | visibilitychange |
5.3 Web 端的安全建议
Web 端无法提供真正的截屏防护,但可以:
- 使用 CSS
user-select: none防止文本选择 - 使用
pointer-events: none在锁定时禁止交互 - 在锁定时清除 DOM 中的敏感数据
📌 Web 端的保护更多是"防君子不防小人"------阻止普通用户的无意泄露,但无法阻止有意的截屏或审查元素。
六、Windows 平台的实现
6.1 检测机制
cpp
// Windows:监听窗口消息
case WM_SIZE:
if (wParam == SIZE_MINIMIZED) {
// 窗口最小化 → 通知锁定
}
break;
case WM_POWERBROADCAST:
if (wParam == PBT_APMSUSPEND) {
// 系统休眠 → 通知锁定
}
break;
6.2 Windows 的能力
| 能力 | 支持 | 说明 |
|---|---|---|
| 最小化检测 | ✅ | WM_SIZE 消息 |
| 锁屏检测 | ✅ | WM_POWERBROADCAST |
| 模糊遮罩 | ✅ | Flutter Desktop 的 BackdropFilter |
| 截屏防护 | ❌ | Windows 无法阻止截屏 |
| 录屏防护 | ❌ | Windows 无法阻止录屏 |
七、跨平台统一抽象
7.1 Dart 层的统一性
secure_application 的 Dart 层代码在所有平台上完全相同:
dart
// 这段代码在五个平台上行为一致
SecureApplication(
onNeedUnlock: (controller) async { ... },
child: SecureGate(
blurr: 20,
opacity: 0.6,
child: MyContent(),
),
)
7.2 平台差异的处理策略
| 策略 | 说明 | 示例 |
|---|---|---|
| 能力降级 | 不支持的功能静默忽略 | Web 端的 secure() 不做截屏防护 |
| 行为对齐 | 尽量保持一致的用户体验 | 所有平台都有模糊遮罩 |
| 平台检测 | 根据平台选择不同策略 | iOS 需要延迟移除原生遮罩 |
7.3 开发者需要注意的平台差异
dart
import 'dart:io' show Platform;
// 根据平台调整行为
if (Platform.isAndroid || Platform.isOhos) {
// 有系统级截屏防护,可以放心
} else if (Platform.isIOS) {
// 有遮挡但无截屏防护,考虑额外提示
} else {
// Web/Windows,保护有限,考虑是否需要额外措施
}
八、适配工作量对比
8.1 从零适配各平台的工作量
| 平台 | 工作量 | 主要工作 |
|---|---|---|
| Android | 1天 | FLAG_SECURE + ActivityAware |
| iOS | 2天 | UIVisualEffectView + 延迟移除 + 调优 |
| OpenHarmony | 2-3天 | Window API + 双重检测 + 错误处理 |
| Web | 0.5天 | visibilitychange 事件 |
| Windows | 1天 | 窗口消息处理 |
8.2 OpenHarmony 适配的额外工作
| 额外工作 | 原因 |
|---|---|
| 异步窗口获取 | getLastWindow 是异步的 |
| 双重检测机制 | 窗口事件 + 生命周期回调 |
| 错误处理 | BusinessError + Promise.catch |
| 环境搭建 | DevEco Studio + Flutter-OHOS SDK |
8.3 维护成本对比
| 平台 | 维护成本 | 原因 |
|---|---|---|
| Android | 低 | API 稳定,FLAG_SECURE 多年未变 |
| iOS | 中 | Apple 偶尔调整生命周期行为 |
| OpenHarmony | 中 | API 仍在演进,需要跟进 |
| Web | 低 | visibilitychange 是标准 API |
| Windows | 低 | Win32 消息机制非常稳定 |
总结
本文对五个平台的隐私保护机制做了全面对比:
- Android 和 OpenHarmony:系统级保护最强,能阻止截屏/录屏
- iOS:原生遮挡方案,效果好但无法阻止截屏
- Web:能力最弱,只能检测可见性变化
- Windows:可检测最小化和锁屏,无截屏防护
- Dart 层统一:所有平台共享相同的 Widget 和状态管理代码
下一篇我们讲错误处理与异常边界------原生端可能出现的各种错误以及如何优雅地处理。
如果这篇文章对你有帮助,欢迎点赞👍、收藏⭐、关注🔔,你的支持是我持续创作的动力!
相关资源: