network_watcher
A robust Flutter plugin for monitoring network connectivity changes across Android and iOS platforms with comprehensive support for multiple connection types.
Features
- π Real-time Monitoring: Stream network connectivity changes
- π± Cross-Platform: Full support for Android and iOS
- π Multiple Connection Types: WiFi, Mobile, Ethernet, VPN, Bluetooth
- π― Type-Safe: Strongly typed API with null safety
- β‘ Efficient: Uses platform-native APIs for optimal performance
- π§ͺ Well-Tested: Comprehensive test coverage
- π Well-Documented: Clear examples and API documentation
Supported Connection Types
none- No network connectionwifi- WiFi connectionmobile- Mobile/Cellular connectionethernet- Wired Ethernet connectionvpn- VPN connectionbluetooth- Bluetooth connectionother- Other type of connection
Installation
Add this to your package's pubspec.yaml file:
dependencies:
network_watcher: ^0.0.1
Then run:
flutter pub get
Platform-Specific Setup
Android
The plugin requires the ACCESS_NETWORK_STATE permission. This is already included in the plugin's AndroidManifest.xml and will be automatically merged into your app.
For Android 12 (API level 31) and above, if you need to support Bluetooth connectivity detection, you might need additional permissions.
iOS
No additional setup required. The plugin uses the Network framework (iOS 12+) for modern iOS versions and falls back to SystemConfiguration for older versions.
Usage
Basic Usage
Check current connectivity:
import 'package:network_watcher/network_watcher.dart';
// Check current connectivity
final result = await NetworkWatcher.instance.checkConnectivity();
if (result.isConnected) {
print('Connected via: ${result.types}');
} else {
print('No connection');
}
Listen to Connectivity Changes
Monitor connectivity changes in real-time:
import 'package:network_watcher/network_watcher.dart';
import 'dart:async';
StreamSubscription<ConnectivityResult>? _subscription;
void startMonitoring() {
_subscription = NetworkWatcher.instance.onConnectivityChanged.listen(
(ConnectivityResult result) {
if (result.isWifi) {
print('Connected to WiFi');
} else if (result.isMobile) {
print('Connected to Mobile Data');
} else if (!result.isConnected) {
print('No connection');
}
},
);
}
void stopMonitoring() {
_subscription?.cancel();
}
// Don't forget to cancel the subscription when done!
@override
void dispose() {
_subscription?.cancel();
super.dispose();
}
Check Specific Connection Types
final result = await NetworkWatcher.instance.checkConnectivity();
// Check for specific connection types
if (result.isWifi) {
print('Connected to WiFi');
}
if (result.isMobile) {
print('Using mobile data');
}
if (result.isVpn) {
print('Connected via VPN');
}
if (result.isEthernet) {
print('Connected via Ethernet');
}
// Check for multiple connections (e.g., WiFi + VPN)
if (result.isWifi && result.isVpn) {
print('Connected to WiFi through VPN');
}
Handle Multiple Connection Types
Some devices can have multiple active connections simultaneously (e.g., WiFi + VPN):
final result = await NetworkWatcher.instance.checkConnectivity();
print('Active connections: ${result.types.length}');
for (var type in result.types) {
print('- ${type.name}');
}
Complete Example with UI
import 'package:flutter/material.dart';
import 'package:network_watcher/network_watcher.dart';
import 'dart:async';
class ConnectivityWidget extends StatefulWidget {
@override
_ConnectivityWidgetState createState() => _ConnectivityWidgetState();
}
class _ConnectivityWidgetState extends State<ConnectivityWidget> {
ConnectivityResult? _connectivity;
StreamSubscription<ConnectivityResult>? _subscription;
@override
void initState() {
super.initState();
_initConnectivity();
_subscription = NetworkWatcher.instance.onConnectivityChanged.listen(
(ConnectivityResult result) {
setState(() {
_connectivity = result;
});
},
);
}
@override
void dispose() {
_subscription?.cancel();
super.dispose();
}
Future<void> _initConnectivity() async {
final result = await NetworkWatcher.instance.checkConnectivity();
setState(() {
_connectivity = result;
});
}
@override
Widget build(BuildContext context) {
return Column(
children: [
if (_connectivity == null)
CircularProgressIndicator()
else if (_connectivity!.isConnected)
Icon(Icons.wifi, color: Colors.green)
else
Icon(Icons.wifi_off, color: Colors.red),
Text(_getStatusText()),
],
);
}
String _getStatusText() {
if (_connectivity == null) return 'Checking...';
if (!_connectivity!.isConnected) return 'No Connection';
return _connectivity!.types.map((t) => t.name).join(' + ').toUpperCase();
}
}
API Reference
NetworkWatcher
Main singleton class for network monitoring.
Properties
static NetworkWatcher instance- Singleton instance
Methods
Future<ConnectivityResult> checkConnectivity()- Check current connectivity statusStream<ConnectivityResult> get onConnectivityChanged- Stream of connectivity changes
ConnectivityResult
Result object containing connectivity information.
Properties
List<ConnectivityType> types- List of active connection typesbool isConnected- Whether there is any network connectionbool isWifi- Whether connected to WiFibool isMobile- Whether connected to mobile databool isEthernet- Whether connected to ethernetbool isVpn- Whether connected via VPNbool isBluetooth- Whether connected via bluetooth
ConnectivityType
Enum representing connection types.
Values: none, wifi, mobile, ethernet, bluetooth, vpn, other
Platform Implementation Details
Android
- Uses
ConnectivityManagerandNetworkCallback(API 21+) - Supports legacy
BroadcastReceiverfor older Android versions - Detects WiFi, Mobile, Ethernet, VPN, and Bluetooth connections
- Handles edge cases like airplane mode and network switching
iOS
- Uses
NWPathMonitorfrom Network framework (iOS 12+) - Falls back to
SCNetworkReachabilityfor iOS < 12 - Detects WiFi, Cellular, Ethernet, and VPN connections
- Handles iOS-specific network states
Error Handling
The plugin gracefully handles errors and edge cases:
- Returns
ConnectivityType.nonewhen connectivity manager is unavailable - Handles platform exceptions and returns safe defaults
- Prevents stream errors from breaking the app
- Validates and filters unknown connection types
Testing
The plugin includes comprehensive tests covering:
- Connectivity checking for all connection types
- Stream functionality and error handling
- Platform channel communication
- Edge cases and error scenarios
Run tests:
flutter test
Example App
The example app demonstrates:
- Real-time connectivity monitoring
- Connection history tracking
- Visual connection status indicators
- Start/stop monitoring controls
Run the example:
cd example
flutter run
Performance Considerations
- The stream uses broadcast streams for multiple listeners
- Duplicate consecutive events are filtered out
- Proper cleanup prevents memory leaks
- Platform-native implementations ensure efficiency
Troubleshooting
Android
Issue: Not detecting network changes
- Ensure
ACCESS_NETWORK_STATEpermission is granted - Check that the app is not in a restricted battery mode
iOS
Issue: Not working on simulator
- Some connectivity features may not work properly in simulator
- Test on a real device for accurate results
Both Platforms
Issue: Stream not emitting updates
- Ensure you haven't canceled the subscription
- Check that you're listening to the stream before network changes occur
Contributing
Contributions are welcome! Please read the contributing guidelines before submitting PRs.
License
This project is licensed under the MIT License - see the LICENSE file for details.
Changelog
See CHANGELOG.md for a detailed list of changes.
Author
Created by Syed Bipul
Support
For issues, questions, or suggestions, please file an issue on the GitHub repository.