Flutter Connectivity Manager

A comprehensive Flutter package for monitoring and managing network connectivity with advanced features like internet access verification, connection speed detection, and flexible configuration options.

๐ŸŒŸ Features

  • ๐Ÿ”„ Real-time Connectivity Monitoring: Stream-based architecture for reactive connectivity updates
  • ๐ŸŒ Internet Access Verification: Not just network connection - actual internet accessibility testing
  • โšก Enhanced Connection Speed Detection: Comprehensive speed classification from poor to excellent with 8 speed levels
  • ๐Ÿ“ก Multiple Connection Types: Support for WiFi, Mobile, Ethernet, Bluetooth, and VPN connections
  • โš™๏ธ Flexible Configuration: Customizable timeouts, retry attempts, test URLs, and monitoring intervals
  • ๐Ÿญ Factory-Based Initialization: Proper async initialization with predefined configuration presets
  • ๐Ÿ”‹ Background Monitoring: Optional background checks with configurable intervals for battery efficiency
  • ๐Ÿ’พ State Caching: Performance optimization with intelligent connection state caching
  • ๐ŸŽฏ Advanced Testing: Ping tests, URL reachability checks, and bandwidth capability assessment
  • โณ Connection Waiting: Wait for specific connection types or internet availability with timeout support
  • ๐Ÿ›ก๏ธ Enhanced Error Handling: Comprehensive error handling with detailed error information and stack traces
  • ๐Ÿ”ง Resource Management: Proper lifecycle management with pause/resume/dispose methods

๐Ÿ“ฑ Supported Platforms

  • โœ… Android (API 16+)
  • โœ… iOS (iOS 12.0+)
  • โœ… macOS (macOS 10.14+)
  • โœ… Windows (Windows 10+)
  • โœ… Linux
  • โœ… Web

๐Ÿš€ Getting Started

Installation

Add flutter_connectivity_manager to your pubspec.yaml:

dependencies:
  flutter_connectivity_manager: ^1.0.3

Then run:

flutter pub get

Basic Usage

import 'package:flutter_connectivity_manager/flutter_connectivity_manager.dart';

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

class _MyAppState extends State<MyApp> {
  late IConnectivityManager _connectivityManager;
  ConnectivityState _currentState = ConnectivityState.noConnection();

  @override
  void initState() {
    super.initState();
    _initializeConnectivity();
  }

  Future<void> _initializeConnectivity() async {
    // Create connectivity manager using factory (required for v1.0.3+)
    _connectivityManager = await ConnectivityManagerFactory.createForProduction();

    // Start monitoring
    await _connectivityManager.startMonitoring();

    // Listen to connectivity changes
    _connectivityManager.onConnectivityChanged.listen((state) {
      setState(() {
        _currentState = state;
      });

      if (state.isConnected) {
        print('Connected via ${state.primaryConnectionType}');
        print('Connection speed: ${state.connectionSpeed.description}');
      } else {
        print('Disconnected');
      }
    });
  }

  @override
  void dispose() {
    _connectivityManager.dispose();
    super.dispose();
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text('Connectivity Status'),
        backgroundColor: _currentState.isConnected ? Colors.green : Colors.red,
      ),
      body: Center(
        child: Column(
          mainAxisAlignment: MainAxisAlignment.center,
          children: [
            Icon(
              _currentState.isConnected ? Icons.wifi : Icons.wifi_off,
              size: 64,
              color: _currentState.isConnected ? Colors.green : Colors.red,
            ),
            SizedBox(height: 16),
            Text(
              _currentState.isConnected ? 'Connected' : 'Disconnected',
              style: TextStyle(fontSize: 24, fontWeight: FontWeight.bold),
            ),
            if (_currentState.isConnected) ...[
              Text('Type: ${_currentState.primaryConnectionType}'),
              Text('Speed: ${_currentState.connectionSpeed.description}'),
              Text('Has Internet: ${_currentState.hasInternetAccess}'),
            ],
          ],
        ),
      ),
    );
  }
}

๐Ÿญ Factory-Based Initialization

Starting from version 1.0.3, the package uses factory-based initialization to ensure proper async setup:

Predefined Factory Methods

