Flutter how to check Internet connection is available or not - flutter

I am trying to use this plugin https://pub.dev/packages/connectivity/example Issue is its not showing or print internet is connected or not.
This is my code
class _HomePageState extends State<HomePage> {
String _connectionStatus = 'Unknown';
final Connectivity _connectivity = Connectivity();
StreamSubscription<ConnectivityResult> _connectivitySubscription;
#override
void initState() {
super.initState();
initConnectivity();
_connectivitySubscription =
_connectivity.onConnectivityChanged.listen(_updateConnectionStatus);
WidgetsBinding.instance.addPostFrameCallback((timeStamp) {
if (mounted) {
if (userManager.getCurrentDriver() != null &&
userManager.getCurrentDriver().isNotEmpty) {
FirebaseFirestore.instance
.collection(FIREBASE_PATH_TRIP)
.doc(userManager.getCurrentDriver())
.get()
.then((event) {
if (event != null) {
var trip =
DriverModel.fromMap(Map<String, dynamic>.from(event.data()));
Provider.of<TripState>(context, listen: false).driver = trip;
Provider.of<BottomSheetSelector>(context, listen: false)
.changeSheet(SheetType.Profile);
} else {
userManager.saveCurrentDriver('');
}
});
}
if (Theme.of(context).platform == TargetPlatform.android) {
checkForAndroidUpdate(context);
}
}
});
}
#override
void dispose() {
_connectivitySubscription.cancel();
super.dispose();
}
Future<void> initConnectivity() async {
ConnectivityResult result;
// Platform messages may fail, so we use a try/catch PlatformException.
try {
result = await _connectivity.checkConnectivity();
} on PlatformException catch (e) {
print(e.toString());
}
// 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);
}
#override
Widget build(BuildContext context) {
final _drawerKey = GlobalKey<ScaffoldState>();
ScreenUtil.init(context);
return SafeArea(
child: WillPopScope(
child: Scaffold(
key: _drawerKey,
backgroundColor: Colors.black,
resizeToAvoidBottomInset: false,
drawer: ViteDrawer(),
body: null,
),
));
}
Future<void> _updateConnectionStatus(ConnectivityResult result) async {
switch (result) {
case ConnectivityResult.wifi:
case ConnectivityResult.mobile:
case ConnectivityResult.none:
setState(() => _connectionStatus = result.toString());
break;
default:
setState(() => _connectionStatus = 'Failed to get connectivity.');
break;
}
}
}
What i need to do is simple print if internet is connected or not. I want to show alert but print is ok so ill manage it. But dont know why its not printing anything

You can try with this
Future<bool> check() async {
var connectivityResult = await (Connectivity().checkConnectivity());
if (connectivityResult == ConnectivityResult.mobile) {
print("Connected}");
return true;
} else if (connectivityResult == ConnectivityResult.wifi) {
print("Connected}");
return true;
}
print("not Connected}");
// return You can add your dialog for notify user to your connectivity is off
}

you can use below code to check the connectivity
Future<bool> checkInternetConnectivity() async {
try {
final result = await InternetAddress.lookup('google.com');
if (result.isNotEmpty && result[0].rawAddress.isNotEmpty) {
return true;
} else {
return false;
}
} on SocketException catch (_) {
return false;
}
}

simple
Future<bool> isConnected() async {
var result = await Connectivity().checkConnectivity();
return result != ConnectivityResult.none;
}

Related

Difference between Buildcontext and NavigatorKey.currentState.context

