I want to check if user has internet connection and want it to be dynamic. Customisable messages will be shown to user according to it.
ElevatedButton(
onPressed: () async {
ans = await InternetConnectionChecker().hasConnection;
print(ans);
},
child: const Text('Fetch Data'),
),
I can check it when clicked on the button by the user but I want it to be automatic when user hops on the home page.
I tried putting
ans = await InternetConnectionChecker().hasConnection;
print(ans);
in initState but it doesn't work. Any suggestions as to how should I improve it?
EDIT :
I tried the first solution and on click of a button I get all the results perfectly
onPressed: () async {
var connectivityResult = await (Connectivity().checkConnectivity());
var subscription = Connectivity()
.onConnectivityChanged
.listen((ConnectivityResult result) {
print("Changed to $result");
});
if (connectivityResult == ConnectivityResult.mobile) {
// I am connected to a mobile network.
print("Mobile");
} else if (connectivityResult == ConnectivityResult.wifi) {
// I am connected to a wifi network.
print("Wifi");
}
},
It shows none when no internet is there. To mobile when connected to mobile hotspot and wifi when connected to wifi network.
But my issue still remains that I want to check internet connection when a user comes to my home page.
I tried this :
var subscription;
#override
initState() async {
super.initState();
print("hlo");
var connectivityResult = await (Connectivity().checkConnectivity());
var subscription = Connectivity()
.onConnectivityChanged
.listen((ConnectivityResult result) {
print("Changed to $result");
});
}
But this doesn't work. What am I dooing wrong? Can i improve this?
This plugin allows Flutter apps to discover network connectivity and configure themselves accordingly. It can distinguish between cellular vs WiFi connection. check here
connectivity_plus 3.0.2
import 'package:connectivity_plus/connectivity_plus.dart';
var connectivityResult = await (Connectivity().checkConnectivity());
if (connectivityResult == ConnectivityResult.mobile) {
// I am connected to a mobile network. }
else if (connectivityResult == ConnectivityResult.wifi) {
// I am connected to a wifi network.
}
You can use connectivity_plus package to check internet connection. The http package that we use to call api can't tell if we don't have internet or the server is down.
class NetworkConnectivity {
NetworkConnectivity._();
static final _instance = NetworkConnectivity._();
static NetworkConnectivity get instance => _instance;
final _networkConnectivity = Connectivity();
final _controller = StreamController.broadcast();
Stream get myStream => _controller.stream;
// 1.
void initialise() async {
ConnectivityResult result = await _networkConnectivity.checkConnectivity();
_checkStatus(result);
_networkConnectivity.onConnectivityChanged.listen((result) {
print(result);
_checkStatus(result);
});
}
// 2.
void _checkStatus(ConnectivityResult result) async {
bool isOnline = false;
try {
final result = await InternetAddress.lookup('example.com');
isOnline = result.isNotEmpty && result[0].rawAddress.isNotEmpty;
} on SocketException catch (_) {
isOnline = false;
}
_controller.sink.add({result: isOnline});
}
void disposeStream() => _controller.close();
}
You can use the following guide: Flutter Internet Connectivity
Related
How to add this feature in Facebook Lite to the Flutter application, where this message appears when the Internet is cut off?
See the image below show image
**
Addition :
Suggest me to add the package connectivity_plus
But Can this package know if Wi-Fi or data are activated, but there is no internet, so the message that there is no internet appears?
With this package https://pub.dev/packages/connectivity_plus
var connectivityResult = await (Connectivity().checkConnectivity());
if (connectivityResult == ConnectivityResult.none) {
showDialog();
}
or you setup a listener and watch yor connectivitiy changes
subscription = Connectivity().onConnectivityChanged.listen((ConnectivityResult result) {
// Got a new connectivity status!
})
Import connectivity_plus package and use below code.
import 'package:connectivity_plus/connectivity_plus.dart';
import 'dart:io';
var connectivityResult = await (Connectivity().checkConnectivity());
if (connectivityResult != ConnectivityResult.mobile && connectivityResult != ConnectivityResult.wifi) {
//Internet is not connected
} else {
// Internet is connected
try {
final result = await InternetAddress.lookup('google.com');
if (result.isNotEmpty && result[0].rawAddress.isNotEmpty) {
print('connected');
}
} on SocketException catch (_) {
print('not connected');
}
}
How to check if connected wi-fi network has internet in the flutter app, when I use connectivityResult == ConnectivityResult.wifi from connectivity 3.0.6 package, it returns true, but the upcoming functionalities won't work if I disabled the wi-fi data connection.
You can check the connection to a web page to make sure you have an internet connection, something like this :
checkConnection() async {
try {
final result = await InternetAddress.lookup('google.com');
if (result.isNotEmpty && result[0].rawAddress.isNotEmpty) {
setState(() {
con = true;
});
}
} on SocketException catch (_) {
setState(() {
con = false;
});
}
}
that's work for me good luck.
I have checked internet connectivity in flutter while calling api in store class like this using 'connectivity' library.
Future<bool> callApi() async {
final isInternet = await Util.checkInternetAndShowDialog(context);
if (isInternet) {
final future = _repository.callApi();
var res = await future;
return true;
}
return false;
}
In Util class network connectivity is been checked like this::
class Util {
static Future<bool> checkInternetAndShowDialog(BuildContext context) async{
var internet = await NetworkConnectivity.rechability();
if (internet == false) {
AlertMessage().showAlertDialog(context, 'error message');
}
return internet;
}
}
In NetworkConnectivity class network connectivity is been checked using Connectivity library.
class NetworkConnectivity {
static Future<bool> rechability() async {
var connectivityResult = await (Connectivity().checkConnectivity());
if (connectivityResult == ConnectivityResult.mobile) {
return true;
} else if (connectivityResult == ConnectivityResult.wifi) {
return true;
}
return false;
}
}
my test cases code is like below:
test('call api successfully', () async {
when(mockStore.callApi()).thenAnswer((realInvocation) => Future.value());
expect(await store.callApi(), true);
});
so while writing unit testing I am facing error of connectivity and method channel.
connectivity error image
Can any one help please me how I can mock for internet connectivity in unit testing and pass the test in flutter. I shall be thankful for this.
I have been searching for long to know the best approach to listen to internet connection in flutter/dart app. I think this approach is better for now and it can be of help to some like me who has been searching. I have used many connectivity plugins, but it didn't work. I have equally used data_connection_checker, lookUpAddress etc as suggested by many but to no avail. But below helped.
Use the below plugins to check or listen to Internet Connection / Network Connectivity in dart, flutter app.
connectivity_plus
internet_connection_checker
import 'dart:async';
import 'package:connectivity_plus/connectivity_plus.dart';
import 'package:internet_connection_checker/internet_connection_checker.dart';
class ConnectionUtil {
static final ConnectionUtil _singleton = new ConnectionUtil._internal();
ConnectionUtil._internal();
static ConnectionUtil getInstance() => _singleton;
bool hasConnection = false;
StreamController connectionChangeController = StreamController();
final Connectivity _connectivity = Connectivity();
void initialize() {
_connectivity.onConnectivityChanged.listen(_connectionChange);
}
void _connectionChange(ConnectivityResult result) {
_hasInternetInternetConnection();
}
Stream get connectionChange => connectionChangeController.stream;
Future<bool> _hasInternetInternetConnection() async {
bool previousConnection = hasConnection;
var connectivityResult = await (Connectivity().checkConnectivity());
if (connectivityResult == ConnectivityResult.mobile || connectivityResult == ConnectivityResult.wifi) {
// this is the different
if (await InternetConnectionChecker().hasConnection) {
hasConnection = true;
} else {
hasConnection = false;
}
} else {
hasConnection = false;
}
if (previousConnection != hasConnection) {
connectionChangeController.add(hasConnection);
}
return hasConnection;
}
}
Implement this code on the stateful widget.....
bool hasInterNetConnection = false;
#override
initState() {
ConnectionUtil connectionStatus = ConnectionUtil.getInstance();
connectionStatus.initialize();
connectionStatus.connectionChange.listen(connectionChanged);
super.initState();
}
void connectionChanged(dynamic hasConnection) {
setState(() {
hasInterNetConnection = hasConnection;
});
}
Good luck
I had faced a similar problem a few weeks ago. This is a good approach. The internet_connection_checker plugin allows one to address issues at the network layer that the connectivity_plus plugin cannot address. I have carried out an implementation of these two plugins using the bloc library. For more information and code refer to this Stackoverflow post and this Github issue.
I want to connect my Flutter app to bluetooth device with flutter_blue library, and return a result (anything) when the connection is ON. But I don't understand how to do.
Here my code :
Future connect(BluetoothDevice device) async {
_btDevice = device;
StreamSubscription<BluetoothDeviceState> subscription;
subscription = device.state.listen((event) async {
if (event != BluetoothDeviceState.connected) {
await device.connect();
} else {
await device.discoverServices().then((value) => _initFeatures(value));
}
})
..onDone(() {
// Cascade
print("onDone");
});
subscription.asFuture();
//subscription.cancel();
}
And when I call this function with
await newDevice.connect(bluetoothDevice).then((value) => print('OK'));
OK is written before the real connection. _initFeatures if well call when the device is connected.
I try to use asFuture from StreamSubscription with onDone, but that change nothing.
Could you help me please ?
UPDATE 12/10
I've worked on another project for few monthes, and when I come back, I can't solve the problem, so I add the full code.
The concept is a class widget calls the connect future in other class and need to receipt the end of work.
Widget
Future<void> _connectDevice() async {
try {
widget.device.connect(widget.btDevice!).then((value) => _initValue());
} catch (e) {
print(e);
}
}
_initValue() is a method to create the rest of the screen
and the Future connect()
Future connect(BluetoothDevice device) async {
_btDevice = device;
StreamSubscription<BluetoothDeviceState> subscription;
subscription = device.state.listen((event) async {
if (event != BluetoothDeviceState.connected) {
await device.connect();
} else {
await device
.discoverServices()
.then((value) => _initFeatures(value))
.then((value) => print("OK"));
}
});
await subscription.asFuture();
await subscription.cancel();
}
What I'd like is the Future finishes when print("OK") is called, in order .then((value) => _initValue()); is called.
The problem is only this end. Maybe it's not the good way to implement this kind of solution.