Flutter屏幕隐私保护插件screen_privacy的使用

Flutter屏幕隐私保护插件screen_privacy的使用

该插件提供了在Android和iOS平台上防止截屏和隐藏应用程序内容的功能。这对于显示敏感信息或媒体内容的应用程序非常有用。

使用

安装

pubspec.yaml文件中添加screen_privacy作为依赖项。

dependencies:
  screen_privacy: ^x.x.x

然后运行flutter pub get以安装依赖项。

导入

import 'package:screen_privacy/screen_privacy.dart';

导入后,你可以在任何地方调用ScreenPrivacy类实例的方法。

细粒度截屏控制

  • 禁止截屏:
    ScreenPrivacy().disableScreenshot();
    
  • 启用截屏:
    ScreenPrivacy().enableScreenshot();
    

近期应用预览管理

  • 隐藏应用内容:
    ScreenPrivacy().enablePrivacyScreen();
    
  • 显示应用内容:
    ScreenPrivacy().disablePrivacyScreen();
    

使用案例:与AutoRoute结合

以下示例展示了如何在基于AutoRoute的应用程序中使用ScreenPrivacy插件,该应用程序使用了AutoTabsScaffoldBottomNavigationBar。该功能仅限于特定页面,并可以切换禁用/启用截屏和隐藏/显示近期应用预览的内容。一旦导航到其他页面或标签路由,此功能将停止工作。

限制到单个页面的示例代码

import 'dart:io';
import 'package:flutter/material.dart';
import 'package:auto_route/auto_route.dart';
import 'package:screen_privacy/screen_privacy.dart';

mixin ScreenPrivacyMixin<T extends StatefulWidget> on State<T> {
  TabsRouter? _watcher;
  AppLifecycleListener? _listener;
  VoidCallback? _navigationListener;
  bool _isNavigatedToDifferentTabRoute = false;
  bool _isIOSLifecycleUnblockedScreenshot = false;
  late final String _routeName;
  late final ScreenPrivacy _screenPrivacy;

  bool blockScreenshot();

  bool enablePrivacyScreen();

  [@override](/user/override)
  void initState() {
    super.initState();
    _screenPrivacy = ScreenPrivacy();
    _listener = Platform.isIOS && enablePrivacyScreen()
        ? AppLifecycleListener(onStateChange: _onLifecycleChanged)
        : null;

    WidgetsBinding.instance.addPostFrameCallback(_initializer);
  }

  void _initializer(Duration timeStamp) {
    _routeName = context.router.current.name;
    final shouldListenNavigation =
        blockScreenshot() || (Platform.isAndroid && enablePrivacyScreen());

    if (Platform.isAndroid) {
      if (enablePrivacyScreen()) {
        _screenPrivacy.enablePrivacyScreen();
      } else if (blockScreenshot()) {
        _screenPrivacy.disableScreenshot();
      }
    } else if (Platform.isIOS) {
      if (blockScreenshot()) {
        _screenPrivacy.disableScreenshot();
      }
    }
    _watcher = shouldListenNavigation == false
        ? null
        : (context.watchTabsRouter
      ..addListener(
        _navigationListener = () {
          if (context.tabsRouter.topRoute.name == _routeName) {
            if (_isNavigatedToDifferentTabRoute) {
              _screenPrivacy.disableScreenshot();
              _isNavigatedToDifferentTabRoute = false;
            }
          } else {
            if (!_isNavigatedToDifferentTabRoute) {
              _screenPrivacy.enableScreenshot();
              _isNavigatedToDifferentTabRoute = true;
            }
          }
        },
      ));
  }

  void _onLifecycleChanged(AppLifecycleState state) {
    switch (state) {
      case AppLifecycleState.resumed:
        _screenPrivacy.disablePrivacyScreen();
        if (_isIOSLifecycleUnblockedScreenshot) {
          _screenPrivacy.disableScreenshot();
          _isIOSLifecycleUnblockedScreenshot = false;
        }
        break;
      case AppLifecycleState.inactive:
        if (context.tabsRouter.topRoute.name == _routeName) {
          if (blockScreenshot()) {
            _screenPrivacy.enableScreenshot();
            _isIOSLifecycleUnblockedScreenshot = true;
          }
          _screenPrivacy.enablePrivacyScreen();
        }
        break;
      case AppLifecycleState.paused:
      case AppLifecycleState.detached:
      case AppLifecycleState.hidden:
        break;
    }
  }

  [@override](/user/override)
  void dispose() {
    if (Platform.isAndroid) {
      if (enablePrivacyScreen()) {
        _screenPrivacy.disablePrivacyScreen();
      } else if (blockScreenshot()) {
        _screenPrivacy.enableScreenshot();
      }
    } else if (Platform.isIOS) {
      if (blockScreenshot()) {
        _screenPrivacy.enableScreenshot();
      }
    }

    final mNavigationListener = _navigationListener;
    if (mNavigationListener != null) {
      _watcher?.removeListener(mNavigationListener);
    }
    _listener?.dispose();
    super.dispose();
  }
}

