Following all tutorials and articles online, everybody is using launch() function from the known url_launcher plugin to open links, so i used it in my application to open messenger, whatsApp, and directcalls as follows:
_directCall() {
launch('tel:00962785522213');
}
//Open WhatsApp
_launchWhatsapp() {
launch("https://wa.me/+962797809910");
}
//Open Messenger
_openMessenger() {
launch("http://m.me/amr.al.shugran");
}
but unfortunately the launch method is no longer used and i have to use launchUrl() so i would be thankful if anyone could tell us how to use this function at the same context am using launch().
You need to use
//Open Messenger
_openMessenger() {
launchUrl(Uri.parse("http://m.me/amr.al.shugran"));
}
Try it
Future _launchUrl(url) async {
if (!await launchUrl(Uri.parse(url))) {
throw 'Could not launch $url';
}
}
#override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: const Text('Test'),
),
body: OutlinedButton(
onPressed: () async {
_launchUrl('www.google.com');
},
child: const Text('Open'),
),
);
}
Related
Within my flutter app, I am launching a payment gateway using the url_launcher plugin with opens the page in a browser. However I would rather have it open in a WebView plugin instead, within the app.
Do I need to use both? how can implement such.
Please assist
Url launcher
if (selectedPaymentMethod == 'Pay Now' &&
_formKey.currentState!.validate()) {
() async {
final ozowApiRes = await OzowApiProvider()
.createPaymentRequest(
'R${(cart.totalAmount + cart.serviceFee + value * cart.newCylinderPrice).toStringAsFixed(0)}',
userData?['username'],
userData?['phoneNumber'],
userData?['email'],
);
() async {
try {
await launchUrl(
Uri.parse(ozowApiRes.data),
);
} catch (ex) {
throw 'Could not launch $ozowApiRes';
}
}();
}();
To do this, you can use url_launcher or flutter_inappwebview. I will recommend you to use flutter_inappwebview if possible cause url_launcher 100% not guaranteed you to launch in inAppWebView and also flutter_inappwebview gives you the granular controll in a page.
(1) you can use url_launcher with mode LaunchMode.inAppWebView
await launchUrl(
Uri.parse("https://www.google.com/"),
mode: LaunchMode.inAppWebView,
);
(2) or you can use a stateless widget page with flutter_inappwebview and just pass the purchase url
import 'package:flutter/material.dart';
import 'package:flutter_inappwebview/flutter_inappwebview.dart';
class InAppPurchasePage extends StatelessWidget {
const InAppPurchasePage({Key? key}) : super(key: key);
#override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: const Text("Purchase Page"),
),
body: InAppWebView(
initialUrlRequest: URLRequest(
url: Uri.parse(
"https://flutter.dev",
),
),
),
);
}
}
I have a barcode scanner working fine on Android, but I am struggling to find plugins that support a web app.
This is the closest one I've found that seems to be getting somewhere:
https://pub.dev/packages/ai_barcode
But I can't really get anything to happen.
Here is the code I'm using currently:
import 'package:flutter/material.dart';
import 'package:ai_barcode/ai_barcode.dart';
class WebBarcodeScannerPage extends StatefulWidget {
// void resultCallback (String result) {
// debugtext
// }
#override
_WebBarcodeScannerPageState createState() => _WebBarcodeScannerPageState();
}
class _WebBarcodeScannerPageState extends State<WebBarcodeScannerPage> {
ScannerController _scannerController;
String _debugText = 'debug';
#override
void initState () {
super.initState();
_scannerController = ScannerController(scannerResult: (r) => resultCallback(r));
// _scannerController = ScannerController(scannerResult: (result) {
// resultCallback(result);
// }, scannerViewCreated: () {
// final TargetPlatform platform = Theme.of(context).platform;
// if (TargetPlatform.iOS == platform) {
// Future.delayed(const Duration(seconds: 2), () {
// _scannerController
// ..startCamera()
// ..startCameraPreview();
// });
// } else {
// _scannerController
// ..startCamera()
// ..startCameraPreview();
// }
// });
}
resultCallback (String r) {
print(r);
setState(() {
_debugText = r;
});
}
_body () {
return Column(
children: [
Text(_debugText),
TextButton(
child: Text('Start camera'),
onPressed: () {
_scannerController.startCamera();
},
),
TextButton(
child: Text('Start preview'),
onPressed: () {
_scannerController.startCameraPreview();
},
),
TextButton(
child: Text('Stop camera'),
onPressed: () {
_scannerController.stopCamera();
},
),
TextButton(
child: Text('Stop preview'),
onPressed: () {
_scannerController.stopCameraPreview();
},
),
PlatformAiBarcodeScannerWidget(platformScannerController: _scannerController),
],
);
}
#override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(),
body: _body(),
);
}
}
The camera preview shows up in a window, but I can't scan any barcodes or QR codes. The debug text never changes.
Again, my goal is to be able to read barcodes into a string on a mobile web app.
You can use our product Cognex Mobile Barcode SDK
Download page for all supported platforms - https://cmbdn.cognex.com/download#Platforms
Knowledge Base for more information about the integration - https://cmbdn.cognex.com/v2.6.x/knowledge/flutter/license-keys
https://pub.dev/packages/cmbsdk_flutter
Regards,
You should add jsQR.js to web folder.
You can find that HERE
you can use the source example from ai_barcode.
QRCodeDartScanView(
typeCamera: TypeCamer.front,
scanInvertedQRCode: true,
resolutionPreset: QRCodeDartScanResolutionPreset.ultraHigh,
formats: const [
BarcodeFormat.QR_CODE,
],
onCapture: (Result result) {
printInfo(info: result.text);
},
);
Just put this piece of code inside a build method. The camera opens and read qr codes.
simple_barcode_scanner (which leverages html5-qrcode for web apps) worked best for my PWA, in fact it was the only package of several I tried that met my requirements of being able to read both EAN-13 and GS1 data matrix from a web app -- and it worked immediately the first time, and it does not require editing index.html. (I couldn't use ai_barcode due to a hard-to-resolve dependency conflict between ai_barcode and barcode, and barcode is a must-have for my web app -- but even without the dependency issue I struggled to make ai_barcode work reliably).
If you decide to use simple_barcode_scanner note that it does not work on desktop browsers, only mobile browsers, so you'll need a check like this:
import 'package:flutter/foundation.dart';
import 'package:simple_barcode_scanner/simple_barcode_scanner.dart';
...
final isWebMobile = kIsWeb &&
(defaultTargetPlatform == TargetPlatform.iOS ||
defaultTargetPlatform == TargetPlatform.android);
if (isWebMobile) {
String scanResult = await Navigator.push(
context,
MaterialPageRoute(
builder: (context) => const SimpleBarcodeScannerPage()),
);
print('scan result = $scanResult');
} else {
print('Scanning is only supported for mobile web browsers.');
}
I have a flutter app and everything was fine until i want to release it.
I'm using firebase for auth.
I'm using:
firebase_core: ^0.7.0
firebase_auth: ^0.20.0
In debug mode or in release, my firebase auth login works fine. My problem is after that.
I have a decentralized 'listener' to firebaseAuth.authStateChanges. Here is where i control my app authentication. This is my buildSelf$ function in my auth repository(where i build the auth state listener):
ReplayConnectableStream<AuthState> buildSelf$() {
return Rx.concat([
Stream.value(AuthInit()),
firebaseAuth.authStateChanges().switchMap((firebaseUser) {
print('[AuthRepository][buildSelf][authStateChanges] firebaseUser');
print(firebaseUser);
if (firebaseUser == null) {
return Stream.value(Unauthenticated());
}
/* continue function */
return Authenticated(firebaseUser: firebaseUser);
})
]).publishReplay();
}
buildSelf$ is a method for my AuthRepository. And i initialize it on:
AuthRepository._() {
Firebase.initializeApp().then((app) {
_firebaseAuth = FirebaseAuth.instance;
state$ = buildSelf$();
state$.connect();
});
setPackageInfo();
}
static final AuthRepository instance = AuthRepository._();
All this code is inside my AuthRepository.
The problem is:
When i'm running my app in debug mode. Every thing works fine. I can login and my app (my navigator observer uses the auth repository state$) and i'm redirected to home page. [Here a printscreen from terminal in debug mode. success authStateChanges emit
But when i'm running im release mode, my login response shows in my terminal 'success' but my listener does not show state changes. Here a printscreen from terminal in release mode. authStateChanges emit only 1 time(when opening)
I'm realy lost about whats going on. I tried even to call this authStateChanges directly in my app.dart but still the same way(in release, only checking auth state once).
Solution:
After 3 days of headache, i finally found out my problem:
My app does not initialize firebase app on root (main). So i have to initialize it every time i need to use some firebase package.
I believe that every time one app was initialized, the others failed.
I move my firebase.initializeApp() to my main function and remove every other firebase initialize. Then, everything works fine.
This is my main:
void main() async {
/* ... main code ... */
WidgetsFlutterBinding.ensureInitialized();
await Firebase.initializeApp();
runApp(App());
}
I did implement a project with the presented methods in release mode in my iPhone but wasn't able to reproduce the problem, the implementation I did to reproduce the project was:
class _TestFirebaseState extends State<TestFirebase> {
bool userLogado = false;
_loginLogout() {
if (FirebaseAuth.instance.currentUser == null) {
FirebaseAuth.instance.signInWithEmailAndPassword(
email: 'teste1#teste.com', password: '123456');
} else {
FirebaseAuth.instance.signOut();
}
}
#override
void initState() {
super.initState();
final stream = Rx.concat(
[
Stream.value('começou'),
FirebaseAuth.instance.authStateChanges().switchMap<String>(
(user) {
debugPrint('user: ' + user.toString());
if (user == null) {
return Stream.value('unauth');
} else {
return Stream.value('auth');
}
},
),
],
).publishReplay();
stream.listen((value) {
debugPrint('value: ' + value);
this.setState(() {
this.userLogado = value == 'auth';
});
});
stream.connect();
}
#override
Widget build(BuildContext context) {
String text = "sair";
if (!userLogado) {
text = "entrar";
}
return Scaffold(
body: Container(
width: double.infinity,
height: double.infinity,
child: Center(
child: RaisedButton(
onPressed: _loginLogout,
child: Text(text),
),
),
),
);
}
}
the only detail is that the main component that loads everything in the app has a future builder that awaits the firebase to init:
Widget build(BuildContext context) {
return MaterialApp(
home: FutureBuilder(
// Initialize FlutterFire:
future: Firebase.initializeApp(),
builder: (context, snapshot) {
// Check for errors
if (snapshot.hasError) {
return Scaffold(
body: Center(
child: Text(
'ocorreu um problema inicializando o aplicativo...',
),
),
);
}
// Once complete, show your application
if (snapshot.connectionState == ConnectionState.done) {
// return LoginPage();
// return VerifySignIn(homePage: Home());
return TestFirebase();
}
// Otherwise, show something whilst waiting for initialization to complete
return Scaffold(
body: Center(
child: CircularProgressIndicator(),
),
);
},
),
debugShowCheckedModeBanner: false,
);
}
And another detail is that the firebase configuration is implemented following the flutter tutorial for the platform used.
So in order to evaluate if the app configuration is just fine, I would implement that button app inside the same project so you can evaluate it properly.
I am working on a flutter app. I have a bunch of times of the day and I want to show an alert notification whenever a time comes and also change the UI of the app if it's running.
So I looked for what options I have, I found the followings
Plugins like flutter-workmanager and background_fetch
Native code implementation with Channels
MY questions are:
Which option is the best for my use case?
Is it better implementing a time counter with delay by duration or using an alarm manager.
How can I pass the data (the current time that comes) between the background task and my app so that I can update the UI?
PS: Currently We are interested in a solution that works at least for Android.
I don't think you need background tasks just to show notifications. Using flutter_local_notifications should be enough for your task. You can schedule a notification with this plugin for specific datetime. Inside of the app, you can use Timer to trigger at specific datetime. I'll show you a simple example:
class _HomePageState extends State<HomePage> {
FlutterLocalNotificationsPlugin notifPlugin;
#override
void initState() {
super.initState();
notifPlugin = FlutterLocalNotificationsPlugin();
}
Future<void> scheduleNotification(DateTime dateTime, String title) async {
final now = DateTime.now();
if (dateTime.isBefore(now)) {
// dateTime is past
return;
}
final difference = dateTime.difference(now);
Timer(difference, () {
showDialog(
context: this.context,
builder: (context) {
return AlertDialog(
content: Text(title),
);
}
);
});
await notifPlugin.schedule(title.hashCode, title, title, dateTime, platformChannelSpecifics, payload: 'test');
}
#override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(),
body: SafeArea(
child: Container()
),
floatingActionButton: Builder(
builder: (context) {
return FloatingActionButton(
onPressed: () {
final snackbar = SnackBar(content: Text('planned notification'), duration: Duration(seconds: 3));
Scaffold.of(context).showSnackBar(snackbar);
scheduleNotification(DateTime.now().add(Duration(seconds: 2)), 'Hello');
},
);
}
),
);
}
}
But if you need to do some calculations or data fetch then background_fetch is what you need. The only problem with it Apple don't allow background tasks in most cases.
I tried to create a QRCode scanner in my mobile application using Flutter.I add the package barcode_scan in pubspec.yaml and the permission to the camera
But everytime the same error was showed that no imlimentation found for method scan i can't found the solution.this is my code
import 'package:flutter/material.dart';
import 'package:barcode_scan/barcode_scan.dart';
import 'dart:async';
import 'package:flutter/services.dart';
class MyHomePage extends StatefulWidget{
#override
_MyHomePageState createState()=> new _MyHomePageState();
}
class _MyHomePageState extends State<MyHomePage> {
String result = "Hey there !";
Future _scanQR() async {
try {
String qrResult = await BarcodeScanner.scan();
setState(() {
result = qrResult;
});
} on PlatformException catch (ex) {
if (ex.code == BarcodeScanner.CameraAccessDenied) {
setState(() {
result = "Camera permission was denied";
});
} else {
setState(() {
result = "Unknown Error $ex";
});
}
} on FormatException {
setState(() {
result = "You pressed the back button before scanning anything";
});
} catch (ex) {
setState(() {
result = "Unknown Error $ex";
});
}
}
#override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text("QR Scanner"),
),
body: Center(
child: Text(
result,
style: new TextStyle(fontSize: 30.0, fontWeight: FontWeight.bold),
),
),
floatingActionButton: FloatingActionButton.extended(
icon: Icon(Icons.camera_alt),
label: Text("Scan"),
onPressed: _scanQR,
),
floatingActionButtonLocation:
FloatingActionButtonLocation.centerFloat,
);
}
}
The error "No implementation found for method..." is usually caused when Flutter is unable to find the method called from the package due to the plugin not being properly added to the project. The same issue can also be encountered if the plugin used doesn't support the targeted platform. But since barcode_scan plugin seems to support both iOS and Android, this may have been caused by the former.
You can try running flutter pub get to verify that the plugins have been added to the project and run the app using full restart to ensure that all packages added are compiled.
I've also noticed that barcode_scan has been discontinued as of this writing. The plugin may still work as expected, but it won't be receiving further updates from its developers. You can also check other barcode scanner plugins from pub.dev that may fit your use case.