'how to implement in app time out session in flutter

I want to log a user out after a specific amount time the user has not interacted with the app.

I've wrapped the whole child widget in GestureDetector().

Please suggest if this is the best optimised way of doing this.

class MyWidget extends StatelessWidget {
  @override
  Widget build(BuildContext context) {

    return new GestureDetector( 
    onTap: () {
      // duration reset's to a specific time 
      startTimeout([int milliseconds]) { return new Timer(duration, handleTimeout); } 
    },
    child: new HomeWidget(),); 
  }

  void handleTimeOut {
    // Log User Out
  }
}


Solution 1:[1]

You should cancel previous timers before initializing a new one

static Timer _sessionTimer;

@override
Widget build(BuildContext context) {
  ...
    onTap: () {
      _sessionTimer?.cancel();
      // duration reset's to a specific time 
      _sessionTimer = new Timer(duration, handleTimeout); 
    },

Solution 2:[2]

If you need something for the web target then better setup a key-up and a mouse-click listener on your index.html's 'body' as follows.

...
<body id = 'myapp-main-content'>
...

Then implement the listeners, here is an example borrowed from Task Tracker (https://github.com/botorabi/TaskTracker/tree/master/src/flutter-app/TaskTracker/lib).

import 'dart:async';
import 'dart:html';

import 'package:TaskTracker/service/authstatus.dart';
import 'package:flutter/material.dart';

import 'config.dart';
import 'navigation.links.dart';
import 'service/service.login.dart';

/// Logout user after long inactivity period.
class SessionTimeoutHandler {

  static const MAIN_CONTAINER_ID = 'myapp-main-content';

  final GlobalKey<NavigatorState> _navigator;
  Timer _sessionTimer;
  int   _timeoutInSeconds;

  static DateTime _timeLeft;

  SessionTimeoutHandler(this._navigator, this._timeoutInSeconds);

  void installLogoutHandler() {
    var body = document.getElementById(MAIN_CONTAINER_ID);
    body.addEventListener("click", (event) => resetLogoutTimer());
    body.addEventListener("keyup", (event) => resetLogoutTimer());

    resetLogoutTimer();
  }

  /// Return the time left to logout in seconds.
  /// If user is not authenticated then 0 is returned.
  static int timeLeftInSeconds() {
    if ((_timeLeft == null) || !Config.authStatus.authenticated) {
      return 0;
    }
    return ((DateTime.now().millisecondsSinceEpoch - _timeLeft.millisecondsSinceEpoch) / 1000).floor();
  }

  void resetLogoutTimer() {
    _timeLeft = DateTime.now();
    _sessionTimer?.cancel();
    _sessionTimer = Timer(Duration(seconds: _timeoutInSeconds), _logout);
  }

  void _logout() {
    if (Config.authStatus.authenticated) {
      ServiceLogin().logoutUser().then((result) {
        Config.authStatus = AuthStatus();
        _navigator.currentState.pushNamedAndRemoveUntil(
            NavigationLinks.NAV_HOME, (Route<dynamic> route) => false);
      });
    }
  }
}

Then use the SessionTimeoutHandler above in your main widget setup (see initState below).

class AppTaskTracker extends StatefulWidget {
  @override
  _AppTaskTrackerState createState() => _AppTaskTrackerState();
}

class _AppTaskTrackerState extends State<AppTaskTracker> {

  final GlobalKey<NavigatorState> _navigator = GlobalKey<NavigatorState>();

  @override
  void initState() {
    super.initState();
    SessionTimeoutHandler(_navigator, Config.LOGOUT_TIMEOUT).installLogoutHandler();
  }

  @override
  Widget build(BuildContext context) {
    return MaterialApp(
  ...

Take into account that SessionTimeoutHandler gets the navigator in order to redirect to home after automatic logout.

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1 Günter Zöchbauer
Solution 2 boto