Flutter how to check if pdf print data has been delivered - flutter

I made an app that converts images to datr-pdf and prints them. my app prints in Wi-Fi Direct format and uses the printing package. there is no problem in printing using the default print service in both android and IOS. select a printer from the default print service and press the print button after connecting, data is sent to the printer and the app returns to the previous app screen from the default print service screen.
After sending data to the printer, I want to receive a return about success or failure with a bool variable in the process of returning to the previous screen.
My end goal is to pass data from the app to the printer and when I return to the screen of the app, if return is `true', I want the app to close while printing. I'm looking at the source via 'GitHub' but haven't found it yet. Do you know of a method or class that sends data and returns to the app's screen??
My PrintSource
_generatedPdf(PdfPageFormat format, BuildContext context) async {
final pdf = pdfWidget.Document(version: PdfVersion.pdf_1_5, compress: true);
//Page Num
for(int nCount=0; nCount<context.read<ScoreImageProvider>().scoreImageList.length; nCount++){
final image = await imageFromAssetBundle(context.read<ScoreImageProvider>().scoreImageList[nCount]);
pdf.addPage(
pdfWidget.Page(
pageFormat: format,
build: (pdfWidget.Context context){
return pdfWidget.Center(
child: pdfWidget.Padding(
padding: pdfWidget.EdgeInsets.zero,
child: pdfWidget.Image(image, fit: pdfWidget.BoxFit.fill)
)
);
}
)
);
}
bool bRes = await Printing.layoutPdf(onLayout: (format) async => pdf.save());
}
printing package verseion is printing: ^5.6.6 thank you.
Solved
Check if printing is complete in void onCompleted in PrintingHandler.java file.

Related

Go back to previous page in flutter

I have a flutter app that connects via bluetooth with a device by pressing on the device name from the list of paired devices. This is the coding :
final BluetoothDevice server;
DataCollectionPage({required this.server});
...............................................................................
child: ListView(
children: devices
.map((_device)=> BluetoothDeviceListEntry(
device: _device,
enabled: true,
onTap: (){
if (kDebugMode) {
print("item");
}
_startDataCollection(context, _device);
},
................................................................................
void _startDataCollection(BuildContext context, BluetoothDevice server){
Navigator.of(context).push(MaterialPageRoute(builder: (context){
return DataCollectionPage(server: server);
}));
}
Then once I navigate to the "DataCollectionPage" page, I perform some actions and data collection methods and at the end I will be in other page named "DataCollectionTimer". In this page a timer will be displayed on the screen for few seconds then at the end of this timer a Dialog will show to give some message and then finally Once I press the button close on this dialog, I want to go back to DataCollectionPage. So If I try to use
MaterialPageRoute( builder: (context) => DataCollectionPage(), ),
It will give an error because parameter 'server' is required which I obtained from the list of paired devices that was in a different class.
Is there a way to go back to DataCollectionPage from the current one without going all the way back to the page where the list of paired devices is there.
Thank you in advance
You need to make the server field optional and then use popUntil
final BluetoothDevice? server;
DataCollectionPage({this.server});

Basic QR code scanner in flutter + qr_code_scanner returning results repeated

I am building a QR scanner to help organize a collection. Basic data about the items is encoded into a json string then into a QR code. The generation of such labels programatically was successful. The next phase was to create a simple visor in flutter. The chosen library was qr_code_scanner. My simple app was to be a scanner which when detecting a valid QR code (one containing a json string describing the required structures) would redirect into another screen where data was displayed. The scanner detects the QR codes, the objects are parsed and a widget containing another scaffold is pushed. This is mostly what I want however an issue was detected: when a valid QR was detected the app would push the data display screen multiple times, sometimes as many as 9, thus breaking backward navigation.
The method responsible of handling the event is named "onQRViewCreated" (like in the example).
void onQRViewCreated(QRViewController controller){
setState(() => this.controller = controller);
controller.scannedDataStream.listen(
(qrData) {
setState(
() {
barcode = qrData;
if (barcode?.format == BarcodeFormat.qrcode) {
try {
Item item = Item.fromJSon(
jsonDecode(barcode?.code ?? "")
);
Navigator.push(
context,
MaterialPageRoute(
builder: (context) =>
ItemDisplay(
key: const Key("item"),
item: item
)
)
);
}
on FormatException {
Fluttertoast.showToast(msg: "Invalid QR Code!");
}
on Exception {
Fluttertoast.showToast(msg: "Error!");
}
}
}
);
}
);
}
I would like to be able to push the ItemDisplay only once but I don't know how to do it.
Thank you in advance
Put await controller.pauseCamera(); before the Navigator.push
I would suggest to use mobile_scanner package, which is a newer version from the same author. When creating MobileScanner widget of this package, there is an option allowDuplicates, which you can set to false to avoid this behaviour.

Flutter: save a generated PDF from preview page with a custom function

I'm using the pdf package (link to pub.dev page) to create documents inside my app.
How can I save the document from the preview page?
I know about the built-in print and share functions, but I need something else.
I need a function that does the following:
save the document to the device
upload it to Firebase Storage
delete the local file
I know how to do all of these steps, but I'm unable to access the Uint8List bytes of the pdf document that is being previewed... I've tried to add a PdfPreviewAction, but I still can't access the bytes of the document from it
all you have to do is call the save method in the Document() object
import "package:pdf/widgets.dart" as w;
final pdf = w.Document();
Future<Uint8List> getPDFData() async {
return await pdf.save();
}
you can do all the operations using the getPDFData() method
for example:
return PdfPreview(
build: (format) => getPdfData(),
actions: [
PdfPreviewAction(
icon: Icon(Icons.print),
onPressed: (context, fn, format) {
//if you call fn(format), you'll get Future<UInt8List>
}),
],
);

How to launch an application when Notification Received from flutter app

I am developing a mobile app and I want to open a splash screen or open startup page when I receive a notification.
Currently, I am using the following code
static Future<dynamic> myBackgroundMessageHandler(
Map<String, dynamic> message) async {
print("_backgroundMessageHandler");
_callBgHandler = 1;
if (message.containsKey('data')) {
// Handle data message
final dynamic data = message['data'];
print("_backgroundMessageHandler: ${data}");
DeviceApps.openApp("com.example.my_flutter_app");
}
if (message.containsKey('notification')) {
// Handle notification message
final dynamic notification = message['notification'];
print("_backgroundMessageHandler notification: ${notification}");
}
return Future<void>.value();
}
and the following error displayed
Attempt to invoke virtual method 'android.content.pm.PackageManager
android.app.Activity.getPackageManager()' on a null object reference
The last one month tried but no luck. If anyone knows let me share the code from flutter dart language
But Button press event it will work.
RaisedButton(
onPressed: () {
DeviceApps.openApp("com.example.my_flutter_app");
},
child: Text("Open App")
)
Default applications like a map, chrome, play store, email app, etc... All are open with no issue but the external app does not open notification background function.

Flutter - How to check is the app has a new version?

I create an app with Flutter. I need to force users to update the app when I upload a new version. I try this package, but I think that it doesn´t work. In the documentation, we can read that we can verify the version with this code.
Container(
margin: EdgeInsets.fromLTRB(12.0, 0.0, 12.0, 0.0),
child: UpgradeCard();
)
The problem is: I need to check the version in *'initState', not in Scaffold. So what is the right way to check the version on the app start?
I recommend trying out the Firebase Remote Config and update the minimum required version there. It's not a good practice to force update app on every update in the store. Also, some users can see the updated version in given store later than others. This is just how Google Play and AppStore work.
Thus, when you really need to force update the application you can increment the parameter on Firebase e.g. a day after update in the store.
Simple code to trigger the dialog can look as following:
Future<bool> checkUpdates() async {
await remoteConfig.fetch();
await remoteConfig.activateFetched();
final requiredBuildNumber = remoteConfig.getInt(Platform.isAndroid
? 'requiredBuildNumberAndroid'
: 'requiredBuildNumberIOS');
final currentBuildNumber = int.parse(packageInfo.buildNumber);
return currentBuildNumber < requiredBuildNumber;
}
This requires package_info package to be added as well as firebase_remote_config.
To open the app in the store you need to use url_launcher package and just pass URL to your app.
you can call https://itunes.apple.com/lookup?bundleId=$id or https://play.google.com/store/apps/details?id=$id to receive the newest app version available on the stores.
i can recommend this package to do this: https://pub.dev/packages/new_version
You can check your app version like
#override
void initState() {
super.initState();
Timer(
Duration(seconds: 3), // put your stuff here
() => Navigator.of(context).pushReplacement(MaterialPageRoute(
builder: (BuildContext context) => LoginScreen())));}
and presume one thing this code must be in spalsh screen or home screen
and there you can check app version forcefully stop any app which is belonged old version
Try out the in app update package- https://pub.dev/packages/in_app_update which works on Android and for iOS, try- https://pub.dev/packages/upgrader.
Use this package -> new_version
It's awesome & easy :)
///initialize your variable
final newVersion = NewVersion(
iOSId: 'com.google.Vespa',
androidId: 'com.google.android.apps.cloudconsole',
);
//and use this inside of your widget or controller
#override
Widget build(BuildContext context) {
newVersion.showAlertIfNecessary(context: context);
return Container();
}
If you just want the current version number from the App Store and Play Store. You can use the upgrader package API like this:
import 'dart:developer';
import 'dart:io';
import 'package:html/dom.dart';
import 'package:upgrader/upgrader.dart';
Future<String?> getStoreVersion(String myAppBundleId) async {
String? storeVersion;
if (Platform.isAndroid) {
PlayStoreSearchAPI playStoreSearchAPI = PlayStoreSearchAPI();
Document? result = await playStoreSearchAPI.lookupById(myAppBundleId, country: 'US');
if (result != null) storeVersion = PlayStoreResults.version(result);
log('PlayStore version: $storeVersion}');
} else if (Platform.isIOS) {
ITunesSearchAPI iTunesSearchAPI = ITunesSearchAPI();
Map<dynamic, dynamic>? result =
await iTunesSearchAPI.lookupByBundleId(myAppBundleId, country: 'US');
if (result != null) storeVersion = ITunesResults.version(result);
log('AppStore version: $storeVersion}');
} else {
storeVersion = null;
}
return storeVersion;
}
EDIT: If your app is NOT available on the US App Store or Play Store, you need to change the country code.