Connectivity Status in Flutter: Complete Tutorial (2026)
Last Updated: | Author: Deep Singh
Every app that talks to the internet needs to handle the case where there is no internet. Maybe the user walked into a tunnel, turned on airplane mode, or their WiFi dropped. If your app doesn't react, you'll end up showing blank screens, endless spinners, or cryptic error messages.
In this tutorial, you'll learn how to monitor network connectivity in Flutter in real time. We'll use the connectivity_plus plugin to detect WiFi, mobile data, and no connection at all, and we'll update the UI instantly whenever the status changes.
Before You Start
Make sure you have the following ready:
- Flutter SDK installed (use the latest stable version for best compatibility)
- Android Studio or VS Code with the Flutter plugin
- A basic understanding of Dart,
StatefulWidget, and streams
Permissions: On Android, the plugin needs the ACCESS_NETWORK_STATE permission. The plugin adds this automatically, but it's good to know it's there. On iOS, no special permissions are required.
Adding the Plugin
The easiest way to add the plugin is to run this command in your project folder:
flutter pub add connectivity_plus
Or add it manually to your pubspec.yaml file under dependencies:
dependencies:
connectivity_plus: ^6.0.5
Then run flutter pub get to fetch the package.
A note on the plugin name: If you've seen older Flutter tutorials, they used a package called connectivity. That package has been deprecated and is no longer maintained. It has been replaced by connectivity_plus, which is the current standard. Make sure you use the _plus version — the old one may not work with modern Flutter versions.
The Full Code
Here's a complete, working example. It listens to connectivity changes and updates a large status indicator on screen — green with a WiFi icon when connected, red with a WiFi-off icon when not.
import 'dart:async';
import 'package:flutter/material.dart';
import 'package:connectivity_plus/connectivity_plus.dart';
void main() {
runApp(const MaterialApp(
home: MyConnection(),
title: 'Connectivity',
));
}
class MyConnection extends StatefulWidget {
const MyConnection({super.key});
@override
State<MyConnection> createState() => _MyConnectionState();
}
class _MyConnectionState extends State<MyConnection> {
String _status = 'Checking...';
bool _isConnected = false;
late final StreamSubscription<List<ConnectivityResult>> _subscription;
@override
void initState() {
super.initState();
// Check the current status when the app starts
_checkCurrentStatus();
// Listen for changes from this point on
_subscription = Connectivity().onConnectivityChanged.listen(_updateStatus);
}
Future<void> _checkCurrentStatus() async {
final result = await Connectivity().checkConnectivity();
_updateStatus(result);
}
void _updateStatus(List<ConnectivityResult> results) {
if (!mounted) return;
setState(() {
if (results.contains(ConnectivityResult.wifi)) {
_status = 'Connected via WiFi';
_isConnected = true;
} else if (results.contains(ConnectivityResult.mobile)) {
_status = 'Connected via Mobile Data';
_isConnected = true;
} else if (results.contains(ConnectivityResult.ethernet)) {
_status = 'Connected via Ethernet';
_isConnected = true;
} else {
_status = 'No Internet Connection';
_isConnected = false;
}
});
}
@override
void dispose() {
_subscription.cancel();
super.dispose();
}
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: const Text('Connection State'),
),
body: Center(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: [
CircleAvatar(
radius: 100,
backgroundColor: Colors.redAccent,
child: CircleAvatar(
radius: 95,
backgroundColor: _isConnected ? Colors.green : Colors.red,
child: Icon(
_isConnected ? Icons.wifi : Icons.wifi_off,
size: 100,
color: Colors.white,
),
),
),
const SizedBox(height: 20),
Text(
_status,
style: const TextStyle(fontSize: 24),
textAlign: TextAlign.center,
),
],
),
),
);
}
}
How the Code Works
Let's walk through the important parts:
1. Checking the Current Status
When the app starts, we call Connectivity().checkConnectivity() to get the current network state. This is important because the stream only fires when the status changes — it won't tell you what the status is right now.
2. Listening for Changes
The onConnectivityChanged stream fires every time the network state changes — WiFi turns off, mobile data turns on, and so on. We subscribe to it in initState() and update the UI whenever a new value arrives.
3. Handling Multiple Results
In recent versions of the plugin, onConnectivityChanged returns a List<ConnectivityResult> instead of a single value. This is because a device can be connected to multiple networks at once (for example, WiFi and Ethernet simultaneously). We check the list for WiFi, mobile, or ethernet, in that order.
4. Cleaning Up
In dispose(), we cancel the stream subscription. If we don't, the subscription keeps running after the widget is destroyed, which can cause memory leaks and errors.
5. Checking mounted
Before calling setState(), we check if (!mounted) return;. This prevents an error if the widget has been removed from the tree while we were waiting for an async operation to complete.
A Very Important Note About Connectivity
Here's something that trips up a lot of developers: the connectivity plugin does not tell you whether you have internet access. It only tells you whether you're connected to a network.
This is a subtle but critical distinction. Your phone can be connected to a WiFi network that has no internet — for example, a hotel WiFi that requires you to log in through a captive portal, or a router that has lost its upstream connection. In that case, connectivity_plus will report ConnectivityResult.wifi, but http requests will still fail.
If you need to know whether the internet is actually reachable, you'll need to combine this plugin with something like the internet_connection_checker package, which pings a known host to verify real connectivity. Use connectivity_plus to detect network changes quickly and cheaply, then verify actual internet access when it matters.
Wrapping Up
You now know how to monitor network connectivity in Flutter and update your UI in real time. This is the foundation for graceful offline handling — showing cached data, disabling buttons, or displaying a friendly "you're offline" message instead of a crash.
A few things to keep in mind as you build on this:
- Don't block the UI. Even with a connectivity check, always handle the case where a request fails. Networks can drop between the check and the actual call.
- Use it for UX, not for security. Connectivity status is a hint, not a guarantee. Never rely on it for anything security-related.
- Combine with a real internet check. As noted above, use
connectivity_plusfor quick network detection and a package likeinternet_connection_checkerfor actual reachability.
No comments:
Post a Comment