Действовать, когда пользователь не взаимодействует - PullRequest
0 голосов
/ 30 апреля 2020

Моя проблема заключается в следующем: иногда мои пользователи не взаимодействуют или не делают никаких событий, поэтому для их защиты я должен выйти из системы, потому что у пользователя есть конфиденциальные данные.

Есть ли какая-нибудь функция от флаттера, делающая то же самое?

Вывод: если пользователь откроет мое приложение и оставит приложение открытым без каких-либо действий или по какой-либо причине, я хочу, чтобы приложение считало 5 минут, если пользователь не взаимодействует, приложение должно выполнить некоторые действия.

Я проверил AppLifecycleState, но в моем случае это не помогает. AppLifecycleState работает, если приложение работает в фоновом режиме или снова открывается.

Ответы [ 2 ]

0 голосов
/ 30 апреля 2020

Вот минимальный рабочий пример, который я написал для этого случая без какого-либо управления состоянием, вы можете попробовать его в dartpad . Вы выйдете из системы, если пользователь простаивает через 5 секунд.

// Copyright (c) 2019, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.
import 'dart:async';
import 'package:flutter/material.dart';

void main() => runApp(MyApp());

class MyApp extends StatefulWidget {
  MyApp({Key key}) : super(key: key);

  @override
  _MyAppState createState() => _MyAppState();
}

class _MyAppState extends State<MyApp> {
  LogoutTimerModel timerModel;
  Timer logoutTimer;

  int page = 1; // you could use enum
  @override
  void initState() {
    super.initState();
    timerModel = LogoutTimerModel();
    timerModel.updateTimestamp(DateTime.now());
    logoutTimer = Timer.periodic(Duration(seconds: 1), (time) {
      DateTime currentTime = DateTime.now();
      if(currentTime.difference(timerModel.timestamp).inSeconds > 5) {
        setState((){
          page = 0;
        });
      }
    });
  }

  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Flutter Demo',
      debugShowCheckedModeBanner: false,
      theme: ThemeData(
        primarySwatch: Colors.blue,
      ),
      home: Listener(
        onPointerDown: (PointerEvent details) {
          timerModel.updateTimestamp(DateTime.now());
        },
        child: Builder(
          builder: (context) {
            if(page == 1)
              return LoginPage();
            else
              return LogoutPage();
          }
        )
      )
    );
  }
}

class LoginPage extends StatelessWidget {
  Widget build(BuildContext context) {
    return Scaffold(
      body: Center(
        child: Text("Login now, but wait for timeout to logout...")
      ),
    );
  }
}

class LogoutPage extends StatelessWidget {
  Widget build(BuildContext context) {
    return Scaffold(
      body: Center(
        child: Text("Logout now")
      ),
    );
  }
}

class LogoutTimerModel {
  DateTime timestamp;

  void updateTimestamp(DateTime timestamp) {
    this.timestamp = timestamp;
  }
}

Поскольку ваш случай выглядит как глобальная операция, вы должны сделать это в MyApp и обернуть его Listener, чтобы сбросить отметку времени вот и все понятия.

Редактировать: Для тех, кто думает, что слушатель будет поглощен обычным событием нажатия кнопки, вот тест:

// Copyright (c) 2019, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.
import 'dart:async';
import 'package:flutter/material.dart';

void main() => runApp(MyApp());

class MyApp extends StatefulWidget {
  MyApp({Key key}) : super(key: key);

  @override
  _MyAppState createState() => _MyAppState();
}

class _MyAppState extends State<MyApp> {
  LogoutTimerModel timerModel;
  Timer logoutTimer;

  int page = 1; // you could use enum
  @override
  void initState() {
    super.initState();
    timerModel = LogoutTimerModel();
    timerModel.updateTimestamp(DateTime.now());
    logoutTimer = Timer.periodic(Duration(seconds: 1), (time) {
      DateTime currentTime = DateTime.now();
      if(currentTime.difference(timerModel.timestamp).inSeconds > 5) {
        setState((){
          page = 0;
        });
      }
    });
  }

  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Flutter Demo',
      debugShowCheckedModeBanner: false,
      theme: ThemeData(
        primarySwatch: Colors.blue,
      ),
      home: Listener(
        onPointerDown: (PointerEvent details) {
          timerModel.updateTimestamp(DateTime.now());
          print("Omitted??");
        },
        child: Builder(
          builder: (context) {
            if(page == 1)
              return LoginPage();
            else
              return LogoutPage();
          }
        )
      )
    );
  }
}

class LoginPage extends StatelessWidget {
  Widget build(BuildContext context) {
    return Scaffold(
      body: Center(
        child: Column(
          children: [
            Text("Login now, but wait for timeout to logout..."),
            FlatButton(
              child: Text("case"),
              onPressed: () {
                print("Omit???");
              }
            )
          ]
        )
      ),
    );
  }
}

class LogoutPage extends StatelessWidget {
  Widget build(BuildContext context) {
    return Scaffold(
      body: Center(
        child: Text("Logout now")
      ),
    );
  }
}

class LogoutTimerModel {
  DateTime timestamp;

  void updateTimestamp(DateTime timestamp) {
    this.timestamp = timestamp;
  }
}

Результат:

Omitted??
Omit???
Omitted??
Omit???
Omitted??
Omit???
Omitted??
Omit???
Omitted??
Omit???
Omitted??
Omit???
Omitted??
Omit???

Кстати, я не тестировал код всеми способами, поэтому, если кто-то найдет что-то, что может повлиять на Listener, не стесняйтесь комментировать, чтобы помочь другим.

Примечание: Возможно, вы захотите пройти как showDialog, вы можете обернуть Listener выше MaterialApp в зависимости от требования.

Listener(child: MaterailApp ...
0 голосов
/ 30 апреля 2020

Вы можете использовать Таймер, чтобы сделать что-то подобное.

Если пользователь не нажмет кнопку, то через 5 минут он напечатает что-то в журнале, а если пользователь щелкнет до этого, он ничего не сделает.

Timer timer;
  @override
  void initState() {
    super.initState();
    timer = Timer.periodic(Duration(minutes: 5), (time) {
      print('Something');
    });
  }

 @override
  void dispose() {
    timer.cancel();
    super.dispose();
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      body: Center(
        child: RaisedButton(
          child: Text("press"),
          onPressed: () {
            timer.cancel();
          },
        ),
      ),
    );
  }
...