// Production configuration (balanced for production apps)
final manager = await ConnectivityManagerFactory.createForProduction();

// Development configuration (faster checks, more detailed logging)
final manager = await ConnectivityManagerFactory.createForDevelopment();

// Minimal configuration (battery-efficient)
final manager = await ConnectivityManagerFactory.createMinimal();

// Aggressive configuration (real-time monitoring)
final manager = await ConnectivityManagerFactory.createAggressive();

Custom Configuration

final config = ConnectivityConfig(
  internetCheckTimeout: Duration(seconds: 10),
  internetCheckInterval: Duration(seconds: 5),
  maxRetryAttempts: 3,
  retryDelay: Duration(seconds: 2),
  testUrls: [
    'https://www.gstatic.com/generate_204',
    'https://www.google.com',
    'https://www.cloudflare.com',
  ],
  enableSpeedTest: true,
  enableBackgroundChecks: true,
  backgroundCheckInterval: Duration(minutes: 1),
  enableConnectionStateCache: true,
  cacheValidDuration: Duration(seconds: 30),
);

final manager = await ConnectivityManagerFactory.create(config: config);

๐Ÿ“Š Connection States

The ConnectivityState class provides comprehensive information about the current connection:

class ConnectivityState {
  final List<ConnectivityResult> networkTypes;  // Available network types
  final bool hasNetworkConnection;              // Device connected to network
  final bool hasInternetAccess;                 // Device can reach internet
  final ConnectionSpeed connectionSpeed;        // Estimated connection speed
  final DateTime? lastChecked;                  // Last update timestamp
  final String? error;                          // Any error occurred
  final StackTrace? stackTrace;                 // Error stack trace

  // Computed properties
  bool get isConnected;                         // Has network + internet
  bool get isOffline;                           // No network connection
  bool get hasNetworkButNoInternet;             // Network but no internet
  ConnectivityResult get primaryConnectionType; // Primary connection type
  bool get isMobileConnection;                  // Using mobile data
  bool get isWiFiConnection;                    // Using WiFi
  bool get isMeteredConnection;                 // Connection might be metered
}

Enhanced Connection Speed Levels

enum ConnectionSpeed {
  none,        // No connection
  poor,        // < 50 Kbps
  slow,        // 50 Kbps - 500 Kbps
  moderate,    // 500 Kbps - 2 Mbps
  good,        // 2-10 Mbps
  fast,        // 10-50 Mbps
  excellent,   // > 50 Mbps
  unknown,     // Speed not tested/determinable
}

Speed Helper Methods

final speed = ConnectionSpeed.good;

// Check if connection is usable for basic operations
if (speed.isUsable) {
  print('Connection is suitable for basic operations');
}

// Check if suitable for high-quality multimedia
if (speed.isGoodForMultimedia) {
  print('Connection can handle high-quality video streaming');
}

// Check if suitable for moderate multimedia
if (speed.isModerateForMultimedia) {
  print('Connection can handle moderate video streaming');
}

// Get human-readable description
print('Speed: ${speed.description}');

๐ŸŽฏ Advanced Features

Stream Subscriptions

// Listen to connectivity state changes
_connectivityManager.onConnectivityChanged.listen((state) {
  print('Connectivity changed: ${state.isConnected}');
  if (state.error != null) {
    print('Error: ${state.error}');
    print('Stack trace: ${state.stackTrace}');
  }
});

// Listen to internet availability only
_connectivityManager.onInternetAvailabilityChanged.listen((hasInternet) {
  print('Internet available: $hasInternet');
});

// Listen to network type changes
_connectivityManager.onNetworkTypeChanged.listen((types) {
  print('Network types: $types');
});

Manual Testing

// Check current connectivity
final state = await _connectivityManager.checkConnectivity();

// Test internet access with custom options
final hasInternet = await _connectivityManager.testInternetAccess(
  testUrls: ['https://httpbin.org/status/200'],
  timeout: Duration(seconds: 5),
  maxRetries: 2,
);

// Test connection speed
final speed = await _connectivityManager.testConnectionSpeed(
  testUrl: 'https://httpbin.org/bytes/1024',
  timeout: Duration(seconds: 10),
);

