import 'dart:async'; import 'dart:math'; import 'package:flutter/foundation.dart'; import 'package:sensors_plus/sensors_plus.dart'; import '../print.dart'; class EmergencySignalService { static final EmergencySignalService instance = EmergencySignalService._(); EmergencySignalService._(); StreamSubscription? _accelerometerSubscription; DateTime? _lastShakeTime; int _shakeCount = 0; // Custom thresholds for shaking (force required) final double _shakeThresholdGravity = 2.7; final int _shakeSlopTimeMs = 500; final int _shakeCountResetTimeMs = 3000; final int _targetShakes = 5; VoidCallback? _onEmergencyTriggered; /// Starts listening to phone movement void startListening(VoidCallback onEmergencyTriggered) { _onEmergencyTriggered = onEmergencyTriggered; if (_accelerometerSubscription != null) return; _accelerometerSubscription = accelerometerEvents.listen((event) { double x = event.x; double y = event.y; double z = event.z; // Calculate the gForce using pythagorean theorem double gX = x / 9.80665; double gY = y / 9.80665; double gZ = z / 9.80665; // Overall gForce double gForce = sqrt(gX * gX + gY * gY + gZ * gZ); if (gForce > _shakeThresholdGravity) { final now = DateTime.now(); // Ignore shakes that are too close to each other if (_lastShakeTime != null && now.difference(_lastShakeTime!).inMilliseconds < _shakeSlopTimeMs) { return; } // Reset the counter if elapsed more than the reset window if (_lastShakeTime != null && now.difference(_lastShakeTime!).inMilliseconds > _shakeCountResetTimeMs) { _shakeCount = 0; } _lastShakeTime = now; _shakeCount++; if (kDebugMode) { Log.print("🚨 Shake detected! Count: $_shakeCount"); } if (_shakeCount >= _targetShakes) { _shakeCount = 0; // Reset counter if (_onEmergencyTriggered != null) { _onEmergencyTriggered!(); } } } }); } void stopListening() { _accelerometerSubscription?.cancel(); _accelerometerSubscription = null; _shakeCount = 0; } }