Connectivity Status in Flutter

Connectivity Status in Flutter: Complete Tutorial (2026) | D.Tech Academic

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.

Connectivity status screen showing WiFi connection in Flutter app
WiFi connection detected
Connectivity status screen showing no internet connection in Flutter app
No internet connection detected

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_plus for quick network detection and a package like internet_connection_checker for actual reachability.

No comments: