I have a website and I converted that website into flutter android application using webview_flutter plugin, everything is working fine.
But there is an issue, there is a form on website in which there is a file input in the form. On website everything works fine but when I click on upload file from android application which I created using webview_flutter plugin, the file input dose not works.
When I click on upload file, it dose not open any popup or anything to allow me to select file from my phone and to upload into the form.
This is my main.dart code:
import 'package:flutter/material.dart';
import 'package:permission_handler/permission_handler.dart';
import 'package:webview_flutter/webview_flutter.dart';
import 'package:custom_splash/custom_splash.dart';
import 'package:connectivity/connectivity.dart';
import 'package:selfcare/nointernet.dart';
void main() {
WidgetsFlutterBinding.ensureInitialized();
runApp(MyApp());
}
class MyApp extends StatelessWidget {
#override
Widget build(BuildContext context) {
return MaterialApp(
title: "Self Care",
debugShowCheckedModeBanner: false,
theme: ThemeData(
primarySwatch: Colors.red,
),
home: Scaffold(body: splash()));
}
}
class splash extends StatefulWidget {
#override
_splashState createState() => _splashState();
}
class _splashState extends State<splash> {
String result = '';
var Colorsval = Colors.white;
#override
void initState() {
CheckStatus();
super.initState();
}
#override
Widget build(BuildContext context) {
if (result != null && result == "Connected") {
return CustomSplash(
//backGroundColor: Color(0xFFFF9800),
imagePath: "assets/images/logo.png",
home: WebViewClass(),
duration: 10,
animationEffect: "zoom-in",
);
} else if (result != null && result == "NoInternet") {
return CustomSplash(
//backGroundColor: Color(0xFFFF9800),
imagePath: "assets/images/logo.png",
home: NoInternetPage(),
duration: 10,
animationEffect: "zoom-in",
);
} else if (result == null) {
return CustomSplash(
//backGroundColor: Color(0xFFFF9800),
imagePath: "assets/images/logo.png",
home: NoInternetPage(),
duration: 10,
animationEffect: "zoom-in",
);
} else {
return CustomSplash(
//backGroundColor: Color(0xFFFF9800),
imagePath: "assets/images/logo.png",
home: NoInternetPage(),
duration: 10,
animationEffect: "zoom-in",
);
}
}
void CheckStatus() {
Connectivity().onConnectivityChanged.listen((ConnectivityResult result) {
if (result == ConnectivityResult.mobile ||
result == ConnectivityResult.wifi) {
ChangeValues("Connected", Colors.green[900]);
} else {
ChangeValues("NoInternet", Colors.red[900]);
}
});
}
void ChangeValues(String resultval, Color colorval) {
setState(() {
result = resultval;
Colorsval = colorval;
});
}
}
class WebViewClass extends StatefulWidget {
WebViewState createState() => WebViewState();
}
class WebViewState extends State<WebViewClass> {
num position = 1;
final key = UniqueKey();
doneLoading(String A) {
setState(() {
position = 0;
});
}
startLoading(String A) {
setState(() {
position = 1;
});
}
#override
void initState() {
// TODO: implement initState
super.initState();
Permission.mediaLibrary.request();
Permission.phone.request();
Permission.photos.request();
Permission.storage.request();
Permission.camera.request();
}
//Check Internet Code Starts
//Check Internet Code Ended here
#override
Widget build(BuildContext context) {
return Scaffold(
//appBar: AppBar(title: Text('Show ProgressBar While Loading Webview')),
appBar: PreferredSize(
child: Container(),
preferredSize: Size.fromHeight(0.0),
),
body: IndexedStack(index: position, children: <Widget>[
WebView(
initialUrl: 'http://mywebsite.com',
javascriptMode: JavascriptMode.unrestricted,
key: key,
onPageFinished: doneLoading,
onPageStarted: startLoading,
//onWebResourceError: ,
),
Container(
color: Colors.white,
child: Center(
child: CircularProgressIndicator(
valueColor: new AlwaysStoppedAnimation<Color>(Colors.red),
)),
),
]));
}
}
And this is the flutter webview plugin I used:
dependencies:
webview_flutter: ^1.0.7
I also used some permissions to get rid of this problem but not solved it, the permissions:
Permission.mediaLibrary.request();
Permission.phone.request();
Permission.photos.request();
Permission.storage.request();
Permission.camera.request();
webview_flutter plugin has yet to have support for file upload. You can track the currently open ticket related to this issue here. In the meantime, you can use either flutter_inappwebview or flutter_webview_plugin as a workaround.
Since webview_flutter 4.0.2 you can easily do it, as support for Android was just added.
In order to achieve this, you'd have to first check if the platform it's running on is Android and then set your custom listener:
if (Platform.isAndroid) { // or: if (webViewController.platform is AndroidWebViewController)
final myAndroidController = webViewController.platform as AndroidWebViewController;
myAndroidController.setOnShowFileSelector( (params) {
// Control and show your picker
// and return a list of Uris.
return []; // Uris
}
}
I managed to get this working using the webview_flutter_pro plugin. I've posted details about how to get it to work here:
How to open file picker from gallery or camera android in webview_flutter?
Related
I am listing different files from device storage with changing extension i followed this link for getting files
link
getting files from device
function for getting files
var files;
Future <void> getFiles() async {
if (await Permission.storage.request().isGranted) {
// Either the permission was already granted before or the user just granted it.
}
//asyn function to get list of files
List<StorageInfo> storageInfo = await PathProviderEx.getStorageInfo();
var root = storageInfo[0]
.rootDir; //storageInfo[1] for SD card, geting the root directory
var fm = FileManager(root: Directory(root)); //
files = await fm.dirsTree(
excludedPaths: ["/storage/emulated/0/Android"],
//optional, to filter files, list only pdf files
);
setState(() {}); //update the UI
}
#override
void initState() {
getFiles(); //call getFiles() function on initial state.
super.initState();
}
body
body:files == null? Text("Searching Files"):
ListView.builder( //if file/folder list is grabbed, then show here
itemCount: files?.length ?? 0,
itemBuilder: (context, index) {
return Card(
child:ListTile(
title: Text(files[index].path.split('/').last),
// trailing: Icon(Icons.play_arrow, color:
Colors.redAccent,),
onTap: (){
}
Use This :
dependencies:
syncfusion_flutter_pdfviewer: ^20.3.59
Example:
import 'package:flutter/material.dart';
import 'package:syncfusion_flutter_pdfviewer/pdfviewer.dart';
void main() {
runApp(MaterialApp(
title: 'Syncfusion PDF Viewer Demo',
home: HomePage(),
));
}
/// Represents Homepage for Navigation
class HomePage extends StatefulWidget {
#override
_HomePage createState() => _HomePage();
}
class _HomePage extends State<HomePage> {
final GlobalKey<SfPdfViewerState> _pdfViewerKey = GlobalKey();
#override
void initState() {
super.initState();
}
#override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: const Text('Syncfusion Flutter PDF Viewer'),
actions: <Widget>[
IconButton(
icon: const Icon(
Icons.bookmark,
color: Colors.white,
semanticLabel: 'Bookmark',
),
onPressed: () {
_pdfViewerKey.currentState?.openBookmarkView();
},
),
],
),
body: SfPdfViewer.network(
'https://cdn.syncfusion.com/content/PDFViewer/flutter-succinctly.pdf',
key: _pdfViewerKey,
),
);
}
}
From Local Storage :
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE"/>
Step 2: Mention the PDF file path while creating the SfPdfViewer widget as shown in the following code.
#override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: const Text('Syncfusion Flutter PDF Viewer'),
),
body: SfPdfViewer.file(
File('storage/emulated/0/Download/gis_succinctly.pdf'),
),
);
}
I have a small app here, i will check buildNumber of current app and compare to my remote api data, based on this condition i will show the user interfaces.
I have home and updateApp screen where home is the normal webview screen and UpdateApp is a screen where user is required to update the new version of my app.
But condition satisfies but update screen is not showing.
// ignore_for_file: prefer_const_constructors, prefer_const_literals_to_create_immutables, use_build_context_synchronously, unrelated_type_equality_checks, unused_element
import 'dart:async';
import 'dart:io';
import 'package:flutter/material.dart';
import 'package:flutter/services.dart';
import 'package:flutter_webview_plugin/flutter_webview_plugin.dart';
import 'package:webview_test/models/app_version.dart';
import 'package:webview_test/services/remote_service.dart';
import 'package:webview_test/views/update_app.dart';
import 'package:package_info_plus/package_info_plus.dart';
void main() {
runApp(MyHomePage());
}
class MyHomePage extends StatefulWidget {
#override
State<MyHomePage> createState() => _MyHomePageState();
}
class _MyHomePageState extends State<MyHomePage> {
final flutterWebViewPlugin = FlutterWebviewPlugin();
bool isLoading = true;
double webProgress = 0;
bool isLoaded = false;
List<AppVersion>? appVersions;
int buildNumber = 0;
late String packageName;
#override
#override
void initState() {
super.initState();
flutterWebViewPlugin.onProgressChanged.listen((double progress) {
setState(() {
this.webProgress = progress;
});
print("The progress is $progress");
});
getVersions();
getBuild();
}
//Fetching remote data for app versions.
getVersions() async {
appVersions = await RemoteService().getAppVersion();
if (appVersions != null) {
setState(() {
isLoaded = true;
});
}
}
//getting app information to compare remote app versions.
getBuild() async {
PackageInfo packageInfo = await PackageInfo.fromPlatform();
packageName = packageInfo.packageName;
buildNumber = int.parse(packageInfo.buildNumber);
print("build number is $buildNumber");
if (buildNumber == 1) {
print("Build number is $buildNumber");
}
}
#override
Widget build(BuildContext context) {
SystemChrome.setSystemUIOverlayStyle(const SystemUiOverlayStyle(
systemNavigationBarColor: Colors.white,
systemNavigationBarIconBrightness: Brightness.dark));
return MaterialApp(
home: buildNumber == 1
? proceedToUpdate(context)
: SafeArea(
child: Scaffold(
body: WillPopScope(
onWillPop: () async {
if (await flutterWebViewPlugin.canGoBack()) {
flutterWebViewPlugin.goBack();
return false;
} else {
SystemNavigator.pop();
return true;
}
},
child: Stack(
children: [
Positioned.fill(
child: Column(
children: [
webProgress < 1
? SizedBox(
height: 5,
child: LinearProgressIndicator(
value: webProgress,
color: Colors.blue,
backgroundColor: Colors.white,
),
)
: SizedBox(),
Expanded(
child: WebviewScaffold(
url: "https://google.com",
mediaPlaybackRequiresUserGesture: false,
withLocalStorage: true,
),
),
// isLoading
// ? Center(
// child: CircularProgressIndicator(),
// )
// : Stack(),
],
),
),
],
)),
),
),
);
}
proceedToUpdate(context) {
Navigator.of(context)
.push(MaterialPageRoute(builder: (context) => UpdateApp()));
}
}
Your variable context in Navigator.of(context).push(...) isn't correct.
You're trying to navigate outside build(BuildContext context), so it won't work. Function build(BuildContext context) is the place where it build your mobile interface - UI screen.
Now in your StatefulWidget MyHomePage -> initState() -> getBuild() -> _proceedToUpdate() -> Navigator.of(context).push(...). The variable context in your Navigator command is not context of your screen UI. Even though function _proceedToUpdate() can run, it cannot navigate.
You may try to show an dialog. Each dialog also has a context. You can show an dialog and then navigate to somewhere when press "OK" button. It'll success.
Good luck!
Update:
Seems like you don't want to show any dialog, therefore we need another approach. You could check the build version in main() async {}. Then pass value buildNumber to somewhere (directly pass to MyApp() or use singleton to make it more professional :D). Then you can make it like: home: _getFirstScreen()
_getFirstScreen() {
if (buildNumber == 1) return UpdateScreen();
else return MyHomePage();
}
I am trying to use the BLoC library with the connectivity_plus plugin in Flutter. I have followed this post and this post to set up an Internet Cubit for the project. The code works fine when the app is started with the internet connection turned on.
However, with the internet connection turned off, if I kill the app and re-launch it or do a hot restart, the CircularProgressIndicator() is shown instead of Text("Internet Disconnected").
Turning the internet back on correctly shows Text("Internet Connected") widget. After this, If I turn off the internet connection again, this time around it correctly shows the Text("Internet Disconnected") widget.
Also, emitInternetDisconnected is not caught as an exception in the try catch block to update the app's state.
The problem with the CircularProgressIndicator() being always displayed with the internet disconnected occurs only when the app is re-launched or hot restarted. I cannot figure out the bug in my code. What should I do to fix my code? Thanks
This is the code in the internet_cubit.dart file
import 'dart:async';
import 'dart:io';
import 'package:bloc/bloc.dart';
import 'package:connectivity_plus/connectivity_plus.dart';
import 'internet_enum.dart';
part 'internet_state.dart';
class InternetCubit extends Cubit<InternetState> {
final Connectivity? connectivity;
StreamSubscription? connectivityStreamSubscription;
InternetCubit({required this.connectivity}) : super(InternetLoading()) {
monitorInternetConnection();
}
void monitorInternetConnection() async {
connectivityStreamSubscription =
connectivity!.onConnectivityChanged.listen((connectivityResult) async {
try {
final result = await InternetAddress.lookup("example.com");
if (result.isNotEmpty && result[0].rawAddress.isNotEmpty) {
if (connectivityResult == ConnectivityResult.wifi) {
emitInternetConnected(ConnectionType.WiFi);
} else if (connectivityResult == ConnectivityResult.mobile) {
emitInternetConnected(ConnectionType.Mobile);
} else if (connectivityResult == ConnectivityResult.none) {
emitInternetDisconnected();
}
}
} on SocketException catch (_) {
emitInternetDisconnected();
}
});
}
void emitInternetConnected(ConnectionType _connectionType) =>
emit(InternetConnected(connectionType: _connectionType));
void emitInternetDisconnected() => emit(InternetDisconnected());
#override
Future<void> close() async {
connectivityStreamSubscription!.cancel();
return super.close();
}
}
This is the code in the internet_state.dart file
part of 'internet_cubit.dart';
abstract class InternetState {}
class InternetLoading extends InternetState {}
class InternetConnected extends InternetState {
final ConnectionType? connectionType;
InternetConnected({required this.connectionType});
}
class InternetDisconnected extends InternetState {}
This is the code in my main.dart file
import 'package:flutter/material.dart';
import 'package:flutter_bloc/flutter_bloc.dart';
import 'package:connectivity_plus/connectivity_plus.dart';
import 'internet_cubit.dart';
void main() {
runApp(
BlocProvider<InternetCubit>(
create: (_) => InternetCubit(connectivity: Connectivity()),
child: MyApp(),
),
);
}
class MyApp extends StatelessWidget {
#override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Flutter BLoC Demo',
home: SafeArea(
child: Scaffold(
appBar: AppBar(
title: Text("Flutter BLoC Demo"),
centerTitle: true,
backgroundColor: Colors.blue[900],
),
body: Center(
child: Builder(
builder: (context) {
return MaterialButton(
onPressed: () {
Navigator.push(context, MaterialPageRoute(builder: (context) => ScreenOne()));
},
color: Colors.black,
textColor: Colors.white,
child: Text("Screen 1"));
},
),
),
),
),
);
}
}
class ScreenOne extends StatelessWidget {
const ScreenOne({Key? key}) : super(key: key);
#override
Widget build(BuildContext context) {
return SafeArea(
child: Scaffold(
appBar: AppBar(
title: Text("Flutter BLoC Demo"),
centerTitle: true,
backgroundColor: Colors.blue[900],
),
body: Center(
child: BlocBuilder<InternetCubit, InternetState>(
builder: (_, state) {
if (state is InternetDisconnected) {
return Text("Internet disconnected");
} else if (state is InternetConnected) {
return Text("Internet connected");
}
return CircularProgressIndicator();
},
),
),
),
);
}
}
I suspected the problem to lie with my Internet connection at the network layer, so I tried a different approach. I will post my solution here so that it can be useful to someone with a similar problem.
First, I modified the internet_cubit.dart and internet_state.dart files like so:
import 'dart:async';
import 'package:bloc/bloc.dart';
import 'package:connectivity_plus/connectivity_plus.dart';
import 'internet_enum.dart';
part 'internet_state.dart';
class InternetCubit extends Cubit<InternetConnectionTypeState> {
final Connectivity? connectivity;
// ignore: cancel_subscriptions
StreamSubscription? internetConnectionTypeStreamSubscription;
InternetCubit({required this.connectivity}) : super(InternetConnectionTypeLoading()) {
monitorConnectionType();
}
void monitorConnectionType() async {
internetConnectionTypeStreamSubscription =
connectivity!.onConnectivityChanged.listen((connectivityResult) async {
if (connectivityResult == ConnectivityResult.wifi) {
emitConnectionType(ConnectionType.WiFi);
} else if (connectivityResult == ConnectivityResult.mobile) {
emitConnectionType(ConnectionType.Mobile);
}
});
}
void emitConnectionType(ConnectionType _connectionType) =>
emit(InternetConnectionType(connectionType: _connectionType));
#override
Future<void> close() async {
internetConnectionTypeStreamSubscription!.cancel();
return super.close();
}
}
part of 'internet_cubit.dart';
abstract class InternetConnectionTypeState {}
class InternetConnectionTypeLoading extends InternetConnectionTypeState {}
class InternetConnectionType extends InternetConnectionTypeState {
final ConnectionType? connectionType;
InternetConnectionType({required this.connectionType});
}
This is the internet_enum.dart file:
enum ConnectionType {
WiFi, Mobile
}
Next, I imported the internet_connection_checker package. I created a new cubit class called ConnectionCheckerCubit. Following the above code as a guide and the documentation for the internet_connection_checker package, here is the code for the connection_cubit.dart and the connection_state.dart file.
import 'dart:async';
import 'package:bloc/bloc.dart';
import 'package:internet_connection_checker/internet_connection_checker.dart';
part 'connection_state.dart';
class ConnectionCheckerCubit extends Cubit<ConnectionCheckerState> {
final InternetConnectionChecker? internetConnectionChecker;
ConnectionCheckerCubit({required this.internetConnectionChecker}) : super(InternetConnectionLoading()) {
monitorInternetConnection();
}
// ignore: cancel_subscriptions
StreamSubscription? internetConnectionStreamSubscription;
void monitorInternetConnection() async {
internetConnectionStreamSubscription = InternetConnectionChecker().onStatusChange.listen((status) {
switch (status) {
case InternetConnectionStatus.connected:
emitInternetConnectionConnected(InternetConnectionStatus.connected);
break;
case InternetConnectionStatus.disconnected:
emitInternetConnectionDisconnected();
break;
}
});
}
void emitInternetConnectionConnected(InternetConnectionStatus _internetConnectionStatus) =>
emit(InternetConnectionConnected(internetConnectionStatus: _internetConnectionStatus));
void emitInternetConnectionDisconnected() => emit(InternetConnectionDisconnected());
#override
Future<void> close() async {
internetConnectionStreamSubscription!.cancel();
return super.close();
}
}
part of 'connection_cubit.dart';
abstract class ConnectionCheckerState {}
class InternetConnectionLoading extends ConnectionCheckerState {}
class InternetConnectionConnected extends ConnectionCheckerState {
final InternetConnectionStatus? internetConnectionStatus;
InternetConnectionConnected({required this.internetConnectionStatus});
}
class InternetConnectionDisconnected extends ConnectionCheckerState {}
In the main.dart file, I used a MultiBlocProvider in the main() function as a wrapper for runApp. In the ScreenOne widget, I used a BlocBuilder widget for the InternetCubit and used context.watch<ConnectionCheckerCubit>().state to monitor the state of the ConnectionCheckerCubit. Also, I have added a AppBlocObserver class for debugging purposes. Here is the code for the main.dart file:
import 'dart:developer';
import 'package:internet_connection_checker/internet_connection_checker.dart';
import 'package:flutter/material.dart';
import 'package:flutter_bloc/flutter_bloc.dart';
import 'package:bloc/bloc.dart';
import 'package:connectivity_plus/connectivity_plus.dart';
import 'package:flutter_bloc_api/internet_enum.dart';
import 'connection_cubit.dart';
import 'internet_cubit.dart';
void main() {
Bloc.observer = AppBlocObserver();
runApp(
MultiBlocProvider(
providers: [
BlocProvider<ConnectionCheckerCubit>(
create: (_) => ConnectionCheckerCubit(internetConnectionChecker: InternetConnectionChecker()),
),
BlocProvider<InternetCubit>(
create: (_) => InternetCubit(connectivity: Connectivity()),
),
],
child: MyApp(),
),
);
}
class MyApp extends StatelessWidget {
#override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Flutter BLoC Demo',
home: SafeArea(
child: Scaffold(
appBar: AppBar(
title: Text("Flutter BLoC Demo"),
centerTitle: true,
backgroundColor: Colors.blue[900],
),
body: Center(
child: Builder(
builder: (context) {
return MaterialButton(
onPressed: () {
Navigator.push(context, MaterialPageRoute(builder: (context) => ScreenOne()));
},
color: Colors.black,
textColor: Colors.white,
child: Text("Screen 1"));
},
),
),
),
),
);
}
}
class ScreenOne extends StatelessWidget {
const ScreenOne({Key? key}) : super(key: key);
#override
Widget build(BuildContext context) {
return SafeArea(
child: Scaffold(
appBar: AppBar(
title: Text("Flutter BLoC Demo"),
centerTitle: true,
backgroundColor: Colors.blue[900],
),
body: Center(
child: Builder(
builder: (context) {
final connectionState = context.watch<ConnectionCheckerCubit>().state;
final internetTypeState = context.watch<InternetCubit>().state;
if (connectionState is InternetConnectionDisconnected)
return Text("Internet Disconnected");
else if (connectionState is InternetConnectionConnected){
if (internetTypeState is InternetConnectionType && internetTypeState.connectionType == ConnectionType.WiFi)
return Text("WiFi");
else
return Text("Mobile");
}
return CircularProgressIndicator();
}
)
),
),
);
}
}
class AppBlocObserver extends BlocObserver {
#override
void onChange(BlocBase bloc, Change change) {
super.onChange(bloc, change);
log('onChange: ${bloc.runtimeType}, ${bloc.state} \nCurrent state: ${change.currentState}\nNext state: ${change.nextState}');
}
#override
void onError(BlocBase bloc, Object error, StackTrace stackTrace) {
log('onError(${bloc.runtimeType}, ${bloc.state}, $error, $stackTrace)');
super.onError(bloc, error, stackTrace);
}
#override
void onEvent(Bloc bloc, Object? event) {
log('onEvent(${bloc.state}, ${bloc.runtimeType}, $event)');
super.onEvent(bloc, event);
}
#override
void onTransition(Bloc bloc, Transition transition) {
log('onTransition(${bloc.state}, ${bloc.runtimeType}, ${transition.currentState}, ${transition.nextState})');
super.onTransition(bloc, transition);
}
#override
void onCreate(BlocBase bloc) {
log('onCreate(${bloc.state}, ${bloc.runtimeType})');
super.onCreate(bloc);
}
#override
void onClose(BlocBase bloc) {
log('onTransition(${bloc.state}, ${bloc.runtimeType})');
super.onClose(bloc);
}
}
Here is a Github link for more information.
add this library connectivity: ^3.0.6
and try this code in your class:-
_startNetworkTesting(BuildContext context) async {
var result = await (Connectivity().checkConnectivity());
if (result == ConnectivityResult.none) {
setState(() {
//perform your action
});
} else if (result == ConnectivityResult.mobile) {
setState(() {
//perform your action
});
} else if (result == ConnectivityResult.wifi) {
setState(() {
//perform your action
});
}
}
The below code is used to generate an app for Webview.
Can someone guide me on how to implement page reload on screen pull down?
I want to achieve this because sometimes due to no internet connection Webview returns an error and when the user turns on the internet connection the page remains as it is. I want user to have the ability to reload the page on screen pull down just like how it is done on chrome app.
import 'dart:io';
import 'package:flutter/material.dart';
import 'package:flutter_webview_plugin/flutter_webview_plugin.dart';
import 'package:fluttertoast/fluttertoast.dart';
void main() => runApp(MyApp());
class MyApp extends StatelessWidget {
#override
Widget build(BuildContext context) {
return MaterialApp(debugShowCheckedModeBanner: false, home: BackButton());
}
}
class BackButton extends StatefulWidget {
#override
_BackButtonState createState() => _BackButtonState();
}
class _BackButtonState extends State<BackButton> {
DateTime backbuttonpressedTime;
#override
Widget build(BuildContext context) {
return Scaffold(
appBar: PreferredSize(
preferredSize: Size(double.infinity, 0),
child: AppBar(
title: Text(""),
backgroundColor: Colors.deepPurple,
),
),
body: WillPopScope(
onWillPop: onWillPop,
child: WebviewScaffold(
url: "https://theonlineindia.co.in/",
hidden: true,
initialChild: Container(
child: const Center(
child: CircularProgressIndicator(
valueColor: AlwaysStoppedAnimation<Color>(Colors.deepPurple)),
),
),
),
),
);
}
Future<bool> onWillPop() async {
DateTime currentTime = DateTime.now();
//ifbackbuttonhasnotbeenpreedOrToasthasbeenclosed
//Statement 1 Or statement2
bool backButton = backbuttonpressedTime == null ||
currentTime.difference(backbuttonpressedTime) > Duration(seconds: 2);
if (backButton) {
backbuttonpressedTime = currentTime;
Fluttertoast.showToast(
msg: "Double tap to exit the app",
backgroundColor: Colors.deepPurple,
textColor: Colors.white);
return false;
}
return true;
}
}
As #Uni mentioned above, pullToRefresh plugin is your solution here. It has all required methods you need. You just need to call the webviews reload function inside _onRefresh() to do your job.
For mobile apps connectivity plugin is working fine.
import 'package:connectivity/connectivity.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.
}
But is there is any way to detect internet connectivity on onPressed of button in Flutter web?
flutter web internet check.
if you want to check the internet connection on index.html.
Type 1:
<script>
var isOnline = navigator.onLine
</script>
if you want to check via listener then do like this.
Type 2:
<script>
var isOnline = navigator.onLine
window.addEventListener('online', function () {
this.isOnline = true
var x = document.getElementById("noInternet")
x.style.display = "none"
console.log('Became online')
})
window.addEventListener('offline', function () {
this.isOnline = false
var x = document.getElementById("noInternet")
x.style.display = "block"
console.log('Became offline')
})
function checkConnection() {
if (isOnline) {
var x = document.getElementById("noInternet")
x.style.display = "none"
}
else {
var x = document.getElementById("noInternet")
x.style.display = "block"
}
}
</script>
<body onload="checkConnection()">
<div class="centerPosition" id="noInternet">
<img src="cloud.png">
<h1>Uh-oh! No Internet</h1>
<h3>Please check your connection and try again</h3>
<button class="button buttonInternetConnection " onclick="checkConnection()">Try again</button>
</div>
</body>
Type 3:
check internet connection in dart file:
import 'dart:html'; //Important to add this line
import 'package:flutter/foundation.dart';
import 'package:flutter/material.dart';
void main() {
runApp(MyApp());
}
class MyApp extends StatelessWidget {
// This widget is the root of your application.
#override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Flutter Demo',
theme: ThemeData(
primarySwatch: Colors.blue,
),
home: MyHomePage(title: 'Flutter Demo Home Page'),
);
}
}
class MyHomePage extends StatefulWidget {
MyHomePage({Key? key, required this.title}) : super(key: key);
final String title;
#override
_MyHomePageState createState() => _MyHomePageState();
}
class _MyHomePageState extends State<MyHomePage> {
#override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: const Text('Connectivity example app'),
),
body: Center(
child: ElevatedButton(
onPressed: () {
print("Connection Status:${window.navigator.onLine}"); //Important to add this line
},
child: Text('Check Connection'))),
);
}
}
maybe you can use html library
import 'dart:html' as html;
html.window.navigator.connection
you can checkout and play with this object
to check network Connectivity in flutter for web use this plugin
https://pub.dev/packages/network_state
to check network Connectivity your code looks like
NetworkState.startPolling();
final ns = new NetworkState();
ns.addListener(() async {
final hasConnection = await ns.isConnected;
});
You can create a method, call that method on click of a button or widget
Sample code
class MyApp extends StatefulWidget {
#override
_State createState() => _State();
}
class _State extends State<MyApp> {
Future<bool> getStatus() async {
var connectivityResult = await (Connectivity().checkConnectivity());
if (connectivityResult == ConnectivityResult.mobile) {
debugPrint("network available using mobile");
return true;
} else if (connectivityResult == ConnectivityResult.wifi) {
debugPrint("network available using wifi");
return true;
} else {
debugPrint("network not available");
return false;
}
}
#override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text('Connectivity Demo'),
),
body: SingleChildScrollView(
child: Container(
padding: EdgeInsets.all(32.0),
child: Column(
children: <Widget>[
GestureDetector(
onTap: () {
Future<bool> status = getStatus();
// now you can use status as per your requirement
},
child: Text("Get Internet Status"),
)
],
),
),
),
);
}
}
This post might be helpful. It uses internet_connection_checker package. However, it doesn't have full web support, but the forked package described here seems to work fine.
Alternatively you might want to use network_state package.