I'm currently using Provider as state management and also to keep all my function in it. At first i was using a callback method for me to to navigate thru screen when function in my Provider class succeed.
Future login(String email, String password, Function callback) async {
_isLoading = true;
notifyListeners();
bool isSuccess = false;
try {
final ApiResponse apiResponse = await authRepo!.login(email, password);
if (apiResponse.response != null && apiResponse.response!.statusCode == 200) {
isSuccess = true;
callback(isSuccess, apiResponse.response!.data[Constants.responseMsg]);
} else {
callback(isSuccess, apiResponse.error);
}
} catch (e) {
_isLoading = false;
print('login error: $e');
notifyListeners();
rethrow;
}
_isLoading = false;
notifyListeners();
}
but then i realized i could just pass the Buildcontext and navigating inside the function itself without using a callback method.
Future login(String email, String password, BuildContext context) async {
_isLoading = true;
notifyListeners();
try {
final ApiResponse apiResponse = await authRepo!.login(email, password);
if (apiResponse.response != null && apiResponse.response!.statusCode == 200) {
Navigator.of(context).pushReplacement(
MaterialPageRoute(
builder: (BuildContext context) => DashboardScreen(),
settings: RouteSettings(name: '/Dashboard'),
),
);
} else {
GlobalFunction.showToast(apiResponse.error);
}
} catch (e) {
_isLoading = false;
print('login error: $e');
notifyListeners();
rethrow;
}
_isLoading = false;
notifyListeners();
}
and then i also realize i could use NavigatorKey.currentState!.context to navigate so i dont need the pass the Buildcontext.
Future login(String email, String password) async {
_isLoading = true;
notifyListeners();
try {
final ApiResponse apiResponse = await authRepo!.login(email, password);
if (apiResponse.response != null && apiResponse.response!.statusCode == 200) {
BuildContext _context = navigatorKey.currentState!.context;
Navigator.of(_context).pushReplacement(
MaterialPageRoute(
builder: (BuildContext context) => DashboardScreen(),
settings: RouteSettings(name: '/Dashboard'),
),
);
} else {
GlobalFunction.showToast(apiResponse.error);
}
} catch (e) {
_isLoading = false;
print('login error: $e');
notifyListeners();
rethrow;
}
_isLoading = false;
notifyListeners();
}
i wonder which one is the better way?

Flutter dart async await not working as expected

I am trying to check the internet connection of the mobile device. I am using below code to check the connectivity.
import 'package:flutter/material.dart';
import 'package:internet_connection_checker/internet_connection_checker.dart';
class RedirectPage extends StatelessWidget {
final int? status;
#override
Widget build(BuildContext context) {
bool? isDeviceConnected;
() async {
print("a");
print(123);
isDeviceConnected = await checkConnection();
print(888);
};
if (isDeviceConnected != null && isDeviceConnected == false) {
return AppNetworkConnectivityHome();
} else{
return HomePage();
}
}
}
print(isDeviceConnected); //giving null for the first time and true or false on the second time.
Future<bool?> checkConnection() async {
bool a = false;
a = await InternetConnectionChecker().hasConnection;
print(a);
return a;
}
how to force wait for the await function to complete
You'd have to await the method call. You've currently defined it as an anonymous function, so depending on where and how you execute it there will be some differences. But it will work if you instead do something like this:
Future<bool?> myMethod() async {
return await InternetConnectionChecker().hasConnection;
}
...
print(await myMethod());
You can't call async function in build method, you need to use FutureBuilder like this:
return FutureBuilder<bool>(
future: checkConnection(),
builder: (context, snapshot) {
switch (snapshot.connectionState) {
case ConnectionState.waiting:
return Text('Loading....');
default:
if (snapshot.hasError) {
return Text('Error: ${snapshot.error}');
} else {
bool data = snapshot.data ?? true;
if (!data) {
return AppNetworkConnectivityHome();
} else{
return HomePage();
}
}
}
},
)

PagedListView shows CircularProgressIndicator in flutter web

