Flutter安全应用切换插件secure_app_switcher的使用

Flutter安全应用切换插件secure_app_switcher的使用

secure_app_switcher 插件可以在应用程序切换器或任务列表上为应用屏幕应用一个安全遮罩效果。这些功能可以在任意过程中启用或禁用,并且还提供了基于屏幕切换的功能。

使用方法

在任意处理中使用功能

import 'package:secure_app_switcher/secure_app_switcher.dart';

// 开启功能
SecureAppSwitcher.on();

// 关闭功能
SecureAppSwitcher.off();

在特定屏幕上使用功能

为了在屏幕切换时切换功能,需要设置 secureAppSwitcherRouteObserver。将目标屏幕包装在 MaterialPageRouteSecureAppSwitcherPage 中。

  • 设置 secureAppSwitcherRouteObserver
[@override](/user/override)
Widget build(BuildContext context) {
  return MaterialApp(
    title: 'Secure App Switcher',
    onGenerateRoute: generateRoute,
    navigatorObservers: [secureAppSwitcherRouteObserver], // 添加
    initialRoute: '/',
  );
}
  • 使用 SecureAppSwitcherPage, MaterialPageRoute
Route<dynamic> generateRoute(RouteSettings settings) {
  switch (settings.name) {
    case "/":
      return MaterialPageRoute(builder: (context) {
        return const HomeScreen();
      });    
    case "/screenA":
      return MaterialPageRoute(builder: (context) {
        return const SecureAppSwitcherPage( // 添加
          style: SecureMaskStyle.dark,
          child: ScreenA(),
        );
      });
  }
}

iOS

对于iOS,可以指定遮罩效果的类型。

SecureAppSwitcher.on(iosStyle: SecureMaskStyle.blurLight);
  • 遮罩效果的类型
Light Dark BlurLight BlurDark

Android

在Android中,使用WindowManager.LayoutParams.FLAG_SECURE

  • 应用切换和截图禁用
应用切换 截图禁用
  • 特点:
    • 无法像iOS那样指定遮罩效果。
    • 在Android 11及更高版本中,启用该功能后需要切换其他应用一次才能使遮罩效果生效。
    • 启用功能后不允许截屏。

完整示例代码

import 'package:flutter/material.dart';
import 'package:secure_app_switcher/secure_app_switcher.dart';

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

class MyApp extends StatelessWidget {
  const MyApp({super.key});

  [@override](/user/override)
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Secure App Switcher',
      onGenerateRoute: generateRoute,
      navigatorObservers: [secureAppSwitcherRouteObserver],
      initialRoute: '/',
    );
  }
}

Route<dynamic> generateRoute(RouteSettings settings) {
  switch (settings.name) {
    case "/":
      return MaterialPageRoute(builder: (context) {
        return const HomeScreen();
      });
    case "/screen_a":
      return MaterialPageRoute(builder: (context) {
        return const ScreenA();
      });
    case "/screen_b":
      return MaterialPageRoute(builder: (context) {
        return const SecureAppSwitcherPage(
          style: SecureMaskStyle.blurLight,
          child: ScreenB(),
        );
      });

    case "/screen_c":
      return MaterialPageRoute(builder: (context) {
        return const SecureAppSwitcherPage(
          style: SecureMaskStyle.blurDark,
          child: ScreenC(),
        );
      });
    case "/screen_d":
      return MaterialPageRoute(builder: (context) {
        return const SecureAppSwitcherPage(
          style: SecureMaskStyle.dark,
          child: ScreenD(),
        );
      });
    default:
      return MaterialPageRoute(builder: (context) {
        return const HomeScreen();
      });
  }
}

/// -------------------------------------------------------------------------------

class HomeScreen extends StatefulWidget {
  const HomeScreen({super.key});

  [@override](/user/override)
  State<HomeScreen> createState() => _HomeScreenState();
}

class _HomeScreenState extends State<HomeScreen> {
  bool _secureEnable = false;