应用示例代码

import 'package:auto_route/auto_route.dart';
import 'package:flutter/material.dart';
import '../screen_privacy_helper.dart';
import '../../../../navigation/navigation.dart';

[@RoutePage](/user/RoutePage)()
class SensitiveDataPage extends StatefulWidget {
  const SensitiveDataPage({super.key});

  [@override](/user/override)
  State<SensitiveDataPage> createState() => _SensitiveDataPageState();
}

class _SensitiveDataPageState extends State<SensitiveDataPage> with ScreenPrivacyMixin<SensitiveDataPage> {
  [@override](/user/override)
  bool blockScreenshot() {
    return true;
  }

  [@override](/user/override)
  bool enablePrivacyScreen() {
    return true;
  }

  [@override](/user/override)
  Widget build(BuildContext context) {
    return const Scaffold(
      backgroundColor: Colors.blueGrey,
      body: Center(
        child: Image(
          image: NetworkImage(
            'https://images.unsplash.com/photo-1512850183-6d7990f42385?q=80&w=1974&auto=format&fit=crop&ixlib=rb-4.0.3&ixid=M3wxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8fA%3D%3D',
          ),
        ),
      ),
    );
  }
}

应用示例代码

import 'dart:io';
import 'package:flutter/material.dart';
import 'package:screen_privacy/screen_privacy.dart';

mixin ScreenPrivacyMixin<T extends StatefulWidget> on State<T> {
  AppLifecycleListener? _listener;
  late final ScreenPrivacy _screenPrivacy;
  bool _isIOSLifecycleUnblockedScreenshot = false;

  bool blockScreenshot();

  bool enablePrivacyScreen();

  [@override](/user/override)
  void initState() {
    super.initState();
    _screenPrivacy = ScreenPrivacy();
    _listener = Platform.isIOS && enablePrivacyScreen()
        ? AppLifecycleListener(onStateChange: _onLifecycleChanged)
        : null;

    WidgetsBinding.instance.addPostFrameCallback(_initializer);
  }

  void _initializer(Duration timeStamp) {
    if (Platform.isAndroid) {
      if (enablePrivacyScreen()) {
        _screenPrivacy.enablePrivacyScreen();
      } else if (blockScreenshot()) {
        _screenPrivacy.disableScreenshot();
      }
    } else if (Platform.isIOS) {
      if (blockScreenshot()) {
        _screenPrivacy.disableScreenshot();
      }
    }
  }

  void _onLifecycleChanged(AppLifecycleState state) {
    switch (state) {
      case AppLifecycleState.resumed:
        _screenPrivacy.disablePrivacyScreen();
        if (_isIOSLifecycleUnblockedScreenshot) {
          _screenPrivacy.disableScreenshot();
          _isIOSLifecycleUnblockedScreenshot = false;
        }
        break;
      case AppLifecycleState.inactive:
        if (blockScreenshot()) {
          _screenPrivacy.enableScreenshot();
          _isIOSLifecycleUnblockedScreenshot = true;
        }
        _screenPrivacy.enablePrivacyScreen();

        break;
      case AppLifecycleState.paused:
      case AppLifecycleState.detached:
      case AppLifecycleState.hidden:
        break;
    }
  }

  [@override](/user/override)
  void dispose() {
    if (Platform.isAndroid) {
      if (enablePrivacyScreen()) {
        _screenPrivacy.disablePrivacyScreen();
      } else if (blockScreenshot()) {
        _screenPrivacy.enableScreenshot();
      }
    } else if (Platform.isIOS) {
      if (blockScreenshot()) {
        _screenPrivacy.enableScreenshot();
      }
    }

    _listener?.dispose();
    super.dispose();
  }
}

应用示例代码

import 'package:auto_route/auto_route.dart';
import 'package:flutter/material.dart';
import '../screen_privacy_helper.dart';

