@ruhiverse/thermal-printer-plugin 1.0.11 → 1.0.15

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.
package/README.md CHANGED
@@ -136,22 +136,28 @@ Returns a list of connected USB printers.
136
136
 
137
137
  ## Platform Support
138
138
 
139
- - Android (USB & Bluetooth)
140
- - iOS (USB & Bluetooth - basic implementation)
141
- - Web (not supported)
139
+ | Platform | Bluetooth | USB | Printer Discovery |
140
+ | -------- | --------- | --- | ----------------- |
141
+ | Android | ✅ | ✅ | ✅ (paired + scan) |
142
+ | iOS | ✅ (MFi & BLE) | ✅ (MFi only) | ✅ (MFi + BLE scan) |
143
+ | Web | ❌ | ❌ | ❌ |
142
144
 
143
145
  ## Android Setup
144
146
 
145
147
  ### Permissions
146
148
 
147
- The plugin automatically requests the following permissions:
149
+ The plugin declares the following permissions in its `AndroidManifest.xml`:
148
150
 
149
151
  - `BLUETOOTH`
150
152
  - `BLUETOOTH_ADMIN`
151
153
  - `BLUETOOTH_CONNECT` (Android 12+)
152
154
  - `BLUETOOTH_SCAN` (Android 12+)
155
+ - `ACCESS_FINE_LOCATION` (required for Bluetooth scanning on Android 6-11)
156
+ - `ACCESS_COARSE_LOCATION`
153
157
  - `USB_PERMISSION`
154
158
 
159
+ The plugin automatically requests Bluetooth permissions at runtime when needed.
160
+
155
161
  ### USB Printing
156
162
 
157
163
  1. Connect your thermal printer via USB
@@ -160,20 +166,21 @@ The plugin automatically requests the following permissions:
160
166
 
161
167
  ### Bluetooth Printing
162
168
 
163
- 1. Pair your thermal printer with the device via Bluetooth settings
164
- 2. The plugin will automatically find and connect to paired printers
169
+ 1. Pair your thermal printer with the device via **Android Settings > Bluetooth**
170
+ 2. Use `listBluetoothPrinters()` to get the list of paired devices
171
+ 3. Use `printByBluetooth()` with the printer's `address` to print, or omit `address` to use the first paired printer
165
172
 
166
173
  ## iOS Setup
167
174
 
168
- ### Info.plist Configuration
175
+ ### Required Info.plist Configuration
169
176
 
170
- Add the following to your app's `Info.plist`:
177
+ Add the following keys to your app's `Info.plist`. **Without these, Bluetooth will not work on iOS.**
171
178
 
172
179
  ```xml
173
180
  <key>NSBluetoothAlwaysUsageDescription</key>
174
- <string>This app needs Bluetooth access to connect to thermal printers</string>
181
+ <string>This app needs Bluetooth access to connect to thermal printers.</string>
175
182
  <key>NSBluetoothPeripheralUsageDescription</key>
176
- <string>This app needs Bluetooth access to connect to thermal printers</string>
183
+ <string>This app needs Bluetooth access to connect to thermal printers.</string>
177
184
  <key>UISupportedExternalAccessoryProtocols</key>
178
185
  <array>
179
186
  <string>com.epson.escpos</string>
@@ -181,72 +188,70 @@ Add the following to your app's `Info.plist`:
181
188
  </array>
182
189
  ```
183
190
 
184
- **Note:** iOS implementation may require additional setup based on your printer model. USB printing on iOS requires MFi (Made for iPhone) certification.
191
+ | Key | Required | Description |
192
+ | --- | -------- | ----------- |
193
+ | `NSBluetoothAlwaysUsageDescription` | **Yes** | iOS will silently block Bluetooth access without this. Triggers the permission dialog. |
194
+ | `NSBluetoothPeripheralUsageDescription` | **Yes** | Required for connecting to Bluetooth peripherals (iOS 12 and earlier). |
195
+ | `UISupportedExternalAccessoryProtocols` | **Yes** (for MFi printers) | Lists the protocol strings your printer supports. Update with your printer's protocols. |
185
196
 
186
- ## Local Testing
197
+ ### iOS Bluetooth Printing
187
198
 
188
- ### Testing Locally Before Publishing to npm
199
+ The plugin supports two types of Bluetooth connections on iOS:
189
200
 
190
- 1. **Link the plugin locally:**
201
+ **MFi / ExternalAccessory printers (classic Bluetooth):**
202
+ - Requires the printer to be MFi-certified (Made for iPhone)
203
+ - Uses the ExternalAccessory framework
204
+ - Printer must be paired in iOS Settings > Bluetooth
205
+ - Protocol strings must be listed in `UISupportedExternalAccessoryProtocols`
191
206
 
192
- ```bash
193
- cd /Users/apple/Desktop/ionic/workspace/plugin/thermal-printer-plugin
194
- npm link
195
- ```
207
+ **BLE printers (Bluetooth Low Energy):**
208
+ - Uses CoreBluetooth framework
209
+ - Discovered via BLE scanning (4-second scan)
210
+ - Use the `address` from `listBluetoothPrinters()` when calling `printByBluetooth()`
196
211
 
197
- 2. **In your Ionic/Capacitor project (e.g., milkwala project):**
212
+ ### iOS USB Printing
198
213
 
199
- ```bash
200
- cd /path/to/milkwala/project
201
- npm link @ruhiverse/thermal-printer-plugin
202
- npx cap sync
203
- ```
214
+ USB printing on iOS requires MFi (Made for iPhone) certification for the printer. The printer is accessed through the ExternalAccessory framework.
204
215
 
205
- 3. **Build and test:**
216
+ ### iOS Troubleshooting
206
217
 
207
- ```bash
208
- # For Android
209
- npx cap run android
210
-
211
- # For iOS
212
- npx cap run ios
213
- ```
218
+ | Issue | Solution |
219
+ | ----- | -------- |
220
+ | `listBluetoothPrinters()` returns empty | Make sure `NSBluetoothAlwaysUsageDescription` is in your Info.plist and Bluetooth permission is granted |
221
+ | Printer not found (MFi) | Verify the printer's protocol string is listed in `UISupportedExternalAccessoryProtocols` |
222
+ | Printer not found (BLE) | Ensure the printer is powered on and in range. BLE scan runs for 4 seconds |
223
+ | Permission dialog not showing | Delete and reinstall the app to reset permissions |
214
224
 
215
- ### Alternative: Using file path
225
+ ## Local Development
216
226
 
217
- You can also install directly from the local path:
227
+ ### Testing Locally Before Publishing
218
228
 
219
- ```bash
220
- cd /path/to/milkwala/project
221
- npm install /Users/apple/Desktop/ionic/workspace/plugin/thermal-printer-plugin
222
- npx cap sync
223
- ```
224
-
225
- ## Publishing to npm
226
-
227
- 1. **Login to npm (if not already logged in):**
229
+ 1. **Link the plugin locally:**
228
230
 
229
231
  ```bash
230
- npm login
231
- # Use your ruhiverse npm account credentials
232
+ cd path/to/thermal-printer-plugin
233
+ npm link
232
234
  ```
233
235
 
234
- 2. **Build the plugin:**
236
+ 2. **In your Ionic/Capacitor project:**
235
237
 
236
238
  ```bash
237
- npm run build
239
+ cd path/to/your-project
240
+ npm link @ruhiverse/thermal-printer-plugin
241
+ npx cap sync
238
242
  ```
239
243
 
240
- 3. **Publish to npm:**
244
+ 3. **Build and test:**
241
245
 
242
246
  ```bash
243
- npm publish --access public
247
+ npx cap run android
248
+ npx cap run ios
244
249
  ```
245
250
 
246
- 4. **After publishing, install in your project:**
251
+ ### Alternative: Install from local path
247
252
 
248
253
  ```bash
249
- npm install @ruhiverse/thermal-printer-plugin
254
+ npm install path/to/thermal-printer-plugin
250
255
  npx cap sync
251
256
  ```
252
257
 
@@ -1,7 +1,5 @@
1
1
  package com.ruhiverse.thermalprinter;
2
2
 
3
- import android.app.AlertDialog;
4
- import android.app.ProgressDialog;
5
3
  import android.content.Context;
6
4
  import android.os.AsyncTask;
7
5
 
@@ -28,7 +26,6 @@ public abstract class AsyncEscPosPrint extends AsyncTask<AsyncEscPosPrinter, Int
28
26
  protected final static int PROGRESS_PRINTING = 3;
29
27
  protected final static int PROGRESS_PRINTED = 4;
30
28
 
31
- protected ProgressDialog dialog;
32
29
  protected WeakReference<Context> weakContext;
33
30
  protected OnPrintFinished onPrintFinished;
34
31
 
@@ -95,91 +92,14 @@ public abstract class AsyncEscPosPrint extends AsyncTask<AsyncEscPosPrinter, Int
95
92
  }
96
93
 
97
94
  protected void onPreExecute() {
98
- if (this.dialog == null) {
99
- Context context = weakContext.get();
100
-
101
- if (context == null) {
102
- return;
103
- }
104
-
105
- this.dialog = new ProgressDialog(context);
106
- this.dialog.setTitle("Printing in progress...");
107
- this.dialog.setMessage("...");
108
- this.dialog.setProgressNumberFormat("%1d / %2d");
109
- this.dialog.setCancelable(false);
110
- this.dialog.setIndeterminate(false);
111
- this.dialog.setProgressStyle(ProgressDialog.STYLE_HORIZONTAL);
112
- this.dialog.show();
113
- }
95
+ // No UI progress is handled silently
114
96
  }
115
97
 
116
98
  protected void onProgressUpdate(Integer... progress) {
117
- switch (progress[0]) {
118
- case AsyncEscPosPrint.PROGRESS_CONNECTING:
119
- this.dialog.setMessage("Connecting printer...");
120
- break;
121
- case AsyncEscPosPrint.PROGRESS_CONNECTED:
122
- this.dialog.setMessage("Printer is connected...");
123
- break;
124
- case AsyncEscPosPrint.PROGRESS_PRINTING:
125
- this.dialog.setMessage("Printer is printing...");
126
- break;
127
- case AsyncEscPosPrint.PROGRESS_PRINTED:
128
- this.dialog.setMessage("Printer has finished...");
129
- break;
130
- }
131
- this.dialog.setProgress(progress[0]);
132
- this.dialog.setMax(4);
99
+ // No UI — progress is handled silently
133
100
  }
134
101
 
