How to use barcode result to open webview in flutter - flutter

I am using BarcodeScanner package. I get the result after scan the QR code. My question is how to use that result then open the website. Here is my code:
Future scan() async{
Completer<WebViewController> _controller = Completer<WebViewController>();
try {
String barcode = await BarcodeScanner.scan();
setState(() {
this.barcode = barcode;
print(this.barcode);
WebView(
initialUrl: this.barcode,
onWebViewCreated: (WebViewController webViewController) {
_controller.complete(webViewController);
},
),
});
} on PlatformException catch (e) {
if (e.code == BarcodeScanner.CameraAccessDenied) {
setState(() {
this.barcode = 'The user did not grant the camera permission!';
});
} else {
setState(() => this.barcode = 'Unknown error: $e');
}
} on FormatException{
setState(() => this.barcode = 'null (User returned using the "back"-button before scanning anything. Result)');
} catch (e) {
setState(() => this.barcode = 'Unknown error: $e');
}
}
}

If you use Webview here, after you receive QR code from scanner you need you navigate to new screen. Like this
Navigator.push(
context,
MaterialPageRoute(builder: (context) => WebView(initUrl: data[index].homeLink))
);
Otherwise, you can use url_launcher plugin
https://pub.dev/packages/url_launcher

controller.pauseCamera();
if (await canLaunch(scanData.code)) {
await launch(scanData.code);
}
controller.resumeCamera();
For more details, see here

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?

Shows warning: Do not use BuildContexts across async gaps

if (_formKey.currentState!.validate()) {
try {
final newUser =
await _auth.createUserWithEmailAndPassword(
email: email.text, password: password.text);
if (newUser != null) {
// Navigator.push(
// context,
// MaterialPageRoute(
// builder: (context) => DashboardScreen(),
// ));
Navigator.pushNamed(context, 'dashboard');
}
setState(() {});
} catch (e) {
print(e);
}
}
},
this warning shown on Navigator.pushNamed(context,'dashboard');
trying to navigate to the dashboar screen.
1.
You have to put delay for other process can finish till then
Future.delayed(Duration(milliseconds: 200)).then((value) {
Navigator.pushNamed(context, 'dashboard')
});
2.
add if (!mounted) return; before Navigator.pushNamed(context, 'dashboard')
3.
Please put await before the navigator flutter because you used an asynchronously method call so you have to wait until the process is finished then you can navigate to your pages
await Navigator.pushNamed(context, 'dashboard');
4.
Also, you can store your navigator into a var and then use it.
final nav = Navigator.of(context);
nav.pushNamed('dashboard');

Flutter show dialog box if no "Internet Connection"

I'm beginner to Flutter development and im creating a webview app to load my responsive website into the app.
Everything works perfect but i need to show a dialog box saying "No internet connection" if there is no internet connection.
My code :
class _MyHomePageState extends State<MyHomePage> {
bool isLoading = true;
ConnectivityResult? _connectivityResult;
late StreamSubscription _connectivitySubscription;
bool? _isConnectionSuccessful;
#override
initState() {
super.initState();
_connectivitySubscription = Connectivity()
.onConnectivityChanged
.listen((ConnectivityResult result) {
print('Current connectivity status: $result');
setState(() {
_connectivityResult = result;
});
});
}
#override
dispose() {
super.dispose();
_connectivitySubscription.cancel();
}
Future<void> _checkConnectivityState() async {
final ConnectivityResult result = await Connectivity().checkConnectivity();
if (result == ConnectivityResult.wifi) {
print('Connected to a Wi-Fi network');
} else if (result == ConnectivityResult.mobile) {
print('Connected to a mobile network');
} else {
print(result);
}
setState(() {
_connectivityResult = result;
});
}
#override
Widget build(BuildContext context) {
return Stack(
children: <Widget>[
WebView(
javascriptMode: JavascriptMode.unrestricted,
// initialUrl: '',
onWebViewCreated: (WebViewController controller) async {
await WebviewCookieManager().setCookies([
Cookie('SESSION-Test', 'token')
..domain = 'dobuyme.online'
..httpOnly = true
]);
controller.loadUrl('https://example.com/source=web_view');
},
onPageFinished: (String url) {
setState(() {
isLoading = false;
});
},
// onPageFinished: (finish) {
// setState(() {
// var isLoading = false;
// });
// },
),
isLoading
? const Center(
child: CircularProgressIndicator(),
)
: Stack(),
],
);
}
}
This variable will be "true" if connection is successful
_isConnectionSuccessful
But i don't know how to append this with the webview and check connection before website loads.
I want to show a message that says "No intenet connection" and close the app.
Please anyone can help. me ?
Thanks
use internet_connection_checker: ^0.0.1+4 plugin to check if internet has available or not...
final StreamSubscription<InternetConnectionStatus> listener =
InternetConnectionChecker().onStatusChange.listen(
(InternetConnectionStatus status) {
switch (status) {
case InternetConnectionStatus.connected:
// Do what you want to do
break;
case InternetConnectionStatus.disconnected:
// Do what you want to do
break;
}
},
);
Here you you find the status....and show dailoge box when status is disconnected

