import 'package:flutter/material.dart'; /// Locks once the app returns after being in the background for at least /// [gracePeriod], so a quick trip to the image picker or installer doesn't. class AppLifecycleLockObserver extends WidgetsBindingObserver { final VoidCallback onLock; final VoidCallback? onBackground; final VoidCallback? onForeground; final bool Function()? shouldLock; final Duration gracePeriod; final DateTime Function() _clock; DateTime? _backgroundedAt; AppLifecycleLockObserver({ required this.onLock, this.onBackground, this.onForeground, this.shouldLock, this.gracePeriod = const Duration(seconds: 30), DateTime Function()? clock, }) : _clock = clock ?? DateTime.now; @override void didChangeAppLifecycleState(AppLifecycleState state) { switch (state) { case AppLifecycleState.inactive: break; case AppLifecycleState.hidden: case AppLifecycleState.paused: case AppLifecycleState.detached: if (_backgroundedAt != null) return; _backgroundedAt = _clock(); onBackground?.call(); case AppLifecycleState.resumed: final backgroundedAt = _backgroundedAt; if (backgroundedAt == null) return; _backgroundedAt = null; final away = _clock().difference(backgroundedAt); if (away >= gracePeriod && (shouldLock?.call() ?? true)) onLock(); onForeground?.call(); } } }