135
102
  protected void onPostExecute(PrinterStatus result) {
136
- this.dialog.dismiss();
137
- this.dialog = null;
138
-
139
- Context context = weakContext.get();
140
-
141
- if (context == null) {
142
- return;
143
- }
144
-
145
- switch (result.getPrinterStatus()) {
146
- case AsyncEscPosPrint.FINISH_SUCCESS:
147
- new AlertDialog.Builder(context)
148
- .setTitle("Success")
149
- .setMessage("Print completed successfully!")
150
- .show();
151
- break;
152
- case AsyncEscPosPrint.FINISH_NO_PRINTER:
153
- new AlertDialog.Builder(context)
154
- .setTitle("No printer")
155
- .setMessage("The application can't find any printer connected.")
156
- .show();
157
- break;
158
- case AsyncEscPosPrint.FINISH_PRINTER_DISCONNECTED:
159
- new AlertDialog.Builder(context)
160
- .setTitle("Broken connection")
161
- .setMessage("Unable to connect the printer.")
162
- .show();
163
- break;
164
- case AsyncEscPosPrint.FINISH_PARSER_ERROR:
165
- new AlertDialog.Builder(context)
166
- .setTitle("Invalid formatted text")
167
- .setMessage("It seems to be an invalid syntax problem.")
168
- .show();
169
- break;
170
- case AsyncEscPosPrint.FINISH_ENCODING_ERROR:
171
- new AlertDialog.Builder(context)
172
- .setTitle("Bad selected encoding")
173
- .setMessage("The selected encoding character returning an error.")
174
- .show();
175
- break;
176
- case AsyncEscPosPrint.FINISH_BARCODE_ERROR:
177
- new AlertDialog.Builder(context)
178
- .setTitle("Invalid barcode")
179
- .setMessage("Data send to be converted to barcode or QR code seems to be invalid.")
180
- .show();
181
- break;
182
- }
183
103
  if(this.onPrintFinished != null) {
184
104
  if (result.getPrinterStatus() == AsyncEscPosPrint.FINISH_SUCCESS) {
185
105
  this.onPrintFinished.onSuccess(result.getAsyncEscPosPrinter());
package/dist/docs.json CHANGED
@@ -53,9 +53,9 @@
53
53
  },
54
54
  {
55
55
  "name": "listBluetoothPrinters",
56
- "signature": "() => Promise<{ name: string; address: string; }[]>",
56
+ "signature": "() => Promise<{ printers: { name: string; address: string; }[]; }>",
57
57
  "parameters": [],
58
- "returns": "Promise<{ name: string; address: string; }[]>",
58
+ "returns": "Promise<{ printers: { name: string; address: string; }[]; }>",
59
59
  "tags": [],
60
60
  "docs": "Get list of paired Bluetooth printers",
61
61
  "complexTypes": [],
@@ -63,9 +63,9 @@
63
63
  },
64
64
  {
65
65
  "name": "listUsbPrinters",
66
- "signature": "() => Promise<{ name: string; address: string; }[]>",
66
+ "signature": "() => Promise<{ printers: { name: string; address: string; }[]; }>",
67
67
  "parameters": [],
68
- "returns": "Promise<{ name: string; address: string; }[]>",
68
+ "returns": "Promise<{ printers: { name: string; address: string; }[]; }>",
69
69
  "tags": [],
70
70
  "docs": "Get list of connected USB printers",
71
71
  "complexTypes": [],
@@ -13,16 +13,20 @@ export interface ThermalPrinterPlugin {
13
13
  * Get list of paired Bluetooth printers
14
14
  */
15
15
  listBluetoothPrinters(): Promise<{
16
- name: string;
17
- address: string;
18
- }[]>;
16
+ printers: {
17
+ name: string;
18
+ address: string;
19
+ }[];
20
+ }>;
19
21
  /**
20
22
  * Get list of connected USB printers
21
23
  */
22
24
  listUsbPrinters(): Promise<{
23
- name: string;
24
- address: string;
25
- }[]>;
25
+ printers: {
26
+ name: string;
27
+ address: string;
28
+ }[];
29
+ }>;
26
30
  }
27
31
  export interface PrintObject {
28
32
  /**
@@ -1 +1 @@
1
- {"version":3,"file":"definitions.js","sourceRoot":"","sources":["../../src/definitions.ts"],"names":[],"mappings":"","sourcesContent":["export interface ThermalPrinterPlugin {\n /**\n * Print text using USB connection\n * @param printObject Object containing text to print\n */\n printByUsb(printObject: PrintObject): Promise<void>;\n\n /**\n * Print text using Bluetooth connection\n * @param printObject Object containing text to print\n */\n printByBluetooth(printObject: PrintObject): Promise<void>;\n\n /**\n * Get list of paired Bluetooth printers\n */\n listBluetoothPrinters(): Promise<{ name: string; address: string }[]>;\n\n /**\n * Get list of connected USB printers\n */\n listUsbPrinters(): Promise<{ name: string; address: string }[]>;\n}\n\nexport interface PrintObject {\n /**\n * Text to print. Supports ESC/POS formatting commands.\n * Example: \"[C]<b>Hello World</b>\\n[C]This is a test\"\n */\n textToPrint: string;\n\n /**\n * Optional Bluetooth MAC address of the printer to use.\n * Only applicable for printByBluetooth.\n */\n address?: string;\n\n /**\n * Optional USB device name of the printer to use.\n * Only applicable for printByUsb.\n */\n name?: string;\n}\n"]}
1
+ {"version":3,"file":"definitions.js","sourceRoot":"","sources":["../../src/definitions.ts"],"names":[],"mappings":"","sourcesContent":["export interface ThermalPrinterPlugin {\n /**\n * Print text using USB connection\n * @param printObject Object containing text to print\n */\n printByUsb(printObject: PrintObject): Promise<void>;\n\n /**\n * Print text using Bluetooth connection\n * @param printObject Object containing text to print\n */\n printByBluetooth(printObject: PrintObject): Promise<void>;\n\n /**\n * Get list of paired Bluetooth printers\n */\n listBluetoothPrinters(): Promise<{ printers: { name: string; address: string }[] }>;\n\n /**\n * Get list of connected USB printers\n */\n listUsbPrinters(): Promise<{ printers: { name: string; address: string }[] }>;\n}\n\nexport interface PrintObject {\n /**\n * Text to print. Supports ESC/POS formatting commands.\n * Example: \"[C]<b>Hello World</b>\\n[C]This is a test\"\n */\n textToPrint: string;\n\n /**\n * Optional Bluetooth MAC address of the printer to use.\n * Only applicable for printByBluetooth.\n */\n address?: string;\n\n /**\n * Optional USB device name of the printer to use.\n * Only applicable for printByUsb.\n */\n name?: string;\n}\n"]}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@ruhiverse/thermal-printer-plugin",
3
- "version": "1.0.11",
3
+ "version": "1.0.15",
4
4
  "description": "Capacitor plugin for thermal printing via USB and Bluetooth",
5
5
  "main": "dist/plugin.cjs.js",
6
6
  "module": "dist/esm/index.js",