Idle Activity Detector

A Flutter package for detecting user idle and activity states based on configurable timeouts and interaction monitoring.

pub package CI License: MIT Platform

Table of Contents

Features

  • Detect when user becomes idle after a period of inactivity
  • Detect when user becomes active again
  • Configurable idle timeout duration
  • Comprehensive interaction detection:
    • Mouse events: movement (mousemove), clicks (mousedown, click)
    • Keyboard events: input (keydown)
    • Scroll events: page scrolling (scroll)
    • Touch events: gestures (touchstart, touchmove)
    • Navigation events: route changes (optional)
    • Visibility events: tab focus/blur (optional)
    • Window events: focus/blur (optional)
  • State change callbacks for custom behavior
  • Optional controller for external state access
  • Zero external dependencies
  • Cross-platform support (Android, iOS, Web, Desktop)
  • Lightweight and efficient
  • Well-tested and documented

Installation

Add to your pubspec.yaml:

dependencies:
  idle_activity_detector: ^0.1.1-dev.2

Install:

flutter pub get

Import:

import 'package:idle_activity_detector/idle_activity_detector.dart';

Quick Start

Wrap your app with IdleActivityDetector:

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

void main() {
  runApp(
    IdleActivityDetector(
      config: IdleConfig(idleTimeout: Duration(minutes: 5)),
      onIdle: () => print('User is idle'),
      onActive: () => print('User is active'),
      child: MyApp(),
    ),
  );
}

API Reference

IdleActivityDetector

Main widget for monitoring user activity.

Properties:

Property Type Required Description
config IdleConfig Yes Configuration for idle detection
onIdle VoidCallback No Callback when user becomes idle
onActive VoidCallback No Callback when user becomes active
onStateChanged ValueChanged<ActivityState> No Callback for any state change
child Widget Yes Child widget to monitor

Example:

IdleActivityDetector(
  config: IdleConfig(idleTimeout: Duration(minutes: 5)),
  onIdle: () {
    print('User is idle');
  },
  onActive: () {
    print('User is active');
  },
  onStateChanged: (state) {
    print('State: ${state.name}');
  },
  child: MyApp(),
)

IdleConfig

Configuration class for idle detection behavior.

Properties:

Property Type Default Description
idleTimeout Duration 5 minutes Duration before considering user idle
detectMouse bool true Enable mouse movement detection
detectMouseClicks bool true Enable mouse click detection
detectKeyboard bool true Enable keyboard input detection
detectScroll bool true Enable scroll detection
detectTouch bool true Enable touch gesture detection
detectNavigation bool false Enable navigation detection
detectVisibility bool false Enable visibility detection
detectWindowFocus bool false Enable window focus detection

Example:

IdleConfig(
  idleTimeout: Duration(seconds: 30),
  detectMouse: true,
  detectMouseClicks: true,
  detectKeyboard: true,
  detectScroll: true,
  detectTouch: false,  // Disable for desktop-only
)

Methods:

// Create a copy with modified values
IdleConfig copyWith({
  Duration? idleTimeout,
  bool? detectTaps,
  bool? detectScrolls,
  bool? detectHover,
})

ActivityState

Enum representing user activity state.

Values:

  • ActivityState.active - User is actively interacting
  • ActivityState.idle - User has been inactive

Example:

void handleStateChange(ActivityState state) {
  switch (state) {
    case ActivityState.active:
      print('User is active');
      break;
    case ActivityState.idle:
      print('User is idle');
      break;
  }
}

Configuration

Basic Configuration

IdleConfig(
  idleTimeout: Duration(minutes: 5),
)

Advanced Configuration

IdleConfig(
  idleTimeout: Duration(seconds: 30),
  detectTaps: true,      // Monitor tap gestures
  detectScrolls: true,   // Monitor scroll gestures
  detectHover: false,    // Disable hover monitoring
)

Dynamic Configuration

// Update configuration at runtime
final config = IdleConfig(idleTimeout: Duration(minutes: 5));
final newConfig = config.copyWith(idleTimeout: Duration(minutes: 10));

Examples

Example 1: Auto-Logout

IdleActivityDetector(
  config: IdleConfig(idleTimeout: Duration(minutes: 15)),
  onIdle: () {
    // Logout user after 15 minutes of inactivity
    Navigator.pushReplacementNamed(context, '/login');
  },
  child: MyApp(),
)

Example 2: Session Timeout Warning

IdleActivityDetector(
  config: IdleConfig(idleTimeout: Duration(minutes: 10)),
  onIdle: () {
    showDialog(
      context: context,
      builder: (context) => AlertDialog(
        title: Text('Session Timeout'),
        content: Text('Your session will expire due to inactivity.'),
        actions: [
          TextButton(
            onPressed: () => Navigator.pop(context),
            child: Text('Continue'),
          ),
        ],
      ),
    );
  },
  child: MyApp(),
)

Example 3: Analytics Tracking

IdleActivityDetector(
  config: IdleConfig(idleTimeout: Duration(minutes: 5)),
  onStateChanged: (state) {
    // Track user engagement patterns
    analytics.logEvent(
      name: 'user_activity_state',
      parameters: {
        'state': state.name,
        'timestamp': DateTime.now().toIso8601String(),
      },
    );
  },
  child: MyApp(),
)

// Firebase Analytics example
import 'package:firebase_analytics/firebase_analytics.dart';

final analytics = FirebaseAnalytics.instance;

IdleActivityDetector(
  config: IdleConfig(idleTimeout: Duration(minutes: 5)),
  onIdle: () {
    analytics.logEvent(name: 'user_idle');
  },
  onActive: () {
    analytics.logEvent(name: 'user_active');
  },
  onStateChanged: (state) {
    analytics.setUserProperty(
      name: 'activity_state',
      value: state.name,
    );
  },
  child: MyApp(),
)

Example 4: Power Saving Mode

class MyApp extends StatefulWidget {
  @override
  State<MyApp> createState() => _MyAppState();
}

class _MyAppState extends State<MyApp> {
  Timer? _updateTimer;

  void _startUpdates() {
    _updateTimer = Timer.periodic(Duration(seconds: 1), (timer) {
      // Regular updates
    });
  }

  void _stopUpdates() {
    _updateTimer?.cancel();
  }

  @override
  Widget build(BuildContext context) {
    return IdleActivityDetector(
      config: IdleConfig(idleTimeout: Duration(minutes: 2)),
      onIdle: _stopUpdates,
      onActive: _startUpdates,
      child: MaterialApp(home: HomePage()),
    );
  }
}

Example 5: Tap-Only Detection

IdleActivityDetector(
  config: IdleConfig(
    idleTimeout: Duration(minutes: 3),
    detectTaps: true,
    detectScrolls: false,  // Ignore scrolling
    detectHover: false,     // Ignore hover
  ),
  onIdle: () => print('No taps for 3 minutes'),
  child: MyApp(),
)

Use Cases

Authentication & Security:

  • Auto-logout after inactivity
  • Session timeout management
  • Security lock screens
  • Re-authentication prompts

User Experience:

  • Pause video/audio during idle
  • Show/hide UI elements based on activity
  • Screen dimming or sleep mode
  • Tutorial/help triggers

Analytics & Monitoring:

  • User engagement tracking
  • Session duration analytics
  • Activity pattern analysis
  • Usage statistics

Performance & Battery:

  • Reduce update frequency when idle
  • Stop animations during inactivity
  • Pause background tasks
  • Battery optimization

Platform Support

Platform Status Notes
Android Supported Full support
iOS Supported Full support
Web Supported Full support
Windows Supported Full support
macOS Supported Full support
Linux Supported Full support

Documentation

Development

This project includes a comprehensive Makefile for common development tasks.

Quick Commands:

make help           # Show all available commands
make dev            # Setup development environment
make pre-commit     # Run all pre-commit checks
make test           # Run tests
make run            # Run example app

Full documentation: https://github.com/alpinnz/idle_activity_detector/blob/main/MAKEFILE.md

Contributing

Contributions are welcome! Please read our Contributing Guide for details on:

  • Development workflow
  • Commit message convention
  • Pull request process
  • Coding standards
  • Testing guidelines

Quick Start:

# Fork and clone the repository
git clone https://github.com/YOUR_USERNAME/idle_activity_detector.git

# Setup environment
make dev

# Create a branch
git checkout -b feat/your-feature

# Make changes and test
make pre-commit

# Commit using conventional commits
git commit -m "feat(detector): add new feature"

# Push and create PR
git push origin feat/your-feature

Reporting Issues:

Report bugs or request features at: https://github.com/alpinnz/idle_activity_detector/issues

License

This project is licensed under the MIT License.

Full license text: https://github.com/alpinnz/idle_activity_detector/blob/main/LICENSE

Copyright (c) 2025 Alpinnz

Author

Created and maintained by Alpinnz.

For questions or support, please visit: https://github.com/alpinnz/idle_activity_detector

Version

Current version: 0.0.1

See full changelog at: https://github.com/alpinnz/idle_activity_detector/blob/main/CHANGELOG.md