[@RoutePage](/user/RoutePage)()
class MyApp extends AutoRouter {
  const MyApp({super.key});

  [@override](/user/override)
  State<MyApp> createState() => _MyAppState();
}

class _MyAppState extends State<MyApp> with ScreenPrivacyMixin {
  [@override](/user/override)
  bool blockScreenshot() {
    return true;
  }

  [@override](/user/override)
  bool enablePrivacyScreen() {
    return true;
  }

  [@override](/user/override)
  Widget build(BuildContext context) {
    return AutoTabsScaffold(
      homeIndex: 0,
      routes: const [],
      restorationId: 'AutoTabsScaffold',
      bottomNavigationBuilder: (context, tabsRouter) {
        return BottomNavigationBar(items: const []);
      },
    );
  }
}

更多关于Flutter屏幕隐私保护插件screen_privacy的使用的实战教程也可以访问 https://www.itying.com/category-92-b0.html

1 回复

更多关于Flutter屏幕隐私保护插件screen_privacy的使用的实战系列教程也可以访问 https://www.itying.com/category-92-b0.html


screen_privacy 是一个用于 Flutter 的插件,旨在帮助开发者在应用中实现屏幕隐私保护功能。例如,当应用进入后台或用户切换到其他应用时,可以模糊或隐藏敏感信息,以防止信息泄露。

以下是如何在 Flutter 项目中使用 screen_privacy 插件的基本步骤:

1. 添加依赖

首先,在 pubspec.yaml 文件中添加 screen_privacy 插件的依赖:

dependencies:
  flutter:
    sdk: flutter
  screen_privacy: ^1.0.0  # 请检查最新版本

然后运行 flutter pub get 来获取依赖。

2. 导入插件

在需要使用 screen_privacy 的 Dart 文件中导入插件:

import 'package:screen_privacy/screen_privacy.dart';

3. 初始化插件

main.dart 文件中初始化插件,并设置屏幕隐私保护的回调:

void main() {
  runApp(MyApp());

  // 初始化屏幕隐私保护
  ScreenPrivacy.initialize();
}

4. 设置屏幕隐私保护

在应用的生命周期中,可以使用 ScreenPrivacy 来启用或禁用屏幕隐私保护。例如,在应用进入后台时启用隐私保护,在应用回到前台时禁用隐私保护:

class MyApp extends StatefulWidget {
  @override
  _MyAppState createState() => _MyAppState();
}

class _MyAppState extends State<MyApp> with WidgetsBindingObserver {
  @override
  void initState() {
    super.initState();
    WidgetsBinding.instance.addObserver(this);
  }

  @override
  void dispose() {
    WidgetsBinding.instance.removeObserver(this);
    super.dispose();
  }

  @override
  void didChangeAppLifecycleState(AppLifecycleState state) {
    super.didChangeAppLifecycleState(state);

    if (state == AppLifecycleState.paused) {
      // 应用进入后台,启用屏幕隐私保护
      ScreenPrivacy.enablePrivacy();
    } else if (state == AppLifecycleState.resumed) {
      // 应用回到前台,禁用屏幕隐私保护
      ScreenPrivacy.disablePrivacy();
    }
  }

  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      home: Scaffold(
        appBar: AppBar(
          title: Text('Screen Privacy Example'),
        ),
        body: Center(
          child: Text('Sensitive Information'),
        ),
      ),
    );
  }
}

5. 自定义隐私保护视图

你可以自定义隐私保护视图,例如模糊效果、颜色覆盖等。screen_privacy 插件通常提供了一些默认的隐私保护效果,但你也可以根据需要自定义。

ScreenPrivacy.setPrivacyBuilder((context) {
  return Container(
    color: Colors.black,
    child: Center(
      child: Text(
        'Privacy Protected',
        style: TextStyle(color: Colors.white, fontSize: 24),
      ),
    ),
  );
});

6. 处理权限

在某些平台上,可能需要特定的权限来实现屏幕隐私保护。确保在 AndroidManifest.xmlInfo.plist 中配置必要的权限。

7. 测试

运行应用并测试屏幕隐私保护功能。当应用进入后台时,应该看到屏幕被模糊或隐藏,回到前台时恢复正常。

8. 处理异常

在实际使用中,可能会遇到一些异常情况,例如插件初始化失败、权限不足等。确保在代码中处理这些异常,并提供适当的用户反馈。

try {
  ScreenPrivacy.initialize();
} catch (e) {
  print('Failed to initialize screen privacy: $e');
}
回到顶部