Checking Network Connectivity in Flutter Applications: The Complete Guide to connectivity_plus
The most reliable method for checking network connectivity in Flutter applications is using the connectivity_plus plugin combined with a secondary DNS or HTTP probe to verify actual internet access.
The Flutter SDK (from the flutter/flutter repository) does not expose a built-in API for monitoring network state, making third-party plugins essential for checking network connectivity in Flutter applications. The connectivity_plus package, maintained by the Flutter Community Plus team, provides the official abstraction over platform-specific APIs like Android's ConnectivityManager and iOS's SCNetworkReachability.
Why connectivity_plus is the Standard for Network Detection
The connectivity_plus plugin is the official continuation of the deprecated connectivity package and is listed on the Flutter website's "Recommended plugins" page. It abstracts platform-specific implementations—including NetworkInfo on Android and Reachability on iOS/macOS—behind a single Dart interface exposed in lib/connectivity_plus.dart.
Unlike manual platform channel implementations, this plugin provides both synchronous checks and real-time streaming capabilities without requiring boilerplate Kotlin or Objective-C code in your project.
Implementing One-Time and Streaming Connectivity Checks
The plugin exposes two primary APIs for checking network connectivity in Flutter applications: checkConnectivity() for single-shot queries and onConnectivityChanged for continuous monitoring.
Checking Current Status with checkConnectivity()
Use checkConnectivity() to determine the immediate connection type. This method returns a ConnectivityResult enum indicating whether the device is on WiFi, mobile data, or offline.
import 'package:connectivity_plus/connectivity_plus.dart';
Future<void> evaluateConnection() async {
final ConnectivityResult result = await Connectivity().checkConnectivity();
if (result == ConnectivityResult.mobile) {
print('Connected to a cellular network');
} else if (result == ConnectivityResult.wifi) {
print('Connected to Wi‑Fi');
} else {
print('No network connection');
}
}
Monitoring Changes with onConnectivityChanged
For real-time applications, subscribe to the onConnectivityChanged stream. This broadcasts connectivity changes as the user moves between networks or enters offline mode.
import 'package:connectivity_plus/connectivity_plus.dart';
import 'dart:async';
late StreamSubscription<ConnectivityResult> _sub;
void startListening() {
_sub = Connectivity()
.onConnectivityChanged
.listen((ConnectivityResult result) {
switch (result) {
case ConnectivityResult.wifi:
print('Wi‑Fi connection restored');
break;
case ConnectivityResult.mobile:
print('Cellular connection restored');
break;
case ConnectivityResult.none:
print('Lost network connectivity');
break;
default:
break;
}
});
}
void stopListening() => _sub.cancel();
Avoiding False Positives: Verifying Actual Internet Access
A device can report ConnectivityResult.wifi while connected to a router with no upstream internet access. To ensure reliable connectivity checking in Flutter applications, combine connectivity_plus with a lightweight DNS lookup or HTTP HEAD request.
The following implementation first checks the connection type, then validates reachability by resolving example.com:
import 'dart:io';
import 'package:connectivity_plus/connectivity_plus.dart';
Future<bool> hasInternetAccess() async {
// First, quick check with connectivity_plus
final result = await Connectivity().checkConnectivity();
if (result == ConnectivityResult.none) return false;
// Then try a DNS lookup (e.g., Google)
try {
final List<InternetAddress> addresses =
await InternetAddress.lookup('example.com');
return addresses.isNotEmpty && addresses.first.rawAddress.isNotEmpty;
} on SocketException catch (_) {
return false;
}
}
Platform-Specific Implementation Details
The connectivity_plus plugin handles platform differences through specific implementations in the fluttercommunity/plus_plugins repository. Understanding these internals helps debug edge cases when checking network connectivity in Flutter applications.
On Android, the plugin utilizes ConnectivityManager via Kotlin code in android/src/main/kotlin/com/plusplugins/connectivity/ConnectivityPlugin.kt. On iOS and macOS, it bridges to SCNetworkReachability through Objective-C implementations in ios/Classes/FLTConnectivityPlugin.m.
The public Dart API exposed in lib/connectivity_plus.dart unifies these platform channels into the Connectivity class used in your application code. While the core flutter/flutter repository contains network-related stubs in files like packages/flutter_tools/lib/src/cache.dart, it does not provide the runtime connectivity detection required for application logic.
Complete UI Implementation Example
For production applications, wrap connectivity logic in a reusable widget that displays status changes to users. This example combines the stream listener with DNS verification and a MaterialBanner for offline notifications:
import 'package:flutter/material.dart';
import 'package:connectivity_plus/connectivity_plus.dart';
import 'dart:async';
import 'dart:io';
class ConnectivityBanner extends StatefulWidget {
const ConnectivityBanner({Key? key}) : super(key: key);
@override
_ConnectivityBannerState createState() => _ConnectivityBannerState();
}
class _ConnectivityBannerState extends State<ConnectivityBanner> {
late StreamSubscription<ConnectivityResult> _subscription;
bool _hasInternet = true;
@override
void initState() {
super.initState();
_subscription = Connectivity()
.onConnectivityChanged
.listen((_) => _updateInternetStatus());
_updateInternetStatus(); // initial check
}
Future<void> _updateInternetStatus() async {
final hasInternet = await _verifyInternet();
if (hasInternet != _hasInternet) {
setState(() => _hasInternet = hasInternet);
}
}
Future<bool> _verifyInternet() async {
final result = await Connectivity().checkConnectivity();
if (result == ConnectivityResult.none) return false;
try {
final lookup = await InternetAddress.lookup('example.com')
.timeout(const Duration(seconds: 3));
return lookup.isNotEmpty;
} on Exception {
return false;
}
}
@override
void dispose() {
_subscription.cancel();
super.dispose();
}
@override
Widget build(BuildContext context) {
if (_hasInternet) return const SizedBox.shrink();
return MaterialBanner(
content: const Text('No internet connection'),
leading: const Icon(Icons.wifi_off),
actions: [
TextButton(
onPressed: _updateInternetStatus,
child: const Text('RETRY'),
),
],
);
}
}
Summary
- The
connectivity_plusplugin is the official and most reliable solution for checking network connectivity in Flutter applications, abstracting Android'sConnectivityManagerand iOS'sSCNetworkReachability. - Use
checkConnectivity()for one-shot status checks andonConnectivityChangedfor real-time monitoring of network transitions. - Always verify actual internet reachability using a DNS lookup or HTTP request to avoid false positives when connected to captive portals or offline routers.
- Platform-specific implementations reside in
android/src/main/kotlin/com/plusplugins/connectivity/ConnectivityPlugin.ktandios/Classes/FLTConnectivityPlugin.m, while the Dart API is exposed inlib/connectivity_plus.dart.
Frequently Asked Questions
What is the difference between connectivity and connectivity_plus?
The connectivity package was the original official plugin maintained by the Flutter team, but it has been deprecated in favor of connectivity_plus. The Plus version is maintained by the Flutter Community Plus team, supports more platforms including desktop and web, and receives regular updates and bug fixes.
How do I check if the user has actual internet access, not just WiFi?
Combine connectivity_plus with a DNS lookup or HTTP request. First verify the connection type is not ConnectivityResult.none, then attempt to resolve a domain like example.com using InternetAddress.lookup(). If the lookup succeeds, the device has actual internet access; if it throws a SocketException, the connection is likely a captive portal or offline router.
Does connectivity_plus work on web and desktop platforms?
Yes, connectivity_plus supports Android, iOS, macOS, Linux, Windows, and Web. The web implementation uses the browser's navigator.connection API where available, while desktop implementations utilize platform-specific network monitoring APIs. However, the DNS verification technique for actual internet access works consistently across all platforms.
Is connectivity_plus maintained by the Flutter team?
No, connectivity_plus is maintained by the Flutter Community Plus team, a community-led organization, not the official Google Flutter team. However, it is endorsed by the Flutter team and listed as a "Recommended plugin" on the official Flutter website, making it the de facto standard for production applications.
Have a question about this repo?
These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:
curl -s "https://instagit.com/install.md" Maintain an open-source project? Get it listed too →