  [@override](/user/override)
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: const Text('Plugin example app'),
      ),
      body: Padding(
        padding: const EdgeInsets.all(20.0),
        child: Column(
          spacing: 10,
          children: [
            Text('任意处理',
                style: Theme.of(context).textTheme.titleLarge),
            Padding(
              padding: const EdgeInsets.all(8.0),
              child: Row(
                mainAxisAlignment: MainAxisAlignment.spaceBetween,
                children: [
                  const Text('SecureAppSwitcher'),
                  Switch(
                    value: _secureEnable,
                    onChanged: (value) {
                      setState(() {
                        _secureEnable = value;
                        if (value) {
                          SecureAppSwitcher.on();
                        } else {
                          SecureAppSwitcher.off();
                        }
                      });
                    },
                  ),
                ],
              ),
            ),
            const Divider(),
            Text('特定屏幕',
                style: Theme.of(context).textTheme.titleLarge),
            Column(
              crossAxisAlignment: CrossAxisAlignment.stretch,
              spacing: 20,
              children: [
                ElevatedButton(
                  onPressed: () {
                    setState(() {
                      _secureEnable = false;
                      SecureAppSwitcher.off();
                    });
                    Navigator.of(context).pushNamed("/screen_a");
                  },
                  child: Column(
                    children: [
                      Text(
                        'Screen A',
                        style: Theme.of(context).textTheme.titleMedium,
                      ),
                      const Text('SecureAppSwitcher : off'),
                    ],
                  ),
                ),
              ],
            ),
          ],
        ),
      ),
    );
  }
}

class ScreenA extends StatelessWidget {
  const ScreenA({super.key});

  [@override](/user/override)
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: const Text('Screen A'),
      ),
      body: Center(
        child: Column(
          mainAxisAlignment: MainAxisAlignment.spaceEvenly,
          crossAxisAlignment: CrossAxisAlignment.center,
          children: [
            Text('SecureAppSwitcher : off',
                style: Theme.of(context).textTheme.bodyLarge),
            ElevatedButton(
              onPressed: () {
                Navigator.of(context).pushNamed("/screen_b");
              },
              child: Column(
                children: [
                  Text(
                    'Screen B',
                    style: Theme.of(context).textTheme.titleMedium,
                  ),
                  const Text('SecureAppSwitcher : on'),
                  const Text('SecureMaskStyle : blurLight (仅限iOS)'),
                ],
              ),
            ),
          ],
        ),
      ),
    );
  }
}

class ScreenB extends StatelessWidget {
  const ScreenB({super.key});

  [@override](/user/override)
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: const Text('Screen B'),
      ),
      body: Center(
        child: Column(
          mainAxisAlignment: MainAxisAlignment.spaceEvenly,
          crossAxisAlignment: CrossAxisAlignment.center,
          children: [
            Column(
              children: [
                Text('SecureAppSwitcher : on',
                    style: Theme.of(context).textTheme.bodyLarge),
                Text('SecureMaskStyle : blurLight (仅限iOS)',
                    style: Theme.of(context).textTheme.bodyLarge),
              ],
            ),
            ElevatedButton(
              onPressed: () {
                Navigator.of(context).pushNamed("/screen_c");
              },
              child: Column(
                children: [
                  Text(
                    'Screen C',
                    style: Theme.of(context).textTheme.titleMedium,
                  ),
                  const Text('SecureAppSwitcher : on'),
                  const Text('SecureMaskStyle : blurDark (仅限iOS)'),
                ],
              ),
            ),
          ],
        ),
      ),
    );
  }
}

class ScreenC extends StatelessWidget {
  const ScreenC({super.key});

  [@override](/user/override)
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: const Text('Screen C'),
      ),
      body: Center(
        child: Column(
          mainAxisAlignment: MainAxisAlignment.spaceEvenly,
          crossAxisAlignment: CrossAxisAlignment.center,
          children: [
            Column(
              children: [
                Text('SecureAppSwitcher : on',
                    style: Theme.of(context).textTheme.bodyLarge),
                Text('SecureMaskStyle : blurDark (仅限iOS)',
                    style: Theme.of(context).textTheme.bodyLarge),
              ],
            ),
            ElevatedButton(
              onPressed: () {
                showModalBottomSheet(
                  context: context,
                  builder: (context) => Navigator(
                    onGenerateRoute: (context) =>
                        generateRoute(const RouteSettings(name: '/screen_d')),
                  ),
                );
              },
              child: Column(
                children: [
                  Text(
                    'Modal Screen D',
                    style: Theme.of(context).textTheme.titleMedium,
                  ),
                  const Text('SecureAppSwitcher : on'),
                  const Text('SecureMaskStyle : dark (仅限iOS)'),
                ],
              ),
            )
          ],
        ),
      ),
    );
  }
}

