network_watcher 0.0.1 copy "network_watcher: ^0.0.1" to clipboard
network_watcher: ^0.0.1 copied to clipboard

A robust Flutter plugin for monitoring network connectivity changes with support for WiFi, Mobile, Ethernet, VPN, and Bluetooth connections on Android and iOS.

example/lib/main.dart

import 'package:flutter/material.dart';
import 'dart:async';

import 'package:network_watcher/network_watcher.dart';

void main() {
  runApp(const MyApp());
}

class MyApp extends StatelessWidget {
  const MyApp({super.key});

  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Network Watcher Demo',
      theme: ThemeData(primarySwatch: Colors.blue, useMaterial3: true),
      home: const NetworkWatcherDemo(),
    );
  }
}

class NetworkWatcherDemo extends StatefulWidget {
  const NetworkWatcherDemo({super.key});

  @override
  State<NetworkWatcherDemo> createState() => _NetworkWatcherDemoState();
}

class _NetworkWatcherDemoState extends State<NetworkWatcherDemo> {
  ConnectivityResult? _currentConnectivity;
  final List<ConnectivityEvent> _connectivityHistory = [];
  StreamSubscription<ConnectivityResult>? _subscription;
  bool _isMonitoring = false;

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

  @override
  void dispose() {
    _subscription?.cancel();
    super.dispose();
  }

  Future<void> _checkCurrentConnectivity() async {
    try {
      final result = await NetworkWatcher.instance.checkConnectivity();
      setState(() {
        _currentConnectivity = result;
      });
    } catch (e) {
      _showError('Error checking connectivity: $e');
    }
  }

  void _startMonitoring() {
    if (_isMonitoring) return;

    _subscription = NetworkWatcher.instance.onConnectivityChanged.listen(
      (ConnectivityResult result) {
        setState(() {
          _currentConnectivity = result;
          _connectivityHistory.insert(
            0,
            ConnectivityEvent(timestamp: DateTime.now(), result: result),
          );
          // Keep only last 20 events
          if (_connectivityHistory.length > 20) {
            _connectivityHistory.removeLast();
          }
        });
      },
      onError: (error) {
        _showError('Stream error: $error');
      },
    );

    setState(() {
      _isMonitoring = true;
    });
  }

  void _stopMonitoring() {
    _subscription?.cancel();
    _subscription = null;
    setState(() {
      _isMonitoring = false;
    });
  }

  void _clearHistory() {
    setState(() {
      _connectivityHistory.clear();
    });
  }

