@capgo/capacitor-printer 7.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,362 @@
1
+ package com.capgo.printer;
2
+
3
+ import android.app.Activity;
4
+ import android.content.Context;
5
+ import android.content.Intent;
6
+ import android.graphics.Bitmap;
7
+ import android.graphics.BitmapFactory;
8
+ import android.net.Uri;
9
+ import android.os.Build;
10
+ import android.os.Bundle;
11
+ import android.os.CancellationSignal;
12
+ import android.os.ParcelFileDescriptor;
13
+ import android.print.PageRange;
14
+ import android.print.PrintAttributes;
15
+ import android.print.PrintDocumentAdapter;
16
+ import android.print.PrintDocumentInfo;
17
+ import android.print.PrintManager;
18
+ import android.util.Base64;
19
+ import android.webkit.WebView;
20
+ import android.webkit.WebViewClient;
21
+ import androidx.annotation.NonNull;
22
+ import androidx.documentfile.provider.DocumentFile;
23
+ import androidx.print.PrintHelper;
24
+ import java.io.File;
25
+ import java.io.FileOutputStream;
26
+ import java.io.IOException;
27
+ import java.io.InputStream;
28
+ import java.io.OutputStream;
29
+
30
+ public class Printer {
31
+
32
+ private final Context context;
33
+ private final Activity activity;
34
+
35
+ public Printer(Context context, Activity activity) {
36
+ this.context = context;
37
+ this.activity = activity;
38
+ }
39
+
40
+ public void printBase64(String data, String mimeType, String name) throws Exception {
41
+ byte[] decodedData = Base64.decode(data, Base64.DEFAULT);
42
+
43
+ // Handle images separately
44
+ if (mimeType.startsWith("image/")) {
45
+ Bitmap bitmap = BitmapFactory.decodeByteArray(decodedData, 0, decodedData.length);
46
+ if (bitmap == null) {
47
+ throw new Exception("Failed to decode image from base64 data");
48
+ }
49
+ printImage(bitmap, name);
50
+ return;
51
+ }
52
+
53
+ // For PDFs and other documents, save to temp file and print
54
+ File tempFile = saveTempFile(decodedData, mimeType);
55
+ printDocument(tempFile, name);
56
+ }
57
+
58
+ public void printFile(String path, String mimeType, String name) throws Exception {
59
+ Uri uri = Uri.parse(path);
60
+
61
+ // Handle content:// URIs
62
+ if ("content".equals(uri.getScheme())) {
63
+ DocumentFile documentFile = DocumentFile.fromSingleUri(context, uri);
64
+ if (documentFile == null || !documentFile.exists()) {
65
+ throw new Exception("File not found: " + path);
66
+ }
67
+
68
+ // Determine MIME type if not provided
69
+ if (mimeType == null) {
70
+ mimeType = documentFile.getType();
71
+ }
72
+
73
+ // Handle images separately
74
+ if (mimeType != null && mimeType.startsWith("image/")) {
75
+ printImageFromUri(uri, name);
76
+ return;
77
+ }
78
+
79
+ // For documents, use direct URI
80
+ printDocumentFromUri(uri, name);
81
+ } else {
82
+ // Handle file:// URIs
83
+ File file = new File(uri.getPath());
84
+ if (!file.exists()) {
85
+ throw new Exception("File not found: " + path);
86
+ }
87
+
88
+ // Determine MIME type if not provided
89
+ if (mimeType == null) {
90
+ mimeType = getMimeTypeFromPath(file.getPath());
91
+ }
92
+
93
+ // Handle images separately
94
+ if (mimeType != null && mimeType.startsWith("image/")) {
95
+ Bitmap bitmap = BitmapFactory.decodeFile(file.getPath());
96
+ if (bitmap == null) {
97
+ throw new Exception("Failed to decode image from file");
98
+ }
99
+ printImage(bitmap, name);
100
+ return;
101
+ }
102
+
103
+ printDocument(file, name);
104
+ }
105
+ }
106
+
107
+ public void printHtml(String html, String name) throws Exception {
108
+ // Create a WebView to render the HTML
109
+ WebView webView = new WebView(context);
110
+ webView.setWebViewClient(
111
+ new WebViewClient() {
112
+ @Override
113
+ public void onPageFinished(WebView view, String url) {
114
+ createWebPrintJob(view, name);
115
+ }
116
+ }
117
+ );
118
+
119
+ webView.loadDataWithBaseURL(null, html, "text/html", "UTF-8", null);
120
+ }
121
+
122
+ public void printPdf(String path, String name) throws Exception {
123
+ Uri uri = Uri.parse(path);
124
+
125
+ // Handle content:// URIs
126
+ if ("content".equals(uri.getScheme())) {
127
+ printDocumentFromUri(uri, name);
128
+ } else {
129
+ // Handle file:// URIs
130
+ File file = new File(uri.getPath());
131
+ if (!file.exists()) {
132
+ throw new Exception("File not found: " + path);
133
+ }
134
+ printDocument(file, name);
135
+ }
136
+ }
137
+
138
+ public void printWebView(WebView webView, String name) throws Exception {
139
+ if (webView == null) {
140
+ throw new Exception("WebView not available");
141
+ }
142
+ createWebPrintJob(webView, name);
143
+ }
144
+
145
+ // MARK: - Private Helper Methods
146
+
147
+ private void printImage(Bitmap bitmap, String name) {
148
+ PrintHelper printHelper = new PrintHelper(activity);
149
+ printHelper.setScaleMode(PrintHelper.SCALE_MODE_FIT);
150
+ printHelper.printBitmap(name, bitmap);
151
+ }
152
+
153
+ private void printImageFromUri(Uri uri, String name) throws Exception {
154
+ try {
155
+ InputStream inputStream = context.getContentResolver().openInputStream(uri);
156
+ if (inputStream == null) {
157
+ throw new Exception("Failed to open image file");
158
+ }
159
+ Bitmap bitmap = BitmapFactory.decodeStream(inputStream);
160
+ inputStream.close();
161
+
162
+ if (bitmap == null) {
163
+ throw new Exception("Failed to decode image");
164
+ }
165
+
166
+ printImage(bitmap, name);
167
+ } catch (IOException e) {
168
+ throw new Exception("Failed to read image file: " + e.getMessage());
169
+ }
170
+ }
171
+
172
+ private void printDocument(File file, String name) throws Exception {
173
+ PrintManager printManager = (PrintManager) context.getSystemService(Context.PRINT_SERVICE);
174
+ if (printManager == null) {
175
+ throw new Exception("Print service not available");
176
+ }
177
+
178
+ PrintDocumentAdapter printAdapter = new PdfDocumentAdapter(file);
179
+ printManager.print(name, printAdapter, new PrintAttributes.Builder().build());
180
+ }
181
+
182
+ private void printDocumentFromUri(Uri uri, String name) throws Exception {
183
+ PrintManager printManager = (PrintManager) context.getSystemService(Context.PRINT_SERVICE);
184
+ if (printManager == null) {
185
+ throw new Exception("Print service not available");
186
+ }
187
+
188
+ PrintDocumentAdapter printAdapter = new UriDocumentAdapter(uri);
189
+ printManager.print(name, printAdapter, new PrintAttributes.Builder().build());
190
+ }
191
+
192
+ private void createWebPrintJob(WebView webView, String name) {
193
+ PrintManager printManager = (PrintManager) context.getSystemService(Context.PRINT_SERVICE);
194
+ if (printManager == null) {
195
+ return;
196
+ }
197
+
198
+ PrintDocumentAdapter printAdapter = webView.createPrintDocumentAdapter(name);
199
+ printManager.print(name, printAdapter, new PrintAttributes.Builder().build());
200
+ }
201
+
202
+ private File saveTempFile(byte[] data, String mimeType) throws IOException {
203
+ String extension = getExtensionFromMimeType(mimeType);
204
+ File tempFile = File.createTempFile("print_temp", extension, context.getCacheDir());
205
+
206
+ try (FileOutputStream fos = new FileOutputStream(tempFile)) {
207
+ fos.write(data);
208
+ }
209
+
210
+ return tempFile;
211
+ }
212
+
213
+ private String getExtensionFromMimeType(String mimeType) {
214
+ switch (mimeType.toLowerCase()) {
215
+ case "application/pdf":
216
+ return ".pdf";
217
+ case "image/jpeg":
218
+ case "image/jpg":
219
+ return ".jpg";
220
+ case "image/png":
221
+ return ".png";
222
+ case "image/gif":
223
+ return ".gif";
224
+ default:
225
+ return ".tmp";
226
+ }
227
+ }
228
+
229
+ private String getMimeTypeFromPath(String path) {
230
+ String extension = path.substring(path.lastIndexOf(".") + 1).toLowerCase();
231
+ switch (extension) {
232
+ case "pdf":
233
+ return "application/pdf";
234
+ case "jpg":
235
+ case "jpeg":
236
+ return "image/jpeg";
237
+ case "png":
238
+ return "image/png";
239
+ case "gif":
240
+ return "image/gif";
241
+ default:
242
+ return "application/octet-stream";
243
+ }
244
+ }
245
+
246
+ // Custom PrintDocumentAdapter for PDF files
247
+ private class PdfDocumentAdapter extends PrintDocumentAdapter {
248
+
249
+ private final File file;
250
+
251
+ public PdfDocumentAdapter(File file) {
252
+ this.file = file;
253
+ }
254
+
255
+ @Override
256
+ public void onLayout(
257
+ PrintAttributes oldAttributes,
258
+ PrintAttributes newAttributes,
259
+ CancellationSignal cancellationSignal,
260
+ LayoutResultCallback callback,
261
+ Bundle extras
262
+ ) {
263
+ if (cancellationSignal.isCanceled()) {
264
+ callback.onLayoutCancelled();
265
+ return;
266
+ }
267
+
268
+ PrintDocumentInfo info = new PrintDocumentInfo.Builder(file.getName())
269
+ .setContentType(PrintDocumentInfo.CONTENT_TYPE_DOCUMENT)
270
+ .build();
271
+
272
+ callback.onLayoutFinished(info, true);
273
+ }
274
+
275
+ @Override
276
+ public void onWrite(
277
+ PageRange[] pages,
278
+ ParcelFileDescriptor destination,
279
+ CancellationSignal cancellationSignal,
280
+ WriteResultCallback callback
281
+ ) {
282
+ try (
283
+ InputStream input = context.openFileInput(file.getName());
284
+ OutputStream output = new FileOutputStream(destination.getFileDescriptor())
285
+ ) {
286
+ byte[] buf = new byte[1024];
287
+ int bytesRead;
288
+ while ((bytesRead = input.read(buf)) > 0) {
289
+ output.write(buf, 0, bytesRead);
290
+ }
291
+
292
+ callback.onWriteFinished(new PageRange[] { PageRange.ALL_PAGES });
293
+ } catch (Exception e) {
294
+ callback.onWriteFailed(e.getMessage());
295
+ }
296
+ }
297
+ }
298
+
299
+ // Custom PrintDocumentAdapter for URIs
300
+ private class UriDocumentAdapter extends PrintDocumentAdapter {
301
+
302
+ private final Uri uri;
303
+
304
+ public UriDocumentAdapter(Uri uri) {
305
+ this.uri = uri;
306
+ }
307
+
308
+ @Override
309
+ public void onLayout(
310
+ PrintAttributes oldAttributes,
311
+ PrintAttributes newAttributes,
312
+ CancellationSignal cancellationSignal,
313
+ LayoutResultCallback callback,
314
+ Bundle extras
315
+ ) {
316
+ if (cancellationSignal.isCanceled()) {
317
+ callback.onLayoutCancelled();
318
+ return;
319
+ }
320
+
321
+ String fileName = "Document";
322
+ DocumentFile documentFile = DocumentFile.fromSingleUri(context, uri);
323
+ if (documentFile != null && documentFile.getName() != null) {
324
+ fileName = documentFile.getName();
325
+ }
326
+
327
+ PrintDocumentInfo info = new PrintDocumentInfo.Builder(fileName)
328
+ .setContentType(PrintDocumentInfo.CONTENT_TYPE_DOCUMENT)
329
+ .build();
330
+
331
+ callback.onLayoutFinished(info, true);
332
+ }
333
+
334
+ @Override
335
+ public void onWrite(
336
+ PageRange[] pages,
337
+ ParcelFileDescriptor destination,
338
+ CancellationSignal cancellationSignal,
339
+ WriteResultCallback callback
340
+ ) {
341
+ try (
342
+ InputStream input = context.getContentResolver().openInputStream(uri);
343
+ OutputStream output = new FileOutputStream(destination.getFileDescriptor())
344
+ ) {
345
+ if (input == null) {
346
+ callback.onWriteFailed("Failed to open file");
347
+ return;
348
+ }
349
+
350
+ byte[] buf = new byte[1024];
351
+ int bytesRead;
352
+ while ((bytesRead = input.read(buf)) > 0) {
353
+ output.write(buf, 0, bytesRead);
354
+ }
355
+
356
+ callback.onWriteFinished(new PageRange[] { PageRange.ALL_PAGES });
357
+ } catch (Exception e) {
358
+ callback.onWriteFailed(e.getMessage());
359
+ }
360
+ }
361
+ }
362
+ }
@@ -0,0 +1,122 @@
1
+ package com.capgo.printer;
2
+
3
+ import com.getcapacitor.JSObject;
4
+ import com.getcapacitor.Plugin;
5
+ import com.getcapacitor.PluginCall;
6
+ import com.getcapacitor.PluginMethod;
7
+ import com.getcapacitor.annotation.CapacitorPlugin;
8
+
9
+ @CapacitorPlugin(name = "Printer")
10
+ public class PrinterPlugin extends Plugin {
11
+
12
+ private final String pluginVersion = "7.0.0";
13
+
14
+ private Printer implementation;
15
+
16
+ @Override
17
+ public void load() {
18
+ implementation = new Printer(getContext(), getActivity());
19
+ }
20
+
21
+ @PluginMethod
22
+ public void printBase64(PluginCall call) {
23
+ String data = call.getString("data");
24
+ String mimeType = call.getString("mimeType");
25
+ String name = call.getString("name", "Document");
26
+
27
+ if (data == null) {
28
+ call.reject("data is required");
29
+ return;
30
+ }
31
+
32
+ if (mimeType == null) {
33
+ call.reject("mimeType is required");
34
+ return;
35
+ }
36
+
37
+ try {
38
+ implementation.printBase64(data, mimeType, name);
39
+ call.resolve();
40
+ } catch (Exception e) {
41
+ call.reject("Failed to print base64 data: " + e.getMessage(), e);
42
+ }
43
+ }
44
+
45
+ @PluginMethod
46
+ public void printFile(PluginCall call) {
47
+ String path = call.getString("path");
48
+ String mimeType = call.getString("mimeType");
49
+ String name = call.getString("name", "Document");
50
+
51
+ if (path == null) {
52
+ call.reject("path is required");
53
+ return;
54
+ }
55
+
56
+ try {
57
+ implementation.printFile(path, mimeType, name);
58
+ call.resolve();
59
+ } catch (Exception e) {
60
+ call.reject("Failed to print file: " + e.getMessage(), e);
61
+ }
62
+ }
63
+
64
+ @PluginMethod
65
+ public void printHtml(PluginCall call) {
66
+ String html = call.getString("html");
67
+ String name = call.getString("name", "Document");
68
+
69
+ if (html == null) {
70
+ call.reject("html is required");
71
+ return;
72
+ }
73
+
74
+ try {
75
+ implementation.printHtml(html, name);
76
+ call.resolve();
77
+ } catch (Exception e) {
78
+ call.reject("Failed to print HTML: " + e.getMessage(), e);
79
+ }
80
+ }
81
+
82
+ @PluginMethod
83
+ public void printPdf(PluginCall call) {
84
+ String path = call.getString("path");
85
+ String name = call.getString("name", "Document");
86
+
87
+ if (path == null) {
88
+ call.reject("path is required");
89
+ return;
90
+ }
91
+
92
+ try {
93
+ implementation.printPdf(path, name);
94
+ call.resolve();
95
+ } catch (Exception e) {
96
+ call.reject("Failed to print PDF: " + e.getMessage(), e);
97
+ }
98
+ }
99
+
100
+ @PluginMethod
101
+ public void printWebView(PluginCall call) {
102
+ String name = call.getString("name", "Document");
103
+
104
+ try {
105
+ implementation.printWebView(getBridge().getWebView(), name);
106
+ call.resolve();
107
+ } catch (Exception e) {
108
+ call.reject("Failed to print web view: " + e.getMessage(), e);
109
+ }
110
+ }
111
+
112
+ @PluginMethod
113
+ public void getPluginVersion(final PluginCall call) {
114
+ try {
115
+ final JSObject ret = new JSObject();
116
+ ret.put("version", this.pluginVersion);
117
+ call.resolve(ret);
118
+ } catch (final Exception e) {
119
+ call.reject("Could not get plugin version", e);
120
+ }
121
+ }
122
+ }