0

I would like to make my flutter application to be able to check the connection status and prompt a warning if the wifi and mobile network is turned off. However, I want to make this globally across the application which means the application will constantly listen for network changes until the application is exited. I do not know how to achieve that. I use Provider as the state management for my project. The package I use for checking the network status are internet_connection_checker and connectivity_plus.

main.dart

import 'package:flutter/material.dart';
import 'package:firebase_core/firebase_core.dart';
import 'package:provider/provider.dart';
import 'package:test/page/error.dart';
import 'package:test/routes.dart';
import 'package:test/service/connection_manager.dart';
import 'package:test/service/firebase_service.dart';
import 'package:test/firebase_options.dart';
import 'package:test/globals.dart';
import 'package:flutter_gen/gen_l10n/app_localizations.dart';


Future<void> main() async {
  WidgetsFlutterBinding.ensureInitialized();
  await Firebase.initializeApp(options: DefaultFirebaseOptions.currentPlatform);
  await FirebaseService().initNotifications();
  await FirebaseService().initFirebaseRemoteConfig();

  int mainCount = 1;

  try {
    await deviceManager.getCurrentLocation();
    print('Main() is executed for $mainCount time(s)');
    mainCount ++;
  } catch(e) {
      print('Error getting current location: $e');
      try {
        await deviceManager.getLastestLocation();
      } catch (e) {
        print('Error getting latest location: $e');
      }
    }


  FlutterError.onError = (FlutterErrorDetails details) {
    runApp(const MaterialApp(
      debugShowCheckedModeBanner: false,
      home: AppErrorScreen(),
    ));
  };


  runApp(
    MultiProvider(
      providers: [
        ChangeNotifierProvider(create: (_) => ConnectionManager()),
        ChangeNotifierProvider(create: (_) => Globals()),
      ],
      child: MyApp(),
    ),
  );
}



class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp.router(
      routerConfig: AppRoute().route,
      localizationsDelegates: AppLocalizations.localizationsDelegates,
      supportedLocales: AppLocalizations.supportedLocales,
      debugShowCheckedModeBanner: false,
    );
  }
}

connection.dart

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

class ConnectionManager with ChangeNotifier {
  final Connectivity _connectivity = Connectivity();
  bool _isConnected = false;
  late StreamSubscription<List<ConnectivityResult>> _subscription;

  bool get isConnected => _isConnected;

  ConnectionManager() {
    _subscription = _connectivity.onConnectivityChanged.listen(_updateConnectionStatus);
    _checkInitialConnection();
  }





  Future<void> _checkInitialConnection() async {
    final List<ConnectivityResult> connectivityResult = await _connectivity.checkConnectivity();
    // await _updateConnectionStatus(connectivityResult);
  }

  Future<void> _updateConnectionStatus(List<ConnectivityResult> result) async {
    bool isConnected = false;

    if (result != ConnectivityResult.none) {
      try {
        final lookupResult = await InternetAddress.lookup('google.com');
        isConnected = lookupResult.isNotEmpty;
      } on SocketException catch (_) {
        isConnected = false;
      }
    }

    _isConnected = isConnected;
    notifyListeners();
  }

I have tried to make the connection check function into a stream however I am new to stream I am not quite sure how can I implement it across the application.

1 Answer 1

1

You can use it like this

Packages

 connectivity_plus: "5.0.0"
 internet_connection_checker:

Code

import 'package:flutter/material.dart';
import 'package:next_app_prototype/features/home/presentation/pages/home_page.dart';
import 'package:provider/provider.dart';
import 'dart:async';
import 'dart:io';
import 'package:connectivity_plus/connectivity_plus.dart';
import 'package:internet_connection_checker/internet_connection_checker.dart';

Future<void> main() async {
  WidgetsFlutterBinding.ensureInitialized();

  runApp(
    MultiProvider(
      providers: [
        ChangeNotifierProvider(create: (_) => ConnectionManager()),
      ],
      child: const MyApp(),
    ),
  );
}

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

  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      home: Scaffold(
        appBar: AppBar(
          title: const Text('Home'),
        ),
        body: Consumer<ConnectionManager>(
          builder: (context, connectionManager, child) {
            if (!connectionManager.isConnected) {
              WidgetsBinding.instance.addPostFrameCallback((_) {
                showDialog(
                  context: context,
                  builder: (context) => AlertDialog(
                    title: const Text('No Internet Connection'),
                    content: const Text('Please check your internet settings.'),
                    actions: <Widget>[
                      TextButton(
                        onPressed: () => Navigator.of(context).pop(),
                        child: const Text('OK'),
                      ),
                    ],
                  ),
                );
              });
            }

            return const HomeScreen();
          },
        ),
      ),
    );
  }
}

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

  @override
  State<HomeScreen> createState() => _HomeScreenState();
}

class _HomeScreenState extends State<HomeScreen> {
  @override
  Widget build(BuildContext context) {
    return const Center(child: Text('Home Page'));
  }
}

class ConnectionManager with ChangeNotifier {
  final Connectivity _connectivity = Connectivity();
  bool _isConnected = true;
  late StreamSubscription<ConnectivityResult> _subscription;
  late StreamSubscription<InternetConnectionStatus> _internetSubscription;

  bool get isConnected => _isConnected;

  ConnectionManager() {
    _subscription = _connectivity.onConnectivityChanged.listen(_updateConnectivityStatus);
    _internetSubscription = InternetConnectionChecker().onStatusChange.listen(_updateInternetStatus);
    _checkInitialConnection();
  }

  Future<void> _checkInitialConnection() async {
    final connectivityResult = await _connectivity.checkConnectivity();
    await _updateConnectivityStatus(connectivityResult);
    final internetResult = await InternetConnectionChecker().hasConnection;
    _updateInternetStatus(internetResult ? InternetConnectionStatus.connected : InternetConnectionStatus.disconnected);
  }

  Future<void> _updateConnectivityStatus(ConnectivityResult result) async {
    _isConnected = result != ConnectivityResult.none;
    if (_isConnected) {
      try {
        final lookupResult = await InternetAddress.lookup('google.com');
        _isConnected = lookupResult.isNotEmpty && lookupResult[0].rawAddress.isNotEmpty;
      } on SocketException catch (_) {
        _isConnected = false;
      }
    }
    notifyListeners();
  }

  Future<void> _updateInternetStatus(InternetConnectionStatus status) async {
    _isConnected = status == InternetConnectionStatus.connected;
    notifyListeners();
  }

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

Not the answer you're looking for? Browse other questions tagged or ask your own question.