class ScreenD extends StatelessWidget {
  const ScreenD({super.key});

  [@override](/user/override)
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: const Text('Screen D'),
        leading: IconButton(
          onPressed: () => Navigator.of(context, rootNavigator: true).pop(),
          icon: const Icon(Icons.close),
        ),
      ),
      body: Center(
        child: Column(
          mainAxisAlignment: MainAxisAlignment.center,
          crossAxisAlignment: CrossAxisAlignment.center,
          children: [
            Text('SecureAppSwitcher : on',
                style: Theme.of(context).textTheme.bodyLarge),
            Text('SecureMaskStyle : dark (仅限iOS)',
                style: Theme.of(context).textTheme.bodyLarge),
          ],
        ),
      ),
    );
  }
}

更多关于Flutter安全应用切换插件secure_app_switcher的使用的实战教程也可以访问 https://www.itying.com/category-92-b0.html

1 回复

更多关于Flutter安全应用切换插件secure_app_switcher的使用的实战系列教程也可以访问 https://www.itying.com/category-92-b0.html


当然,以下是如何在Flutter应用中使用secure_app_switcher插件的示例代码。这个插件允许应用在切换到后台时执行一些安全措施,例如清除敏感数据。

首先,确保你的Flutter项目已经添加了secure_app_switcher依赖。在pubspec.yaml文件中添加以下依赖:

dependencies:
  flutter:
    sdk: flutter
  secure_app_switcher: ^x.y.z  # 请替换为最新版本号

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

接下来,在你的Flutter应用中,你可以按照以下步骤使用secure_app_switcher插件:

  1. 导入插件

    在你的Dart文件中导入secure_app_switcher插件。

    import 'package:secure_app_switcher/secure_app_switcher.dart';
    
  2. 初始化插件并设置监听器

    你需要在应用启动时初始化插件,并设置一个监听器来处理应用切换到后台的事件。这通常在MaterialAppCupertinoAppbuilder方法中进行。

    void main() {
      runApp(MyApp());
    }
    
    class MyApp extends StatelessWidget {
      @override
      Widget build(BuildContext context) {
        return SecureAppSwitcher(
          onAppInactive: _handleAppInactive,
          child: MaterialApp(
            title: 'Flutter Demo',
            theme: ThemeData(
              primarySwatch: Colors.blue,
            ),
            home: MyHomePage(),
          ),
        );
      }
    
      void _handleAppInactive() {
        // 在这里执行你的安全措施,例如清除敏感数据
        print('App is going to inactive state, clearing sensitive data...');
        // 例如,清除一个保存敏感信息的变量
        // sensitiveData = null;
      }
    }
    
    class MyHomePage extends StatelessWidget {
      @override
      Widget build(BuildContext context) {
        return Scaffold(
          appBar: AppBar(
            title: Text('Flutter Demo Home Page'),
          ),
          body: Center(
            child: Text('Hello, Flutter!'),
          ),
        );
      }
    }
    

在上面的代码中,我们创建了一个MyApp类,它使用SecureAppSwitcher作为根小部件。SecureAppSwitcher接受一个onAppInactive回调,当应用切换到后台时,这个回调将被调用。在回调中,你可以执行任何必要的安全措施,例如清除敏感数据。

请注意,实际的安全措施将取决于你的应用需求。上面的示例只是打印了一条消息,但在实际应用中,你可能会清除内存中的敏感信息、注销用户会话或执行其他安全操作。

希望这个示例代码能帮助你理解如何在Flutter应用中使用secure_app_switcher插件。如果你有任何其他问题,欢迎继续提问!

回到顶部