How to check internet connectivity globally with routers?

29 views Asked by At

How can we check internet connectivity? I can check with Streambuilder but how to achieve this with routers? The problem is we can not use async await in this.

If anyone can suggest anything on this will be much appreciated. OnGenerateRoute we can check the provided route. As in code, I passed the _connectivityStatus to check and route to no internet screen but that is not working.

class MyProjectAppScreen extends ConsumerStatefulWidget {
  const MyProjectAppScreen({super.key});
  @override
  ConsumerState<MyProjectAppScreen> createState() {
    return _MyProjectAppScreenState();
  }
}

class _MyProjectAppScreenState extends ConsumerState<MyProjectAppScreen> {
  ConnectivityResult _connectionStatus = ConnectivityResult.none;
  final Connectivity _connectivity = Connectivity();
  late StreamSubscription<ConnectivityResult> _connectivitySubscription;

  // Platform messages are asynchronous, so we initialize in an async method.
  Future<void> initConnectivity() async {
    late ConnectivityResult result;
    // Platform messages may fail, so we use a try/catch PlatformException.
    try {
      result = await _connectivity.checkConnectivity();
    } on PlatformException catch (e) {
      developer.log('Couldn\'t check connectivity status', error: e);
      return;
    }

    // If the widget was removed from the tree while the asynchronous platform
    // message was in flight, we want to discard the reply rather than calling
    // setState to update our non-existent appearance.
    if (!mounted) {
      return Future.value(null);
    }

    return _updateConnectionStatus(result);
  }

  Future<void> _updateConnectionStatus(ConnectivityResult result) async {
    print(result);
    setState(() {
      _connectionStatus = result;
    });
  }

  @override
  void initState() {
    initConnectivity();
    _connectivitySubscription =
        _connectivity.onConnectivityChanged.listen(_updateConnectionStatus);
    super.initState();
  }



@override
  Widget build(BuildContext context) {
    String appRoot = splash;
    return MaterialApp(
      title: 'My Project',
      theme: theme_data.ManageTheme().getTheme(context),
      darkTheme: theme_data.ManageTheme().getDarkTheme(context),
      themeMode: ThemeMode.light,
      initialRoute: appRoot,
      onGenerateRoute: (settings) => generateRoute(settings, _connectionStatus),
      debugShowCheckedModeBanner: false,
    );
  }

}

How to achieve this in globally?

1

There are 1 answers

2
Manoj Reddy On

I am able to display a No Internet screen whenever there is no internet with this code. Additionally, I have added a few TODO statements, please review them.

import 'dart:async';

import 'package:connectivity_plus/connectivity_plus.dart';
import 'package:flutter/material.dart';
import 'package:flutter/services.dart';

void main() {
  runApp(const MyApp());
}

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

  // This widget is the root of your application.
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Flutter Demo',
      theme: ThemeData(
        colorScheme: ColorScheme.fromSeed(seedColor: Colors.deepPurple),
        useMaterial3: true,
      ),
      home: const MyProjectAppScreen(),
    );
  }
}

class MyProjectAppScreen extends StatefulWidget {
  const MyProjectAppScreen({super.key});
  @override
  State<MyProjectAppScreen> createState() {
    return _MyProjectAppScreenState();
  }
}

class _MyProjectAppScreenState extends State<MyProjectAppScreen> {
  ConnectivityResult _connectionStatus = ConnectivityResult.none;
  final Connectivity _connectivity = Connectivity();
  late StreamSubscription<ConnectivityResult> _connectivitySubscription;

  // Platform messages are asynchronous, so we initialize in an async method.
  Future<void> initConnectivity() async {
    late ConnectivityResult result;
    // Platform messages may fail, so we use a try/catch PlatformException.
    try {
      result = await _connectivity.checkConnectivity();
    } on PlatformException catch (e) {
      print('Couldn\'t check connectivity status:$e');
      return;
    }

    // If the widget was removed from the tree while the asynchronous platform
    // message was in flight, we want to discard the reply rather than calling
    // setState to update our non-existent appearance.
    if (!mounted) {
      return Future.value(null);
    }

    return _updateConnectionStatus(result);
  }

  Future<void> _updateConnectionStatus(ConnectivityResult result) async {
    print(result);

    ///TODO: Actually, `setState` is not required here since we are not updating anything in the UI.
    _connectionStatus = result;
  }

  @override
  void initState() {
    initConnectivity();
    _connectivitySubscription =
        _connectivity.onConnectivityChanged.listen(_updateConnectionStatus);
    super.initState();
  }

  @override
  void dispose() {
    _connectivitySubscription.cancel();

    super.dispose();
  }

  ///TODO: Move this function to a separate file, as you will have multiple routes in your application.
  Route<dynamic> generateRoute(
      RouteSettings settings, ConnectivityResult connectionStatus) {
    ///TODO: Based on the route name, you can decide which widget to attach.
    // switch (settings.name!.replaceAll('?', '')) {
    //   case 'route1':
    //     break;
    //   case 'route2':
    //     break;
    // }

    /// Check if there is a network failure or not.
    return MaterialPageRoute(
      settings: settings,
      builder: (BuildContext context) =>
          _connectionStatus == ConnectivityResult.none
              ? const NoInternet()
              : const SecondScreen(),
    );
  }

  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'My Project',
      // theme: theme_data.ManageTheme().getTheme(context),
      // darkTheme: theme_data.ManageTheme().getDarkTheme(context),
      themeMode: ThemeMode.light,
      // initialRoute: appRoot,
      routes: {
        '/': (context) => const FirstScreen(),
      },
      onGenerateRoute: (settings) => generateRoute(settings, _connectionStatus),
      debugShowCheckedModeBanner: false,
    );
  }
}

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

  @override
  Widget build(BuildContext context) {
    return Material(
      child: Container(
        color: Colors.white,
        child: const Center(
          child: Text(
            "t seems like there's a problem connecting to the internet right now",
          ),
        ),
      ),
    );
  }
}

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

  @override
  Widget build(BuildContext context) {
    return Material(
      child: Container(
        color: Colors.white,
        child: Center(
          child: ElevatedButton(
            onPressed: () {
              Navigator.pushNamed(context, '/second');
            },
            child: const Text("Navigate"),
          ),
        ),
      ),
    );
  }
}

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

  @override
  Widget build(BuildContext context) {
    return Material(
      child: Container(
        color: Colors.white,
        child: const Center(
          child: Text("Second screen"),
        ),
      ),
    );
  }
}