You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.09.26 00:54:05