I have used connectivity_plus
and internet_connection_checker
packages to check the internet connectivity.
The problem occured is , the app works perfectly fine as expected when the app start's with internet on state. But when the app is opened with internet off, the dialog isn't shown !!
I assume this is happening because the build method is called before the stream of internet is listened.
Code :
class _HomePageState extends State<HomePage> {
late StreamSubscription subscription;
bool isDeviceConnected = false;
bool isAlertSet = false;
@override
void initState() {
getConnectivity();
super.initState();
}
getConnectivity() {
subscription = Connectivity().onConnectivityChanged.listen(
(ConnectivityResult result) async {
isDeviceConnected = await InternetConnectionChecker().hasConnection;
if (!isDeviceConnected && isAlertSet == false) {
showDialogBox();
setState(() {
isAlertSet = true;
});
}
},
);
}
@override
void dispose() {
subscription.cancel();
super.dispose();
}
@override
Widget build(BuildContext context) {
return Scaffold(
...
);
}
showDialogBox() => showDialog(/* no internet dialog */)
Extending the question: Is it assured that this works for all the pages ?
- if yes, how ?
- if not , how to overcome this?
CodePudding user response:
First of all you need to listen for internet connectivity in your app first screen which is probably app.dart
GlobalKey<NavigatorState> navigatorKey = GlobalKey(); final noInternet = NoInternetDialog(); class TestApp extends StatefulWidget { @override State<TestApp> createState() => _TestAppState(); } class _TestAppState extends State<TestApp> { @override void initState() { super.initState(); checkInternetConnectivity(); } @override Widget build(BuildContext context) { return MaterialApp(...); } Future<void> checkInternetConnectivity() async { Connectivity().onConnectivityChanged.getInternetStatus().listen((event) { if (event == InternetConnectionStatus.disconnected) { if (!noInternet.isShowing) { noInternet.showNoInternet(); } } }); } }
Make the screen stateful in which you are calling MaterialApp and in initState of that class check for your internet connection, like above
You are saying how can I show dialog when internet connection changes for that you have to create a Generic class or extension which you can on connectivity change. You have to pass context to that dialogue using NavigatorKey
class NoInternetDialog { bool _isShowing = false; NoInternetDialog(); void dismiss() { navigatorKey.currentState?.pop(); } bool get isShowing => _isShowing; set setIsShowing(bool value) { _isShowing = value; } Future showNoInternet() { return showDialog( context: navigatorKey.currentState!.overlay!.context, barrierDismissible: true, barrierColor: Colors.white.withOpacity(0), builder: (ctx) { setIsShowing = true; return AlertDialog( elevation: 0, backgroundColor: Colors.transparent, insetPadding: EdgeInsets.all(3.0.h), content: Container(...), ); }, ); } }
CodePudding user response:
Use checkConnectivity to check current status. Only changes are exposed to the stream.
final connectivityResult = await Connectivity().checkConnectivity();