3

I developed my app for Android using Java and now want to migrate to Flutter.

For detecting user inactivity I override this method in my Activity: onUserInteraction and reset a Timer, if there is no user interaction, I show a Screen Saver like Animation.

Is there Any clean way in Flutter to do this? I don't want to use platform channels. I want it pure Dart and flutter. I know I can set timer and reset it on user touch, but like in Android I want system to inform me about the user interaction.

Mneckoee
  • 2,802
  • 6
  • 23
  • 34
  • check [pointerRouter](https://api.flutter.dev/flutter/gestures/GestureBinding/pointerRouter.html) and call `addGlobalRoute` / `addRoute` so that you will be able to "catch" any pointer event from the device – pskink Feb 06 '21 at 05:56
  • Is `PointerRouter` catch all events including key, touch, or trackball? – Mneckoee Feb 07 '21 at 03:47
  • no, its for pointer events only, for key events, check `RawKeybord` class – pskink Feb 07 '21 at 06:56
  • Possible duplicate? https://stackoverflow.com/questions/58956814/how-to-execute-a-function-after-a-period-of-inactivity-in-flutter I'm about to test the solution in the link to see if it still works one year later – il_boga Apr 30 '21 at 13:29

2 Answers2

6

You can use wrap your MaterialApp in Listener. And reset a timer on interaction. Similar to what you are doing in android.

It only listens for gestures such as tap, drag, then released or canceled. It does not however listen to mouse events like hovering a region without pressing any buttons. For such events, use MouseRegion.

Sample code:

import 'package:flutter/material.dart';

final Color darkBlue = Color.fromARGB(255, 18, 32, 47);

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

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return Listener(
      onPointerDown: (_) => print('down'), // best place to reset timer imo
      onPointerMove: (_) => print('move'),
      onPointerUp: (_) => print('up'),
      child: MaterialApp(
        theme: ThemeData.dark().copyWith(scaffoldBackgroundColor: darkBlue),
        debugShowCheckedModeBanner: false,
        home: Scaffold(
          body: Center(
            child: MyWidget(),
          ),
        ),
      ),
    );
  }
}

class MyWidget extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return TextFormField(
      maxLength: 10,
      maxLengthEnforced: true,
      decoration: InputDecoration(
        border: OutlineInputBorder(),
        labelText: 'Details',
      ),
    );
  }
}
Vineet
  • 1,139
  • 1
  • 11
  • 20
  • thanks, but I want to catch all events like `onUserInteraction`. onUserInteraction() Called whenever a key, touch, or trackball event is dispatched to the activity – Mneckoee Feb 07 '21 at 03:46
0

All you need to do is to have access to the app's lifecycle. And a good way to do this is to use the mixin WidgetsBindingObserver on your LandingPage of the app.

The mixin provides you with an enum AppLifecycleState which can have 4 values, detached, inactive, paused and resumed which depicts the current state of the app.

You could, with this create a function e.g. didAppLifecycleChange which takes the state of the app. i.e. didAppLifecycleChange(AppLifecycleState state). You could then use these states to perform actions on the app.

IdrisAde
  • 11
  • 3
  • You could then write an if/else or switch/case function to perform specific actions depending on the state of the app – IdrisAde Jan 06 '22 at 01:28