Flutter应用配置防截屏规则后epub_viewer内仍可截屏,该如何处理?
问题根因
- epub_viewer 在安卓端会启动一个独立于主应用的新 Activity 渲染 Epub 内容,你为主 MainActivity 配置的
FLAG_SECURE仅作用于 Flutter 主页面所属的 Activity,无法覆盖这个插件新启动的页面,因此截屏限制失效。 - iOS 端同理,epub_viewer 会使用独立的
SFSafariViewController或者 WKWebView 容器渲染内容,默认不会继承 Flutter 主页面的安全配置。
安卓端解决方法
方法1:修改插件原生代码(适配性最高)
找到 pub 缓存中 epub_viewer 插件的安卓源码目录,定位到 EpubViewerActivity.java 文件,在其 onCreate 生命周期方法中添加安全标记:
@Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); // 新增下行代码,给当前 Activity 也添加禁止截屏标记 getWindow().setFlags(WindowManager.LayoutParams.FLAG_SECURE, WindowManager.LayoutParams.FLAG_SECURE); // 原有逻辑保留 }
如果不想修改缓存中的源码,可以将插件fork到本地修改后依赖本地版本,避免更新依赖时配置失效。
方法2:全局 Activity 生命周期监听(无需修改插件)
在你自己项目的主 Application 类中注册全局 Activity 生命周期回调,所有新启动的 Activity 都会自动添加禁止截屏标记:
public class CustomApplication extends FlutterApplication { @Override public void onCreate() { super.onCreate(); registerActivityLifecycleCallbacks(new ActivityLifecycleCallbacks() { @Override public void onActivityCreated(@NonNull Activity activity, @Nullable Bundle savedInstanceState) { activity.getWindow().setFlags(WindowManager.LayoutParams.FLAG_SECURE, WindowManager.LayoutParams.FLAG_SECURE); } // 其余生命周期方法保持空实现即可 @Override public void onActivityStarted(@NonNull Activity activity) {} @Override public void onActivityResumed(@NonNull Activity activity) {} @Override public void onActivityPaused(@NonNull Activity activity) {} @Override public void onActivityStopped(@NonNull Activity activity) {} @Override public void onActivitySaveInstanceState(@NonNull Activity activity, @NonNull Bundle outState) {} @Override public void onActivityDestroyed(@NonNull Activity activity) {} }); } }
修改完成后需要在 AndroidManifest.xml 中将 application 节点的 android:name 属性改为你自定义的 Application 类路径。
iOS 端解决方法
在 AppDelegate 的 didFinishLaunchingWithOptions 方法中添加全局屏幕捕获监听,检测到截屏/录屏操作时主动遮挡敏感内容:
override func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool { // 监听截屏通知 NotificationCenter.default.addObserver(forName: UIApplication.userDidTakeScreenshotNotification, object: nil, queue: .main) { _ in // 检测到截屏时可弹出提示或者遮挡当前页面 } // 监听录屏通知 NotificationCenter.default.addObserver(forName: UIScreen.capturedDidChangeNotification, object: nil, queue: .main) { _ in if UIScreen.main.isCaptured { // 检测到录屏时隐藏epub渲染页面 } } return super.application(application, didFinishLaunchingWithOptions: launchOptions) }
如果使用的是支持配置安全属性的 epub_viewer 衍生版本,也可以直接在 Dart 端调用打开 epub 的方法时传入对应的禁止截屏参数,无需修改原生代码。
内容的提问来源于stack exchange,提问作者Dhruvbhati
相关产品推荐
相关产品推荐

