Hi I am using riverpod to check internet connectivity across the app however the state notifier is giving intial state value only or shoul I saw its value is not changing. Also yes I am updating state you can see it in the code.
InternetProvider.dart:
import 'package:internet_connection_checker_plus/internet_connection_checker_plus.dart';
import 'package:riverpod/riverpod.dart';
class ConnectivityStatusNotifier extends StateNotifier<bool> {
ConnectivityStatusNotifier() : super(false);
void checkInternet() {
final listener =
InternetConnection().onStatusChange.listen((InternetStatus status) {
if (status == InternetStatus.connected) {
state = true;
}
else{
state = false;
}
});
}
}
final connectivityProvider =
StateNotifierProvider<ConnectivityStatusNotifier, bool>((ref) {
return ConnectivityStatusNotifier();
});
In HomeScreen.dart:
final internet = ref.watch(connectivityProvider);
final Widget floatingActionButton = FloatingActionButton(
onPressed: () {
print(internet);
},
child: const Icon(Icons.chat),
);
whether the internet is connected or not its always false
I tried this with connectivity_plus package as well but it also didn't worked. I have also tried this:medium.com this also didn't worked,this one also provides inital state as well which is connectivitystatus.connected.
First of all, when using the internet_connection_checker_plus package, you need to give permissions on the platforms:
-> Android
Add the following permissions to your AndroidManifest.xml
file:
<uses-permission android:name="android.permission.INTERNET" />
-> macOS
Add the following permissions to your macOS .entitlements
files:
<key>com.apple.security.network.client</key>
<true/>
Then I rethought your code a bit and wrote another one, more reactive and using Notifier
instead of the legacy StateNotifier
:
final connectivityProvider = NotifierProvider<ConnectivityStatusNotifier, bool>(
ConnectivityStatusNotifier.new,
);
class ConnectivityStatusNotifier extends Notifier<bool> {
late InternetConnection _internetConnection;
@override
bool build() {
_internetConnection = InternetConnection();
final stream = _internetConnection.onStatusChange.listen(_statusListener);
ref.onDispose(() {
stream.cancel();
});
return false;
}
void _statusListener(InternetStatus status) {
switch (status) {
case InternetStatus.connected:
state = true;
case InternetStatus.disconnected:
state = false;
}
}
}
Now you can do something in the interface to just listen
for changes to the connectivityProvider
. If desired, you can add an action button to snack:
class MyApp extends ConsumerWidget {
const MyApp({super.key});
@override
Widget build(BuildContext context, WidgetRef ref) {
ref.listen(connectivityProvider, (_, isConnected) {
if (!isConnected) {
ScaffoldMessenger.of(context).showSnackBar(
const SnackBar(content: Text('No internet connection')),
);
}
});
return const Text('Next are other widgets');
}
}
It's not very clear in your code when you call checkInternet
. The problem is that if you call it several times without canceling the previous subscription, you will get a small memory leak :) I assume that maybe you forgot to call this function altogether)