network_health_monitor 0.1.1
network_health_monitor: ^0.1.1 copied to clipboard
Lightweight Flutter package to monitor internet connectivity and network quality continuously.
network_health_monitor #
Lightweight Flutter package that continuously monitors internet connectivity and network quality.
This package only reports network state. It is UI-agnostic — your app owns offline/slow UI. No per-screen or API-layer checks are required.
Platforms #
| Android | iOS | Desktop |
|---|---|---|
| ✅ | ✅ | ✅ |
Web: validate your probe URL for CORS before relying on it.
Install #
dependencies:
network_health_monitor: ^0.1.1
import 'package:network_health_monitor/network_health_monitor.dart';
Basic usage #
WidgetsFlutterBinding.ensureInitialized();
final monitor = NetworkHealthMonitor();
await monitor.startMonitoring();
monitor.statusStream.listen((status) {
switch (status) {
case NetworkStatus.checking:
break;
case NetworkStatus.online:
break;
case NetworkStatus.slow:
break;
case NetworkStatus.offline:
break;
}
});
Notes #
- Default probe (
https://www.cloudflare.com/cdn-cgi/trace) checks general internet, not your backend. - If the default probe fails, best-effort public fallbacks are tried (
gstatic generate_204, Microsoft connect test). They improve resilience but do not guarantee internet detection (third-party endpoints can change). CustomhealthCheckUrldoes not auto-add public fallbacks. - Captive-portal HTML responses are treated as offline.
- Connectivity-type changes are handled immediately; silent internet loss is caught on the next periodic check (default 30s) and on app resume.
- Latency means HTTP request latency (not pure network RTT).
measureBandwidthdefaults tofalse. When enabled,bandwidthProbeUrlis required (approximate download throughput only).- Each
statusStreamsubscription first emitscurrentStatus, then future changes. - Stale in-flight HTTP results cannot overwrite a newer connectivity
OFFLINEevent. - Call
dispose()when the monitor is no longer needed (e.g. app teardown).
Retry #
final result = await monitor.retry();
retry() and check() run an on-demand evaluation and return a [NetworkHealthResult].
States #
| Status | Meaning |
|---|---|
checking |
Initial health check in progress |
online |
Reachable with acceptable quality |
slow |
Reachable, but latency/throughput is poor |
offline |
No usable internet connectivity |
Stabilization #
| Transition | Behavior |
|---|---|
online → slow |
Consecutive bad checks (default 2) |
slow → online |
Consecutive good checks (default 2) |
offline → online/slow |
Immediate |
any → offline |
Immediate |
Set consecutiveBadChecksForSlow / consecutiveGoodChecksForOnline to 1 and shorten periodicCheckInterval if you want faster status transitions.
Config #
NetworkHealthConfig(
healthCheckUrl: 'https://www.cloudflare.com/cdn-cgi/trace',
// Optional; defaults to public fallbacks when using the default primary URL.
// Pass [] to disable fallbacks, or your own list.
// fallbackHealthCheckUrls: [...],
slowLatency: const Duration(milliseconds: 1500),
requestTimeout: const Duration(seconds: 8),
periodicCheckInterval: const Duration(seconds: 30),
consecutiveBadChecksForSlow: 2,
consecutiveGoodChecksForOnline: 2,
measureBandwidth: false,
);
// If measuring approximate download throughput:
NetworkHealthConfig(
measureBandwidth: true,
bandwidthProbeUrl: 'https://cdn.example.com/probe.bin',
bandwidthProbeBytes: 50 * 1024,
slowDownloadSpeedKbps: 300,
);
| Option | Default | Purpose |
|---|---|---|
healthCheckUrl |
Cloudflare trace | Reachability + latency probe |
fallbackHealthCheckUrls |
Public fallbacks* | Tried if primary fails |
slowLatency |
1500 ms | Latency above this → slow |
requestTimeout |
8 s | Max wait per HTTP probe |
periodicCheckInterval |
30 s | Background check interval |
consecutiveBadChecksForSlow |
2 | Samples before online → slow |
consecutiveGoodChecksForOnline |
2 | Samples before slow → online |
measureBandwidth |
false |
Enable download throughput check |
bandwidthProbeUrl |
null |
Required when measuring bandwidth |
bandwidthProbeBytes |
50 KB | Bytes to download for throughput |
slowDownloadSpeedKbps |
300 | Throughput below this → slow |
* Applied automatically only when healthCheckUrl is the package default.
API #
| API | Purpose |
|---|---|
startMonitoring() |
Start listeners + periodic checks |
stopMonitoring() |
Pause monitoring (keeps last status) |
check() / retry() |
On-demand evaluation |
currentStatus |
Latest status |
lastResult |
Latest full health snapshot |
isMonitoring |
Whether monitoring is active |
config |
Active [NetworkHealthConfig] |
statusStream |
Current status, then updates |
resultStream |
Latency/throughput snapshots |
dispose() |
Clean up |
NetworkHealthResult #
| Field | Meaning |
|---|---|
status |
Evaluated [NetworkStatus] |
checkedAt |
When the check completed |
latency |
HTTP request latency, if measured |
downloadSpeedKbps |
Approximate throughput, if measured |
connectionTypes |
Platform connectivity types |
probeUrl |
Probe that succeeded (or last tried) |
errorMessage |
Detail when the check failed |
isConnected |
true for online or slow |
Example #
See example/main.dart.