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 operationsConnectivityManagerImpl
: Default implementation with comprehensive featuresConnectivityManagerFactory
: Factory class for proper async initializationConnectivityState
: Immutable state class representing current connectivityConnectivityConfig
: Configuration class for customizing behaviorConnectivityUtils
: 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
- Built on top of connectivity_plus
- Uses internet_connection_checker_plus for internet verification
- Utilizes flutter_shared_utilities for shared functionality
Libraries
- flutter_connectivity_manager
- A comprehensive Flutter connectivity manager package to check internet connection and network type.