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.
Related
I'm newly learning Serverpod version 0.9.21 as my backend, first I changed the Client address from http://localhost:8080/ to http://10.0.2.2:8080/ so the SocketException error had gone on the emulator and now the sample app (say hello) works correctly. The Problem is my code faces Error 400 with no errorMessage, Also I've added the tables and checked the database, and everything looks fine.
After creating the project, I added Province Protocol inside the test_server package:
class: Province
table: province
fields:
name: String
isEnabled: bool
Then added the province_endpoint:
import 'package:serverpod/serverpod.dart';
import '../generated/protocol.dart';
class ProvinceEndpoint extends Endpoint {
Future<bool> addProvince(Session session, Province province) async {
await Province.insert(session, province);
return true;
}
}
Then run serverpod generate and start the docker and the server as tutorials are mentioning.
And finally the test_flutter main.dart:
import 'package:back_client/back_client.dart';
import 'package:flutter/material.dart';
import 'package:serverpod_flutter/serverpod_flutter.dart';
var client = Client('http://10.0.2.2:8080/')
..connectivityMonitor = FlutterConnectivityMonitor();
void main() {
runApp(const MyApp());
}
class MyApp extends StatelessWidget {
const MyApp({super.key});
// This widget is the root of your application.
#override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Flutter Demo',
theme: ThemeData(
primarySwatch: Colors.blue,
),
home: const HomePage(),
);
}
}
class HomePage extends StatefulWidget {
const HomePage({Key? key}) : super(key: key);
#override
State<HomePage> createState() => _HomePageState();
}
class _HomePageState extends State<HomePage> {
final _nameController = TextEditingController(text: "name1");
String result = "here";
addProvince() async {
final province = Province(name: _nameController.text, isEnabled: true);
client.province.addProvince(province).then((value) {
if (value) {
setState(() {
result = "Done adding ${_nameController.text} province";
});
} else {
result = "Nashod!";
}
}).catchError((onError) {
final error = (onError is ServerpodClientException)
? "${onError.message} ${onError.statusCode}"
: "Error ";
setState(() {
result = error;
});
}).whenComplete(() {
print("done");
});
}
#override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(),
body: Column(
children: [
TextField(
controller: _nameController,
),
Text(
result,
style: Theme.of(context).textTheme.headline3,
)
],
),
floatingActionButton: FloatingActionButton(
onPressed: addProvinces,
child: const Icon(Icons.add),
),
);
}
}
I am a noob in Backend stuff, I didn't restart the docker and server after developing the endpoint! As flutter has hot-reload it made me a little bit lazy!
After development, in the terminal that serverpod is running, press Ctrl + C to close its processes, then run docker-compose up --build --detach && dart bin/main.dart
I am developing a Flutter app where it acts as a client, connecting to a server via an API.
The app makes requests and depending on the response it progresses the state.
My question is the following: Can I make a request, and then depending on the response, either update the UI or open a new page?
I have used FutureBuilder as shown below. The problem is that the FutureBuilder requires to return a UI. In my case, if the response is OK I want to open a new page (see //todo line).
I tried using Navigator.pushReplacement but it does not really work.
Any ideas?
import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';
import 'dart:async';
import 'package:flutter/rendering.dart';
import 'model.dart';
class Start extends StatefulWidget {
final String title;
Start({Key key, #required this.title}) : super(key: key);
#override
State<StatefulWidget> createState() => new StartState();
}
class StartState extends State<Start> {
Future<StartReply> _startReply;
_makeRequest() {
setState(() {
_startReply = ...; // actual API request
});
}
#override
Widget build(BuildContext context) {
return MaterialApp(
title: widget.title,
home: Scaffold(
appBar: AppBar(
title: Text(widget.title),
leading: IconButton(
icon: Icon(Icons.arrow_back),
onPressed: () => Navigator.of(context).pop(false)
),
),
body: Center(
child: FutureBuilder(
future: _startReply,
builder: (context, snapshot) {
if(snapshot.connectionState == ConnectionState.none) {
return ElevatedButton(
onPressed: _makeRequest,
child: Text("Make request")
);
} else if(snapshot.connectionState == ConnectionState.done && snapshot.hasData) {
// todo open page here
return Text('Started!', style: TextStyle(color: Colors.green, fontStyle: FontStyle.italic));
} else if(snapshot.hasError) {
debugPrint('StartReply: ${snapshot.data}');
return Text('Error (${snapshot.error})', style: TextStyle(color: Colors.red, fontStyle: FontStyle.italic));
} else {
return CircularProgressIndicator();
}
}
)
)
)
);
}
}
Yes, you should not use a FutureBuilder if you want to do anything other than changing the UI depending on the async task. You should manage your own async. Here's some code to get you started:
class MyWidget extends StatefulWidget {
#override
_MyWidgetState createState() => _MyWidgetState();
}
class _MyWidgetState extends State<MyWidget> {
bool loaded;
#override
void initState() {
super.initState();
asyncInit();
}
Future<void> asyncInit() async {
final response =
await doTheNetworkRequest() //imagine that this was an http request
if (yes) {
setState(() {
loaded = true;
});
} else {
Navigator.of(context).push(...);
}
}
#override
Widget build(BuildContext context) {
return loaded == true ? Text('Loaded') : Text('Loading');
}
}
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?
I'm unsure of how to incorporate this into an existing flutter project and I haven't been able to find any useful guides or tips online. Im looking to implement a 2D only barcode scanner, and none of the existing flutter barcode scanners have that option.
I know ZXing also has the 2d only functionality in it so I could be swayed to use that if anyone can point me in the direction of how to implement them in flutter
Please check this url
https://pub.dartlang.org/packages/qrcode_reader
Here is implementation code
import 'dart:async';
import 'package:flutter/material.dart';
import 'package:qrcode_reader/QRCodeReader.dart';
void main() {
runApp(new MyApp());
}
class MyApp extends StatelessWidget {
#override
Widget build(BuildContext context) {
return new MaterialApp(
title: 'QRCode Reader Demo',
home: new MyHomePage(),
);
}
}
class MyHomePage extends StatefulWidget {
MyHomePage({Key key, this.title}) : super(key: key);
final String title;
final Map<String, dynamic> pluginParameters = {
};
#override
_MyHomePageState createState() => new _MyHomePageState();
}
class _MyHomePageState extends State<MyHomePage> {
Future<String> _barcodeString;
#override
Widget build(BuildContext context) {
return new Scaffold(
appBar: new AppBar(
title: const Text('QRCode Reader Example'),
),
body: new Center(
child: new FutureBuilder<String>(
future: _barcodeString,
builder: (BuildContext context, AsyncSnapshot<String> snapshot) {
return new Text(snapshot.data != null ? snapshot.data : '');
})),
floatingActionButton: new FloatingActionButton(
onPressed: () {
setState(() {
_barcodeString = new QRCodeReader()
.setAutoFocusIntervalInMs(200)
.setForceAutoFocus(true)
.setTorchEnabled(true)
.setHandlePermissions(true)
.setExecuteAfterPermissionGranted(true)
.scan();
});
},
tooltip: 'Reader the QRCode',
child: new Icon(Icons.add_a_photo),
),
);
}
}
This can be done by using flutter barcode_scan dependency.
Future _openQRScanner() async {
try {
// Below code will open camera preview and return result after qr scan
String _content = await BarcodeScanner.scan();
setState(() => this._content = _content);
} on PlatformException catch (e) {
if (e.code == BarcodeScanner.CameraAccessDenied) {
showSnackBar('Please grant camera permission!');
setState(() {
this._content = null;
});
} else {
showSnackBar('Error: $e');
setState(() {
this._content = null;
});
}
} on FormatException {
showSnackBar('User pressed "back" button before scanning');
setState(() {
this._content = null;
});
} catch (e) {
showSnackBar('Error: $e');
setState(() {
this._content = null;
});
}
}
Please find the repo.
If you want to take a look at Flutter you can find some good examples at our companie’s Github page. Also, you can check our company's page FlutterDevs.
I have a raised button that kicks off my fingerprint authentication, when the Future returns I want to be able to change the Raised Button to new text and new onPressed method to complete the required authentication. I have given the Raised Button a key but can not find how to act upon that button to change it. Is it possible? Anyone have examples of it?
I tried to create new Raised Button with same key based on if the user is authenticated, but it did not change anything.
Any help would be great.
I would recommend reviewing the Flutter Interactivity Tutorial.
Once the Future completes you can call setState to tell Flutter to rebuild your StatefulWidget. And in your build() method, you can use the authenticated status of the user to construct a different RaisedButton.
Here's some example code that does this:
import 'dart:async';
import 'package:flutter/material.dart';
import 'package:flutter/services.dart';
import 'package:local_auth/local_auth.dart';
void main() {
runApp(new MyApp());
}
class MyApp extends StatelessWidget {
#override
Widget build(BuildContext context) {
return new MaterialApp(
title: 'Flutter Local Auth Demo',
home: new MyHomePage(),
);
}
}
class MyHomePage extends StatefulWidget {
MyHomePage({Key key}) : super(key: key);
#override
_MyHomePageState createState() => new _MyHomePageState();
}
class _MyHomePageState extends State<MyHomePage> {
bool _authenticated = false;
Future<Null> _authenticate() async {
final LocalAuthentication auth = new LocalAuthentication();
bool authenticated = false;
try {
authenticated = await auth.authenticateWithBiometrics(
localizedReason: 'Scan your fingerprint to authenticate',
useErrorDialogs: true);
} on PlatformException catch (e) {
print(e);
}
if (!mounted) return;
setState(() {
_authenticated = authenticated;
});
}
Widget _buildAuthButton() {
assert(!_authenticated);
return new RaisedButton(
child: new Text('Authenticate'),
onPressed: _authenticate,
);
}
Widget _buildContinueButton() {
assert(_authenticated);
return new RaisedButton(
child: new Text('Continue'),
onPressed: () {
// Do something now that the user is authenticated
},
);
}
#override
Widget build(BuildContext context) {
return new Scaffold(
appBar: new AppBar(
title: new Text('Interactivity Tutoral'),
),
body: new Center(
child: _authenticated ? _buildContinueButton() : _buildAuthButton(),
),
);
}
}
I would use FutureBuilder, just return one widget or the other based on whether the Future is complete
new FutureBuilder<String>(
future: your_future,
builder: (_, AsyncSnapshot<String> snapshot) {
switch (snapshot.connectionState) {
case ConnectionState.waiting:
return const CircularProgressIndicator();
default:
if (snapshot.hasError)
return new Text('Error: ${snapshot.error}');
else
return new Text(
'Your data: ${snapshot.data}',
);
}
})