我需要创建一个应用程序,导航到一个用户后,一段时间的不活动.

我try 将我的应用程序包装在GestureDetector中,并在指定的时间段后运行计时器,如下所示,但它不起作用:

class _MyAppState extends State<MyApp> {
  Timer _timer;

  @override
  void initState() {
    super.initState();

    _initializeTimer();
  }

  void _initializeTimer() {
    _timer = Timer.periodic(const Duration(seconds: 20), (_) => _logOutUser);
  }

  void _logOutUser() {
Navigator.push(
        context,
        MaterialPageRoute(
            builder: (context) => WelcomePage()));
    _timer.cancel();
  }

  void _handleUserInteraction([_]) {
    if (!_timer.isActive) {
      return;
    }

    _timer.cancel();
    _initializeTimer();
  }

  @override
  Widget build(BuildContext context) {
    return GestureDetector(
      onTap: _handleUserInteraction,
      onPanDown: _handleUserInteraction,
      child: MaterialApp(
        title: 'Hello',
        home: WelcomePage(),
        routes: <String, WidgetBuilder>{
          '/welcome': (BuildContext context) => new WelcomePage(),
          '/login': (BuildContext context) => new LoginPage(),
        },
        debugShowCheckedModeBanner: false,
      ),
    );
  }
}

我的问题是,在一段时间的不活动之后,我应该如何最好地实现在Ffltter应用程序中运行函数?

推荐答案

FWIW,我按照建议try 了使用GestureDetector,但它并没有像预期的那样工作.问题是,当没有活动时,我会收到源源不断的手势.这包括当我try 更严格的ONTAP:Callback时.

我在模拟器的调试模式下看到了这一点.我没有做进一步的实验来观察真正的手机是否表现出同样的行为,因为即使它们现在没有表现出同样的行为,它们在future 也可能表现出同样的行为:显然没有任何规范保证手势检测器won't会接收到虚假事件.对于与安全相关的东西,比如不活动超时,这是不可接受的.

对于我的用例,我决定可以改为检测应用程序何时超过设定的时间不可见.我对我的预期使用的理由是,真正的危险是当应用程序不可见时,他们会忘记它在那里.

设置这种非活动超时相当容易.我安排在应用程序获得访问敏感信息的权限时(例如,在输入密码后)拨打startKeepAlive().就我的使用而言,在超时后直接退出应用程序是可以的;显然,如果需要的话,可以变得更复杂.总之,这是相关的代码:

const _inactivityTimeout = Duration(seconds: 10);
Timer _keepAliveTimer;

void _keepAlive(bool visible) {
  _keepAliveTimer?.cancel();
  if (visible) {
    _keepAliveTimer = null;
  } else {
    _keepAliveTimer = Timer(_inactivityTimeout, () => exit(0));
  }
}

class _KeepAliveObserver extends WidgetsBindingObserver {
  @override didChangeAppLifecycleState(AppLifecycleState state) {
    switch(state) {
      case AppLifecycleState.resumed:
        _keepAlive(true);
        break;
      case AppLifecycleState.inactive:
      case AppLifecycleState.paused:
      case AppLifecycleState.detached:
        _keepAlive(false);  // Conservatively set a timer on all three
        break;
    }
  }
}

/// Must be called only when app is visible, and exactly once
void startKeepAlive() {
  assert(_keepAliveTimer == null);
  _keepAlive(true);
  WidgetsBinding.instance.addObserver(_KeepAliveObserver());
}

在生产中,我可能会延长超时时间:-)

Flutter相关问答推荐

未处理异常:字符串类型不是值类型子类型的子类型'

下拉图标未居中

允许冻结在初始化时使用工厂

如何在用Ffltter成功登录后重定向下一页?

BlocBuilder仅生成一次,并在后续发出时停止重建

在LinkedIn上分享Fighter和Web的链接会产生不同的结果

Flutter-Riverpod:如何只从提供者读取一次值

没有为类型 'Widget' 定义运算符 '[]' .try 定义运算符[]

我无法找到修复此错误的位置,指出无法使用静态访问来访问实例成员

显示图像的放大部分

在参数为空时保持命名参数的默认值

网页浏览器不支持鼠标滚动的行项目

Flutter Firebase 升级后出现问题? ARC 语义问题 (Xcode): Select 器appleCredentialWithIDToken:rawNonce:fullName:没有已知的类方法

使用堆栈的自定义按钮

Flutter blue plus 库,当try 从 esp32 驱动程序获取 PlatformException 时读取特性

Flutter - 展开图标无法正常工作

setState 方法有时有效,有时无效

为什么 ref.watch(otherProvider.stream) 在 Riverpod 2.x 中被弃用并且将在 3.x 中被删除?

底部工作表顶部的一块 Flutter

如何在 Flutter 中将 ScaffoldMessenger 中的 Snackbar 显示为 Widget?