  void _showError(String message) {
    if (!mounted) return;
    ScaffoldMessenger.of(context).showSnackBar(
      SnackBar(content: Text(message), backgroundColor: Colors.red),
    );
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(title: const Text('Network Watcher Demo'), elevation: 2),
      body: Column(
        children: [
          // Current Status Card
          Card(
            margin: const EdgeInsets.all(16),
            elevation: 4,
            child: Padding(
              padding: const EdgeInsets.all(16),
              child: Column(
                crossAxisAlignment: CrossAxisAlignment.start,
                children: [
                  Row(
                    children: [
                      Icon(
                        _getConnectionIcon(),
                        size: 48,
                        color: _getConnectionColor(),
                      ),
                      const SizedBox(width: 16),
                      Expanded(
                        child: Column(
                          crossAxisAlignment: CrossAxisAlignment.start,
                          children: [
                            const Text(
                              'Current Status',
                              style: TextStyle(
                                fontSize: 18,
                                fontWeight: FontWeight.bold,
                              ),
                            ),
                            const SizedBox(height: 4),
                            Text(
                              _getStatusText(),
                              style: TextStyle(
                                fontSize: 16,
                                color: _getConnectionColor(),
                                fontWeight: FontWeight.w500,
                              ),
                            ),
                          ],
                        ),
                      ),
                    ],
                  ),
                  if (_currentConnectivity != null) ...[
                    const Divider(height: 24),
                    _buildConnectionDetails(),
                  ],
                ],
              ),
            ),
          ),

          // Control Buttons
          Padding(
            padding: const EdgeInsets.symmetric(horizontal: 16),
            child: Row(
              children: [
                Expanded(
                  child: ElevatedButton.icon(
                    onPressed: _checkCurrentConnectivity,
                    icon: const Icon(Icons.refresh),
                    label: const Text('Check Now'),
                  ),
                ),
                const SizedBox(width: 12),
                Expanded(
                  child: ElevatedButton.icon(
                    onPressed: _isMonitoring
                        ? _stopMonitoring
                        : _startMonitoring,
                    icon: Icon(_isMonitoring ? Icons.stop : Icons.play_arrow),
                    label: Text(
                      _isMonitoring ? 'Stop Monitor' : 'Start Monitor',
                    ),
                    style: ElevatedButton.styleFrom(
                      backgroundColor: _isMonitoring
                          ? Colors.red
                          : Colors.green,
                      foregroundColor: Colors.white,
                    ),
                  ),
                ),
              ],
            ),
          ),

          // History Section
          Padding(
            padding: const EdgeInsets.all(16),
            child: Row(
              mainAxisAlignment: MainAxisAlignment.spaceBetween,
              children: [
                const Text(
                  'Connection History',
                  style: TextStyle(fontSize: 18, fontWeight: FontWeight.bold),
                ),
                if (_connectivityHistory.isNotEmpty)
                  TextButton.icon(
                    onPressed: _clearHistory,
                    icon: const Icon(Icons.clear_all, size: 18),
                    label: const Text('Clear'),
                  ),
              ],
            ),
          ),

          // History List
          Expanded(
            child: _connectivityHistory.isEmpty
                ? Center(
                    child: Column(
                      mainAxisAlignment: MainAxisAlignment.center,
                      children: [
                        Icon(Icons.history, size: 64, color: Colors.grey[400]),
                        const SizedBox(height: 16),
                        Text(
                          'No history yet.\nStart monitoring to see changes.',
                          textAlign: TextAlign.center,
                          style: TextStyle(
                            fontSize: 16,
                            color: Colors.grey[600],
                          ),
                        ),
                      ],
                    ),
                  )
                : ListView.builder(
                    itemCount: _connectivityHistory.length,
                    itemBuilder: (context, index) {
                      final event = _connectivityHistory[index];
                      return _buildHistoryItem(event);
                    },
                  ),
          ),
        ],
      ),
    );
  }

  Widget _buildConnectionDetails() {
    final connectivity = _currentConnectivity!;
    return Wrap(
      spacing: 8,
      runSpacing: 8,
      children: [
        _buildDetailChip('Connected', connectivity.isConnected),
        if (connectivity.isWifi) _buildDetailChip('WiFi', true),
        if (connectivity.isMobile) _buildDetailChip('Mobile', true),
        if (connectivity.isEthernet) _buildDetailChip('Ethernet', true),
        if (connectivity.isVpn) _buildDetailChip('VPN', true),
        if (connectivity.isBluetooth) _buildDetailChip('Bluetooth', true),
      ],
    );
  }

  Widget _buildDetailChip(String label, bool value) {
    return Chip(
      label: Text(label),
      backgroundColor: value ? Colors.green[100] : Colors.red[100],
      side: BorderSide(color: value ? Colors.green : Colors.red, width: 1),
    );
  }

  Widget _buildHistoryItem(ConnectivityEvent event) {
    return Card(
      margin: const EdgeInsets.symmetric(horizontal: 16, vertical: 4),
      child: ListTile(
        leading: Icon(
          _getConnectionIconForResult(event.result),
          color: _getConnectionColorForResult(event.result),
        ),
        title: Text(
          event.result.types.map((t) => t.name).join(', '),
          style: const TextStyle(fontWeight: FontWeight.w500),
        ),
        subtitle: Text(
          _formatTimestamp(event.timestamp),
          style: TextStyle(fontSize: 12, color: Colors.grey[600]),
        ),
        trailing: event.result.isConnected
            ? const Icon(Icons.check_circle, color: Colors.green, size: 20)
            : const Icon(Icons.cancel, color: Colors.red, size: 20),
      ),
    );
  }

  String _getStatusText() {
    if (_currentConnectivity == null) {
      return 'Checking...';
    }
    if (!_currentConnectivity!.isConnected) {
      return 'No Connection';
    }
    return _currentConnectivity!.types
        .map((t) => t.name.toUpperCase())
        .join(' + ');
  }

  IconData _getConnectionIcon() {
    if (_currentConnectivity == null) {
      return Icons.signal_wifi_statusbar_null;
    }
    return _getConnectionIconForResult(_currentConnectivity!);
  }

  IconData _getConnectionIconForResult(ConnectivityResult result) {
    if (!result.isConnected) {
      return Icons.signal_wifi_off;
    }
    if (result.isWifi) {
      return Icons.wifi;
    }
    if (result.isMobile) {
      return Icons.signal_cellular_alt;
    }
    if (result.isEthernet) {
      return Icons.settings_ethernet;
    }
    if (result.isVpn) {
      return Icons.vpn_key;
    }
    if (result.isBluetooth) {
      return Icons.bluetooth;
    }
    return Icons.device_unknown;
  }

  Color _getConnectionColor() {
    if (_currentConnectivity == null) {
      return Colors.grey;
    }
    return _getConnectionColorForResult(_currentConnectivity!);
  }

  Color _getConnectionColorForResult(ConnectivityResult result) {
    return result.isConnected ? Colors.green : Colors.red;
  }

  String _formatTimestamp(DateTime timestamp) {
    final now = DateTime.now();
    final difference = now.difference(timestamp);

    if (difference.inSeconds < 60) {
      return '${difference.inSeconds}s ago';
    } else if (difference.inMinutes < 60) {
      return '${difference.inMinutes}m ago';
    } else {
      return '${timestamp.hour.toString().padLeft(2, '0')}:${timestamp.minute.toString().padLeft(2, '0')}:${timestamp.second.toString().padLeft(2, '0')}';
    }
  }
}

class ConnectivityEvent {
  final DateTime timestamp;
  final ConnectivityResult result;

  ConnectivityEvent({required this.timestamp, required this.result});
}
0
likes
160
points
3
downloads

Publisher

verified publishersyedbipul.me

Weekly Downloads

A robust Flutter plugin for monitoring network connectivity changes with support for WiFi, Mobile, Ethernet, VPN, and Bluetooth connections on Android and iOS.

Homepage

Documentation

API reference

License

MIT (license)

Dependencies

flutter, plugin_platform_interface

More

Packages that depend on network_watcher

Packages that implement network_watcher