Flutter call function from other class?

Hi I am building flutter function which able to capture qr code and after display the result after user scan QR Code. I need user to be able navigate to previous scanning screen by using button if they need rescan or scan new qr code. This is code for button which on Scanview class.
SizedBox(height: 40,),
CupertinoButton(
color: Color(0xFF88070B),
child:Text("Re-scan QR "),
onPressed: (){
Navigator.of(context).push(
MaterialPageRoute(
builder: (context) => **ScanFunction**(),
),
);
}
)
I want to call this _scanQR method from other class ScanFunction . What is proper way when user tap Re-scan QR button and call _scanQR method which is on other class? How to access method from other class? Thanks for help.
class ScanFunction extends StatefulWidget {
#override
ScanFunctionState createState() {
return ScanFunctionState();
}
}
class ScanFunctionState extends State<ScanFunction> {
String result = "Maklumat Inventori";
Future _scanQR() async {
try {
String qrResult = await BarcodeScanner.scan();
Navigator.of(context).push(
MaterialPageRoute(
builder: (context) => Scanresultview(qrResult),
),
);
} on PlatformException catch (ex) {
if (ex.code == BarcodeScanner.CameraAccessDenied) {
setState(() {
result = "Kebenaran kamera telah ditolak";
});
} else {
setState(() {
result = "Ralat tidak diketahui$ex";
});
}
} on FormatException {
setState(() {
result = "Anda menekan butang belakang sebelum mengimbas apa-apa";
});
} catch (ex) {
setState(() {
result = "Ralat tidak diketahui $ex";
});
}
}
You can call this method from initState.
class ScanFunction extends StatefulWidget {
#override
ScanFunctionState createState() {
return ScanFunctionState();
}
}
class ScanFunctionState extends State<ScanFunction> {
#override
void initState() {
_scanQR();
super.initState();
}
String result = "Maklumat Inventori";
Future _scanQR() async {
try {
String qrResult = await BarcodeScanner.scan();
Navigator.of(context).push(
MaterialPageRoute(
builder: (context) => Scanresultview(qrResult),
),
);
} on PlatformException catch (ex) {
if (ex.code == BarcodeScanner.CameraAccessDenied) {
setState(() {
result = "Kebenaran kamera telah ditolak";
});
} else {
setState(() {
result = "Ralat tidak diketahui$ex";
});
}
} on FormatException {
setState(() {
result = "Anda menekan butang belakang sebelum mengimbas apa-apa";
});
} catch (ex) {
setState(() {
result = "Ralat tidak diketahui $ex";
});
}
}

Barcode crash without errors

I am making an app using the qrCode scanner and when i open the app on my iphone and touch the button for the qrCode scanning it shuts down automatically , not opening even the camera.I used barcode_scan in pubspec.yaml and the code is:
String qrResult = "Not yet Scanned";
onPressed: () async {
String scaning = await BarcodeScanner.scan();
setState(() {
qrResult = scaning;
});
},
The app is made in flutter
Please You can use this package flutter_barcode_scanner 1.0.1 to make your Work Simple.Cheers!!
scan() async {
try {
dynamic bar = await BarcodeScanner.scan();
if(bar != null && bar.isNotEmpty){
print(" scanning qrcode ------------------------ $barcode");
setState(() {
barcode = bar;
});
}} on PlatformException catch (e) {
setState(() => this.barcode = '');
} on FormatException{
setState(() => this.barcode = '');
} catch (e) {
setState(() => this.barcode = '');
}
}