I used infinite_scroll_pagination: ^3.2.0 to implement pagination in the flutter web.
I got response from API but in UI it still shows CircularProgressIndicator. I am using GetX .
UI part is,
PagedListView<int, dynamic>(
pagingController:
collectionController.pagingControllerLibraryDetails,
shrinkWrap: true,
builderDelegate:
PagedChildBuilderDelegate<dynamic>(
itemBuilder: (context, item, indexs) {
return Obx(
() {
return
Text(collectionController.libraryAllContentResponse2.value.data!.rows![indexs].categoryName.toString());
}
);
},
noItemsFoundIndicatorBuilder: (_) =>
CollectionEmptyScreen()))
Api call in Getxcontroller,
final PagingController<int, dynamic> pagingControllerLibraryDetails=
PagingController(firstPageKey: 1);
getLibInsideContent(
pages
) async {
try {
SharedPreferences pref = await SharedPreferences.getInstance();
libraryAllContentRequest. page= pages;
libraryAllContentRequest.pageSize = 10;
libraryAllContentRequest.loggedInUserID = pref.getString("userId");
qry.libraryId = libraryId.value;
libraryAllContentRequest.query = Query(libraryId:libraryId.value
);
try {
var res = await libraryProvider
.getAllLibContent(libraryAllContentRequest.toJson());
if (res.statusCode == 200) {
try {
LibraryAllContentResponse libraryAllContentResponse =
LibraryAllContentResponse.fromJson(res.body);
if (libraryAllContentResponse2.value.data != null) {
final isLastPage = int.parse(libraryAllContentResponse.data!.rows!.length.toString())< 10;
if(isLastPage){
pagingControllerLibraryDetails.appendLastPage(
libraryAllContentResponse.data!.rows!,
);
}
else{
final nextPageKey = pages +1;
pagingControllerLibraryDetails.appendPage( libraryAllContentResponse.data!.rows!, nextPageKey);
}
libraryAllContentResponse.data!.rows!.forEach((element) {
if (!libraryAllContentResponse2.value.data!.rows!.contains(element)) {
libraryAllContentResponse2.value.data!.rows!.add(element);
}
});
} else {
libraryAllContentResponse2.value = libraryAllContentResponse;
}
return libraryAllContentResponse;
} on Exception catch (e) {
// print(e);
return e;
}
}
Get.snackbar('Loding', 'Issue');
return null;
} on Exception catch (e) {
return "e";
}
} on Exception catch (e) {
}
}
I called getLibInsideContent(pages) functions in the success response of another api calls.(getLibInsideContent(1);)
Issue resolved.
Added listener in initstate();
#override
void onInit() {
pagingControllerLibraryDetails.addPageRequestListener((page) => getLibInsideContent(page));
super.onInit();
}

The return type 'SignUpScreen' isn't a 'void', as required by the closure's context

I'm trying to build a funtion who return Widget for persiting state but I am getting this error.
Future<Widget?> persiting () async {
await FirebaseAuth.instance
.authStateChanges()
.listen((User? user) {
if (user == null) {
return SignUpScreen() ;
} else {
return HomeScreen() ;
}
});
}
try this:
Future<Widget?> persiting () async {
late bool hasUsers;
await FirebaseAuth.instance
.authStateChanges()
.listen((User? user) {
if (user == null) {
hasUsers = true;
} else {
hasUsers = false;
}
});
return hasUsers ? SignUpScreen() : HomeScreen();
}
The exception showed because you are returning onject to the .listen() function instead of the persiting() function.
What you need to do is await to listen the stream inside the presiting() function.
Future<Widget?> persiting () async {
try{
Stream<User?> stream = await FirebaseAuth.instance
.authStateChanges();
bool hasUser = false;
await stream.forEach((user){
hasUser = user != null;
});
return hasUser? HomeScreen() : SignUpScreen();
}catch(e){
/// better do some handling if any network or unexpected error here
}
}

Show dialog using Scoped model

I have a basic login form, with my LoginModel.
But I do not understand how I can call to the function notifyListeners to display a dialog in my view.
The login widget:
#override
Widget build(BuildContext context) {
return new Scaffold(
body: new ScopedModel<LoginModel>(
model: _loginModel,
child: Center(child: ScopedModelDescendant<LoginModel>(
builder: (context, child, model) {
if (model.status == Status.LOADING) {
return Loading();
}
else return showForm(context);
}))));
}
And the login model:
class LoginModel extends Model {
Status _status = Status.READY;
Status get status => _status;
void onLogin(String username, String password) async {
_status = Status.LOADING;
notifyListeners();
try {
await api.login();
_status = Status.SUCCESS;
notifyListeners();
} catch (response) {
_status = Status.ERROR;
notifyListeners();
}
}
I need to display a dialog when the status is Error
Finally I got this, just returning a Future in the method onLogin
Future<bool> onLogin(String username, String password) async {
_status = Status.LOADING;
notifyListeners();
try {
await api.login();
_status = Status.SUCCESS;
notifyListeners();
return true;
} catch (response) {
_status = Status.ERROR;
notifyListeners();
return false;
}
}
And in the widget:
onPressed: () async {
bool success = await _loginModel.onLogin(_usernameController.text, _passwordController.text);
if(success) {
Navigator.pop(context, true);
}
else{
_showDialogError();
}
}