David PHAM-VAN

Add printing completion

# Changelog
## 2.1.5
- Add printing completion
## 2.1.4
- Update example to show saved documents on iOS Files app
... ...
... ... @@ -30,6 +30,8 @@ import android.print.PdfConvert;
import android.print.PrintAttributes;
import android.print.PrintDocumentAdapter;
import android.print.PrintDocumentInfo;
import android.print.PrintJob;
import android.print.PrintJobInfo;
import android.print.PrintManager;
import android.print.pdf.PrintedPdfDocument;
import android.webkit.WebView;
... ... @@ -56,6 +58,7 @@ public class PrintingPlugin extends PrintDocumentAdapter implements MethodCallHa
private final Activity activity;
private final MethodChannel channel;
private PrintedPdfDocument mPdfDocument;
private PrintJob printJob;
private byte[] documentData;
private String jobName;
private LayoutResultCallback callback;
... ... @@ -126,7 +129,33 @@ public class PrintingPlugin extends PrintDocumentAdapter implements MethodCallHa
@Override
public void onFinish() {
// noinspection ResultOfMethodCallIgnored
try {
while (true) {
int state = printJob.getInfo().getState();
if (state == PrintJobInfo.STATE_COMPLETED) {
HashMap<String, Object> args = new HashMap<>();
args.put("completed", true);
channel.invokeMethod("onCompleted", args);
break;
} else if (state == PrintJobInfo.STATE_CANCELED) {
HashMap<String, Object> args = new HashMap<>();
args.put("completed", false);
channel.invokeMethod("onCompleted", args);
break;
}
Thread.sleep(200);
}
} catch (Exception e) {
HashMap<String, Object> args = new HashMap<>();
args.put("completed", printJob.isCompleted());
args.put("error", e.getMessage());
channel.invokeMethod("onCompleted", args);
}
printJob = null;
mPdfDocument = null;
}
@Override
... ... @@ -136,7 +165,7 @@ public class PrintingPlugin extends PrintDocumentAdapter implements MethodCallHa
jobName =
call.argument("name") == null ? "Document" : (String) call.argument("name");
assert jobName != null;
printManager.print(jobName, this, null);
printJob = printManager.print(jobName, this, null);
result.success(0);
break;
case "writePdf":
... ...
... ... @@ -30,9 +30,11 @@ class MyAppState extends State<MyApp> {
Future<void> _printPdf() async {
print('Print ...');
await Printing.layoutPdf(
final bool result = await Printing.layoutPdf(
onLayout: (PdfPageFormat format) async =>
(await generateDocument(format)).save());
print('Document printed: $result');
}
Future<void> _saveAsFile() async {
... ...
... ... @@ -87,13 +87,24 @@ public class SwiftPrintingPlugin: NSObject, FlutterPlugin, UIPrintInteractionCon
if !completed, error != nil {
print("Unable to print: \(error?.localizedDescription ?? "unknown error")")
}
let data: NSDictionary = [
"completed": completed,
"error": error?.localizedDescription as Any,
]
channel?.invokeMethod("onCompleted", arguments: data)
renderer = nil
}
func printPdf(_ name: String) {
let printing = UIPrintInteractionController.isPrintingAvailable
if !printing {
print("printing not available")
let data: NSDictionary = [
"completed": false,
"error": "Printing not available",
]
channel?.invokeMethod("onCompleted", arguments: data)
return
}
... ...
... ... @@ -22,6 +22,7 @@ mixin Printing {
static const MethodChannel _channel = MethodChannel('printing');
static LayoutCallback _onLayout;
static Completer<List<int>> _onHtmlRendered;
static Completer<bool> _onCompleted;
static Future<void> _handleMethod(MethodCall call) async {
switch (call.method) {
... ... @@ -38,6 +39,15 @@ mixin Printing {
'doc': Uint8List.fromList(bytes),
};
return await _channel.invokeMethod('writePdf', params);
case 'onCompleted':
final bool completed = call.arguments['completed'];
final String error = call.arguments['error'];
if (completed == false && error != null) {
_onCompleted.completeError(error);
} else {
_onCompleted.complete(completed);
}
break;
case 'onHtmlRendered':
_onHtmlRendered.complete(call.arguments);
break;
... ... @@ -50,12 +60,20 @@ mixin Printing {
/// Prints a Pdf document to a local printer using the platform UI
/// the Pdf document is re-built in a [LayoutCallback] each time the
/// user changes a setting like the page format or orientation.
static Future<void> layoutPdf(
{@required LayoutCallback onLayout, String name = 'Document'}) async {
///
/// returns a future with a `bool` set to true if the document is printed
/// and false if it is canceled.
/// throws an exception in case of error
static Future<bool> layoutPdf({
@required LayoutCallback onLayout,
String name = 'Document',
}) async {
_onCompleted = Completer<bool>();
_onLayout = onLayout;
_channel.setMethodCallHandler(_handleMethod);
final Map<String, dynamic> params = <String, dynamic>{'name': name};
return await _channel.invokeMethod('printPdf', params);
await _channel.invokeMethod<int>('printPdf', params);
return _onCompleted.future;
}
/// Prints a [PdfDocument] or a pdf stream to a local printer using the platform UI
... ...
... ... @@ -4,7 +4,7 @@ description: Plugin that allows Flutter apps to generate and print documents to
homepage: https://github.com/DavBfr/dart_pdf/tree/master/printing
repository: https://github.com/DavBfr/dart_pdf
issue_tracker: https://github.com/DavBfr/dart_pdf/issues
version: 2.1.4
version: 2.1.5
environment:
sdk: ">=2.1.0 <3.0.0"
... ...