Connection Waiting

// Wait for any internet connection
final connected = await _connectivityManager.waitForConnection(
  timeout: Duration(seconds: 30),
  checkInterval: Duration(seconds: 1),
);

// Wait for specific connection type
final wifiConnected = await _connectivityManager.waitForConnectionType(
  ConnectivityResult.wifi,
  timeout: Duration(seconds: 60),
);

Advanced Network Operations

// Ping a host
final latency = await _connectivityManager.ping(
  'google.com',
  timeout: Duration(seconds: 5),
  maxAttempts: 3,
);

// Check if URL is reachable
final reachable = await _connectivityManager.isUrlReachable(
  'https://api.example.com/health',
  timeout: Duration(seconds: 10),
);

// Check bandwidth capability
final canHandleBandwidth = await _connectivityManager
    .canHandleBandwidthIntensiveOperations();

// Get connection quality score (0.0 to 1.0)
final qualityScore = await _connectivityManager.getConnectionQualityScore();

// Get detailed network information
final networkInfo = await _connectivityManager.getNetworkInfo();

Lifecycle Management

// Pause monitoring (e.g., when app goes to background)
await _connectivityManager.pauseMonitoring();

// Resume monitoring (e.g., when app comes to foreground)
await _connectivityManager.resumeMonitoring();

// Reset and restart monitoring
await _connectivityManager.reset();

// Clean up resources
await _connectivityManager.dispose();

๐Ÿ—๏ธ Architecture

The package follows clean architecture principles:

  • IConnectivityManager: Main interface defining all connectivity operations
  • ConnectivityManagerImpl: Default implementation with comprehensive features
  • ConnectivityManagerFactory: Factory class for proper async initialization
  • ConnectivityState: Immutable state class representing current connectivity
  • ConnectivityConfig: Configuration class for customizing behavior
  • ConnectivityUtils: Utility functions for connectivity operations
  • Factory Pattern: Ensures proper async initialization with predefined configurations

๐Ÿงช Testing

The package is designed with testability in mind:

// Mock the interface for testing
class MockConnectivityManager extends Mock implements IConnectivityManager {}

void main() {
  late MockConnectivityManager mockConnectivityManager;

  setUp(() {
    mockConnectivityManager = MockConnectivityManager();
  });

  testWidgets('should show connected state', (tester) async {
    // Arrange
    when(mockConnectivityManager.currentState)
        .thenReturn(ConnectivityState.connected(
          networkTypes: [ConnectivityResult.wifi],
          connectionSpeed: ConnectionSpeed.good,
        ));

    // Act & Assert
    await tester.pumpWidget(MyApp(
      connectivityManager: mockConnectivityManager,
    ));

    expect(find.text('Connected'), findsOneWidget);
  });
}

๐Ÿ“š Examples

Check out the example directory for a complete sample app demonstrating all features:

  • Factory-based initialization
  • Real-time connectivity monitoring
  • Manual connectivity testing
  • Connection speed testing
  • Advanced network operations
  • Configuration options
  • Error handling with stack traces

๐Ÿ”„ Migration from v1.0.2 to v1.0.3

Breaking Changes

Old initialization (v1.0.2):

final manager = ConnectivityManagerImpl();
await manager.startMonitoring();

New initialization (v1.0.3+):

final manager = await ConnectivityManagerFactory.createForProduction();
await manager.startMonitoring();

Benefits of Factory-Based Initialization

  • Proper Async Setup: Ensures all async dependencies are initialized
  • Error Prevention: Eliminates initialization-related runtime errors
  • Better Performance: Optimized initialization process
  • Consistent Configuration: Predefined presets for common use cases

๐Ÿค Contributing

Contributions are welcome! Please read our Contributing Guide for details on our code of conduct and the process for submitting pull requests.

๐Ÿ“„ License

This project is licensed under the MIT License - see the LICENSE file for details.

๐Ÿ› Issues

Please file issues on the GitHub Issues page.

๐Ÿ“– Documentation

For detailed API documentation, visit pub.dev documentation.

๐Ÿ™ Acknowledgments

Libraries

flutter_connectivity_manager
A comprehensive Flutter connectivity manager package to check internet connection and network type.