@m430/capacitor-label-printer 0.1.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.
Files changed (150) hide show
  1. package/API.md +218 -0
  2. package/LICENSE +21 -0
  3. package/M430CapacitorLabelPrinter.podspec +21 -0
  4. package/README.md +190 -0
  5. package/android/build.gradle +46 -0
  6. package/android/libs/.gitkeep +1 -0
  7. package/android/libs/fat-generic-tspl-bluetooth-classic-0.1.16-GA.jar +0 -0
  8. package/android/src/main/AndroidManifest.xml +12 -0
  9. package/android/src/main/java/com/m430/capacitor/labelprinter/.gitkeep +1 -0
  10. package/android/src/main/java/com/m430/capacitor/labelprinter/AndroidPrinterManager.java +132 -0
  11. package/android/src/main/java/com/m430/capacitor/labelprinter/AndroidStatusMapper.java +54 -0
  12. package/android/src/main/java/com/m430/capacitor/labelprinter/LabelPrinterPlugin.java +273 -0
  13. package/android/src/main/java/com/m430/capacitor/labelprinter/VendorAndroidDeviceCatalog.java +81 -0
  14. package/android/src/main/java/com/m430/capacitor/labelprinter/VendorAndroidPrinterSession.java +189 -0
  15. package/capacitor-label-printer.podspec +21 -0
  16. package/dist/docs.json +443 -0
  17. package/dist/esm/cpcl/builder.d.ts +10 -0
  18. package/dist/esm/cpcl/builder.js +35 -0
  19. package/dist/esm/definitions.d.ts +107 -0
  20. package/dist/esm/definitions.js +1 -0
  21. package/dist/esm/errors.d.ts +1 -0
  22. package/dist/esm/errors.js +1 -0
  23. package/dist/esm/index.d.ts +9 -0
  24. package/dist/esm/index.js +11 -0
  25. package/dist/esm/tspl/builder.d.ts +13 -0
  26. package/dist/esm/tspl/builder.js +45 -0
  27. package/dist/esm/tspl/helpers.d.ts +2 -0
  28. package/dist/esm/tspl/helpers.js +6 -0
  29. package/dist/esm/types.d.ts +12 -0
  30. package/dist/esm/types.js +1 -0
  31. package/dist/esm/web.d.ts +21 -0
  32. package/dist/esm/web.js +34 -0
  33. package/dist/plugin.cjs.js +143 -0
  34. package/dist/plugin.cjs.js.map +1 -0
  35. package/dist/plugin.js +136 -0
  36. package/dist/plugin.js.map +1 -0
  37. package/ios/Plugin/.gitkeep +1 -0
  38. package/ios/Plugin/IOSPrinterManager.swift +230 -0
  39. package/ios/Plugin/IOSStatusMapper.swift +57 -0
  40. package/ios/Plugin/LabelPrinterPlugin.swift +141 -0
  41. package/ios/VendorFrameworks/.gitkeep +1 -0
  42. package/ios/VendorFrameworks/adapter.framework/Headers/BasedOtherConnectedDevice.h +17 -0
  43. package/ios/VendorFrameworks/adapter.framework/Headers/ConnectedDevice.h +213 -0
  44. package/ios/VendorFrameworks/adapter.framework/Headers/IPRTBlueToothBaseDef.h +22 -0
  45. package/ios/VendorFrameworks/adapter.framework/Headers/KeepStateConnectedDevice.h +18 -0
  46. package/ios/VendorFrameworks/adapter.framework/Headers/QueueConfig.h +18 -0
  47. package/ios/VendorFrameworks/adapter.framework/Headers/ReadOptions.h +22 -0
  48. package/ios/VendorFrameworks/adapter.framework/Headers/WroteReporter.h +23 -0
  49. package/ios/VendorFrameworks/adapter.framework/Headers/adapter.h +18 -0
  50. package/ios/VendorFrameworks/adapter.framework/Info.plist +0 -0
  51. package/ios/VendorFrameworks/adapter.framework/Modules/module.modulemap +6 -0
  52. package/ios/VendorFrameworks/adapter.framework/adapter +0 -0
  53. package/ios/VendorFrameworks/appleble.framework/Frameworks/adapter.framework/Info.plist +0 -0
  54. package/ios/VendorFrameworks/appleble.framework/Frameworks/adapter.framework/_CodeSignature/CodeResources +101 -0
  55. package/ios/VendorFrameworks/appleble.framework/Frameworks/adapter.framework/adapter +0 -0
  56. package/ios/VendorFrameworks/appleble.framework/Frameworks/ibridge.framework/Frameworks/adapter.framework/Info.plist +0 -0
  57. package/ios/VendorFrameworks/appleble.framework/Frameworks/ibridge.framework/Frameworks/adapter.framework/adapter +0 -0
  58. package/ios/VendorFrameworks/appleble.framework/Frameworks/ibridge.framework/Info.plist +0 -0
  59. package/ios/VendorFrameworks/appleble.framework/Frameworks/ibridge.framework/_CodeSignature/CodeResources +132 -0
  60. package/ios/VendorFrameworks/appleble.framework/Frameworks/ibridge.framework/ibridge +0 -0
  61. package/ios/VendorFrameworks/appleble.framework/Headers/AppleBle.h +25 -0
  62. package/ios/VendorFrameworks/appleble.framework/Info.plist +0 -0
  63. package/ios/VendorFrameworks/appleble.framework/Modules/module.modulemap +6 -0
  64. package/ios/VendorFrameworks/appleble.framework/_CodeSignature/CodeResources +252 -0
  65. package/ios/VendorFrameworks/appleble.framework/appleble +0 -0
  66. package/ios/VendorFrameworks/father.framework/Frameworks/adapter.framework/Info.plist +0 -0
  67. package/ios/VendorFrameworks/father.framework/Frameworks/adapter.framework/adapter +0 -0
  68. package/ios/VendorFrameworks/father.framework/Headers/Appendat.h +28 -0
  69. package/ios/VendorFrameworks/father.framework/Headers/Arg.h +22 -0
  70. package/ios/VendorFrameworks/father.framework/Headers/BasicBatteryVolumeArg.h +16 -0
  71. package/ios/VendorFrameworks/father.framework/Headers/BinaryCommand.h +17 -0
  72. package/ios/VendorFrameworks/father.framework/Headers/CPCLCommand.h +10 -0
  73. package/ios/VendorFrameworks/father.framework/Headers/CallbackData.h +26 -0
  74. package/ios/VendorFrameworks/father.framework/Headers/Checker.h +16 -0
  75. package/ios/VendorFrameworks/father.framework/Headers/Command.h +25 -0
  76. package/ios/VendorFrameworks/father.framework/Headers/CommandClause.h +33 -0
  77. package/ios/VendorFrameworks/father.framework/Headers/Commander.h +31 -0
  78. package/ios/VendorFrameworks/father.framework/Headers/DataWriteOperation.h +42 -0
  79. package/ios/VendorFrameworks/father.framework/Headers/DefaultCommand.h +16 -0
  80. package/ios/VendorFrameworks/father.framework/Headers/EasyArg.h +16 -0
  81. package/ios/VendorFrameworks/father.framework/Headers/FastBinary.h +20 -0
  82. package/ios/VendorFrameworks/father.framework/Headers/HexOutput.h +19 -0
  83. package/ios/VendorFrameworks/father.framework/Headers/IDataWriteCallback.h +25 -0
  84. package/ios/VendorFrameworks/father.framework/Headers/Lifecycle.h +21 -0
  85. package/ios/VendorFrameworks/father.framework/Headers/NewLineArg.h +15 -0
  86. package/ios/VendorFrameworks/father.framework/Headers/OnlyBinaryHeaderArg.h +15 -0
  87. package/ios/VendorFrameworks/father.framework/Headers/OnlyTextHeaderArg.h +16 -0
  88. package/ios/VendorFrameworks/father.framework/Headers/PImageTool.h +22 -0
  89. package/ios/VendorFrameworks/father.framework/Headers/PReplaceKit.h +16 -0
  90. package/ios/VendorFrameworks/father.framework/Headers/PSDK.h +60 -0
  91. package/ios/VendorFrameworks/father.framework/Headers/PVariableKit.h +18 -0
  92. package/ios/VendorFrameworks/father.framework/Headers/PsdkConst.h +33 -0
  93. package/ios/VendorFrameworks/father.framework/Headers/Raw.h +22 -0
  94. package/ios/VendorFrameworks/father.framework/Headers/SimpleCheck.h +16 -0
  95. package/ios/VendorFrameworks/father.framework/Headers/SingleCommand.h +32 -0
  96. package/ios/VendorFrameworks/father.framework/Headers/TSPLCommand.h +10 -0
  97. package/ios/VendorFrameworks/father.framework/Headers/WriteControl.h +12 -0
  98. package/ios/VendorFrameworks/father.framework/Headers/WriteOptions.h +28 -0
  99. package/ios/VendorFrameworks/father.framework/Headers/father.h +21 -0
  100. package/ios/VendorFrameworks/father.framework/Info.plist +0 -0
  101. package/ios/VendorFrameworks/father.framework/Modules/module.modulemap +6 -0
  102. package/ios/VendorFrameworks/father.framework/father +0 -0
  103. package/ios/VendorFrameworks/tspl.framework/Frameworks/father.framework/Frameworks/adapter.framework/Info.plist +0 -0
  104. package/ios/VendorFrameworks/tspl.framework/Frameworks/father.framework/Frameworks/adapter.framework/adapter +0 -0
  105. package/ios/VendorFrameworks/tspl.framework/Frameworks/father.framework/Info.plist +0 -0
  106. package/ios/VendorFrameworks/tspl.framework/Frameworks/father.framework/father +0 -0
  107. package/ios/VendorFrameworks/tspl.framework/Headers/BasicTSPL.h +146 -0
  108. package/ios/VendorFrameworks/tspl.framework/Headers/BasicTSPLArg.h +17 -0
  109. package/ios/VendorFrameworks/tspl.framework/Headers/GenericTSPL.h +16 -0
  110. package/ios/VendorFrameworks/tspl.framework/Headers/TBar.h +30 -0
  111. package/ios/VendorFrameworks/tspl.framework/Headers/TBarCode.h +54 -0
  112. package/ios/VendorFrameworks/tspl.framework/Headers/TBatteryVolume.h +19 -0
  113. package/ios/VendorFrameworks/tspl.framework/Headers/TBox.h +32 -0
  114. package/ios/VendorFrameworks/tspl.framework/Headers/TCircle.h +26 -0
  115. package/ios/VendorFrameworks/tspl.framework/Headers/TCleanBmpFlash.h +20 -0
  116. package/ios/VendorFrameworks/tspl.framework/Headers/TClear.h +20 -0
  117. package/ios/VendorFrameworks/tspl.framework/Headers/TCut.h +21 -0
  118. package/ios/VendorFrameworks/tspl.framework/Headers/TDensity.h +21 -0
  119. package/ios/VendorFrameworks/tspl.framework/Headers/TDirection.h +51 -0
  120. package/ios/VendorFrameworks/tspl.framework/Headers/TDmatrix.h +29 -0
  121. package/ios/VendorFrameworks/tspl.framework/Headers/TDownloadBmpFlash.h +16 -0
  122. package/ios/VendorFrameworks/tspl.framework/Headers/TGap.h +21 -0
  123. package/ios/VendorFrameworks/tspl.framework/Headers/TImage.h +36 -0
  124. package/ios/VendorFrameworks/tspl.framework/Headers/TLine.h +34 -0
  125. package/ios/VendorFrameworks/tspl.framework/Headers/TMddle.h +16 -0
  126. package/ios/VendorFrameworks/tspl.framework/Headers/TPage.h +22 -0
  127. package/ios/VendorFrameworks/tspl.framework/Headers/TPrint.h +21 -0
  128. package/ios/VendorFrameworks/tspl.framework/Headers/TQRCode.h +35 -0
  129. package/ios/VendorFrameworks/tspl.framework/Headers/TReadState.h +16 -0
  130. package/ios/VendorFrameworks/tspl.framework/Headers/TReverse.h +27 -0
  131. package/ios/VendorFrameworks/tspl.framework/Headers/TSN.h +19 -0
  132. package/ios/VendorFrameworks/tspl.framework/Headers/TSPLCodeType.h +53 -0
  133. package/ios/VendorFrameworks/tspl.framework/Headers/TSPLCorrectLevel.h +21 -0
  134. package/ios/VendorFrameworks/tspl.framework/Headers/TSPLFont.h +83 -0
  135. package/ios/VendorFrameworks/tspl.framework/Headers/TSPLImageMode.h +30 -0
  136. package/ios/VendorFrameworks/tspl.framework/Headers/TSPLLineMode.h +37 -0
  137. package/ios/VendorFrameworks/tspl.framework/Headers/TSPLLineType.h +21 -0
  138. package/ios/VendorFrameworks/tspl.framework/Headers/TSPLOutDirection.h +27 -0
  139. package/ios/VendorFrameworks/tspl.framework/Headers/TSPLRotation.h +36 -0
  140. package/ios/VendorFrameworks/tspl.framework/Headers/TSPLShowType.h +36 -0
  141. package/ios/VendorFrameworks/tspl.framework/Headers/TSPL_.h +18 -0
  142. package/ios/VendorFrameworks/tspl.framework/Headers/TSpeed.h +20 -0
  143. package/ios/VendorFrameworks/tspl.framework/Headers/TText.h +38 -0
  144. package/ios/VendorFrameworks/tspl.framework/Headers/TTextBox.h +44 -0
  145. package/ios/VendorFrameworks/tspl.framework/Headers/TVersion.h +19 -0
  146. package/ios/VendorFrameworks/tspl.framework/Headers/tspl.h +45 -0
  147. package/ios/VendorFrameworks/tspl.framework/Info.plist +0 -0
  148. package/ios/VendorFrameworks/tspl.framework/Modules/module.modulemap +6 -0
  149. package/ios/VendorFrameworks/tspl.framework/tspl +0 -0
  150. package/package.json +95 -0
@@ -0,0 +1,273 @@
1
+ package com.m430.capacitor.labelprinter;
2
+
3
+ import android.Manifest;
4
+ import android.content.Intent;
5
+ import android.net.Uri;
6
+ import android.os.Build;
7
+ import android.provider.Settings;
8
+ import com.getcapacitor.JSArray;
9
+ import com.getcapacitor.JSObject;
10
+ import com.getcapacitor.PermissionState;
11
+ import com.getcapacitor.Plugin;
12
+ import com.getcapacitor.PluginCall;
13
+ import com.getcapacitor.PluginMethod;
14
+ import com.getcapacitor.annotation.CapacitorPlugin;
15
+ import com.getcapacitor.annotation.Permission;
16
+ import com.getcapacitor.annotation.PermissionCallback;
17
+ import java.util.ArrayList;
18
+ import java.util.List;
19
+
20
+ @CapacitorPlugin(
21
+ name = "LabelPrinter",
22
+ permissions = {
23
+ @Permission(alias = "bluetoothConnect", strings = { Manifest.permission.BLUETOOTH_CONNECT }),
24
+ @Permission(alias = "bluetoothScan", strings = { Manifest.permission.BLUETOOTH_SCAN })
25
+ }
26
+ )
27
+ public class LabelPrinterPlugin extends Plugin {
28
+ private static final String BLUETOOTH_CONNECT_ALIAS = "bluetoothConnect";
29
+ private static final String BLUETOOTH_SCAN_ALIAS = "bluetoothScan";
30
+ private static final String[] DISCOVERY_PERMISSION_ALIASES = new String[] {
31
+ BLUETOOTH_CONNECT_ALIAS,
32
+ BLUETOOTH_SCAN_ALIAS
33
+ };
34
+ private static final String[] CONNECTION_PERMISSION_ALIASES = new String[] { BLUETOOTH_CONNECT_ALIAS };
35
+ private static final String PERMISSION_DENIED_CODE = "PERMISSION_DENIED";
36
+ private AndroidPrinterManager manager;
37
+
38
+ @Override
39
+ public void load() {
40
+ manager = new AndroidPrinterManager(new VendorAndroidDeviceCatalog(getContext()), new AndroidStatusMapper());
41
+ }
42
+
43
+ @PluginMethod
44
+ public void isSupported(PluginCall call) {
45
+ JSObject result = new JSObject();
46
+ result.put("supported", true);
47
+ call.resolve(result);
48
+ }
49
+
50
+ @PluginMethod
51
+ @Override
52
+ public void checkPermissions(PluginCall call) {
53
+ call.resolve(buildPermissionResult(currentBluetoothConnectState(), currentBluetoothScanState()));
54
+ }
55
+
56
+ @PluginMethod
57
+ public void ensurePermissions(PluginCall call) {
58
+ if (hasPermissionAliases(DISCOVERY_PERMISSION_ALIASES)) {
59
+ call.resolve(buildPermissionResult(currentBluetoothConnectState(), currentBluetoothScanState()));
60
+ return;
61
+ }
62
+
63
+ if (!requiresNearbyDevicesPermission()) {
64
+ call.resolve(buildPermissionResult(PermissionState.GRANTED, PermissionState.GRANTED));
65
+ return;
66
+ }
67
+
68
+ requestPermissionForAliases(DISCOVERY_PERMISSION_ALIASES, call, "ensurePermissionsCallback");
69
+ }
70
+
71
+ @PluginMethod
72
+ public void discoverDevices(PluginCall call) {
73
+ if (!hasPermissionAliases(DISCOVERY_PERMISSION_ALIASES)) {
74
+ if (!requiresNearbyDevicesPermission()) {
75
+ performDiscoverDevices(call);
76
+ return;
77
+ }
78
+
79
+ requestPermissionForAliases(DISCOVERY_PERMISSION_ALIASES, call, "discoverDevicesPermissionCallback");
80
+ return;
81
+ }
82
+
83
+ performDiscoverDevices(call);
84
+ }
85
+
86
+ @PluginMethod
87
+ public void connect(PluginCall call) {
88
+ if (!hasPermissionAliases(CONNECTION_PERMISSION_ALIASES)) {
89
+ if (!requiresNearbyDevicesPermission()) {
90
+ performConnect(call);
91
+ return;
92
+ }
93
+
94
+ requestPermissionForAliases(CONNECTION_PERMISSION_ALIASES, call, "connectPermissionCallback");
95
+ return;
96
+ }
97
+
98
+ performConnect(call);
99
+ }
100
+
101
+ @PluginMethod
102
+ public void disconnect(PluginCall call) {
103
+ manager.disconnect();
104
+ call.resolve();
105
+ }
106
+
107
+ @PluginMethod
108
+ public void getConnectionState(PluginCall call) {
109
+ call.resolve(manager.getConnectionState());
110
+ }
111
+
112
+ @PluginMethod
113
+ public void print(PluginCall call) {
114
+ if (!hasPermissionAliases(CONNECTION_PERMISSION_ALIASES)) {
115
+ rejectPermissionCall(call);
116
+ return;
117
+ }
118
+
119
+ String payload = call.getString("payload", "");
120
+ String language = call.getString("language", "tspl");
121
+ Integer copiesValue = call.getInt("copies", 1);
122
+ int copies = copiesValue != null ? copiesValue : 1;
123
+ try {
124
+ manager.print(payload, language, copies);
125
+ call.resolve();
126
+ } catch (Exception exception) {
127
+ call.reject(exception.getMessage(), exception);
128
+ }
129
+ }
130
+
131
+ @PluginMethod
132
+ public void getStatus(PluginCall call) {
133
+ call.resolve(manager.getStatus());
134
+ }
135
+
136
+ @PluginMethod
137
+ public void openAppSettings(PluginCall call) {
138
+ Intent intent = new Intent(Settings.ACTION_APPLICATION_DETAILS_SETTINGS);
139
+ intent.setData(Uri.fromParts("package", getContext().getPackageName(), null));
140
+ intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
141
+ getContext().startActivity(intent);
142
+ call.resolve();
143
+ }
144
+
145
+ @PermissionCallback
146
+ private void ensurePermissionsCallback(PluginCall call) {
147
+ call.resolve(buildPermissionResult(currentBluetoothConnectState(), currentBluetoothScanState()));
148
+ }
149
+
150
+ @PermissionCallback
151
+ private void discoverDevicesPermissionCallback(PluginCall call) {
152
+ if (!hasPermissionAliases(DISCOVERY_PERMISSION_ALIASES)) {
153
+ rejectPermissionCall(call);
154
+ return;
155
+ }
156
+
157
+ performDiscoverDevices(call);
158
+ }
159
+
160
+ @PermissionCallback
161
+ private void connectPermissionCallback(PluginCall call) {
162
+ if (!hasPermissionAliases(CONNECTION_PERMISSION_ALIASES)) {
163
+ rejectPermissionCall(call);
164
+ return;
165
+ }
166
+
167
+ performConnect(call);
168
+ }
169
+
170
+ private void performDiscoverDevices(PluginCall call) {
171
+ JSArray prefixesArray = call.getArray("namePrefixes");
172
+ List<String> prefixes = new ArrayList<>();
173
+ if (prefixesArray != null) {
174
+ for (int index = 0; index < prefixesArray.length(); index++) {
175
+ String item = prefixesArray.optString(index, null);
176
+ if (item != null) {
177
+ prefixes.add(item);
178
+ }
179
+ }
180
+ }
181
+
182
+ try {
183
+ JSObject result = new JSObject();
184
+ result.put("devices", manager.getBondedDevices(prefixes));
185
+ call.resolve(result);
186
+ } catch (Exception exception) {
187
+ call.reject(exception.getMessage(), exception);
188
+ }
189
+ }
190
+
191
+ private void performConnect(PluginCall call) {
192
+ try {
193
+ manager.connect(call.getString("deviceId"));
194
+ call.resolve();
195
+ } catch (Exception exception) {
196
+ call.reject(exception.getMessage(), exception);
197
+ }
198
+ }
199
+
200
+ private void rejectPermissionCall(PluginCall call) {
201
+ call.reject(
202
+ "需要附近设备权限才能扫描、连接和打印蓝牙标签机",
203
+ PERMISSION_DENIED_CODE,
204
+ buildPermissionResult(currentBluetoothConnectState(), currentBluetoothScanState())
205
+ );
206
+ }
207
+
208
+ private boolean requiresNearbyDevicesPermission() {
209
+ return Build.VERSION.SDK_INT >= Build.VERSION_CODES.S;
210
+ }
211
+
212
+ private PermissionState currentBluetoothConnectState() {
213
+ if (!requiresNearbyDevicesPermission()) {
214
+ return PermissionState.GRANTED;
215
+ }
216
+ return getPermissionState(BLUETOOTH_CONNECT_ALIAS);
217
+ }
218
+
219
+ private PermissionState currentBluetoothScanState() {
220
+ if (!requiresNearbyDevicesPermission()) {
221
+ return PermissionState.GRANTED;
222
+ }
223
+ return getPermissionState(BLUETOOTH_SCAN_ALIAS);
224
+ }
225
+
226
+ private boolean hasPermissionAliases(String[] aliases) {
227
+ if (!requiresNearbyDevicesPermission()) {
228
+ return true;
229
+ }
230
+ for (String alias : aliases) {
231
+ if (getPermissionState(alias) != PermissionState.GRANTED) {
232
+ return false;
233
+ }
234
+ }
235
+ return true;
236
+ }
237
+
238
+ private static PermissionState aggregateBluetoothState(PermissionState bluetoothConnect, PermissionState bluetoothScan) {
239
+ if (bluetoothConnect == PermissionState.DENIED || bluetoothScan == PermissionState.DENIED) {
240
+ return PermissionState.DENIED;
241
+ }
242
+ if (
243
+ bluetoothConnect == PermissionState.PROMPT_WITH_RATIONALE ||
244
+ bluetoothScan == PermissionState.PROMPT_WITH_RATIONALE
245
+ ) {
246
+ return PermissionState.PROMPT_WITH_RATIONALE;
247
+ }
248
+ if (bluetoothConnect == PermissionState.PROMPT || bluetoothScan == PermissionState.PROMPT) {
249
+ return PermissionState.PROMPT;
250
+ }
251
+ return PermissionState.GRANTED;
252
+ }
253
+
254
+ private static boolean canPrompt(PermissionState state) {
255
+ return state == PermissionState.PROMPT || state == PermissionState.PROMPT_WITH_RATIONALE;
256
+ }
257
+
258
+ private static JSObject buildPermissionResult(PermissionState bluetoothConnect, PermissionState bluetoothScan) {
259
+ PermissionState bluetooth = aggregateBluetoothState(bluetoothConnect, bluetoothScan);
260
+
261
+ JSObject permissions = new JSObject();
262
+ permissions.put("bluetoothConnect", bluetoothConnect.toString());
263
+ permissions.put("bluetoothScan", bluetoothScan.toString());
264
+ permissions.put("bluetooth", bluetooth.toString());
265
+
266
+ JSObject result = new JSObject();
267
+ result.put("granted", bluetooth == PermissionState.GRANTED);
268
+ result.put("canPrompt", canPrompt(bluetooth));
269
+ result.put("shouldOpenSettings", bluetooth != PermissionState.GRANTED && !canPrompt(bluetooth));
270
+ result.put("permissions", permissions);
271
+ return result;
272
+ }
273
+ }
@@ -0,0 +1,81 @@
1
+ package com.m430.capacitor.labelprinter;
2
+
3
+ import android.annotation.SuppressLint;
4
+ import android.bluetooth.BluetoothAdapter;
5
+ import android.bluetooth.BluetoothDevice;
6
+ import android.content.Context;
7
+ import com.getcapacitor.JSArray;
8
+ import com.getcapacitor.JSObject;
9
+ import com.printer.psdk.device.bluetooth.Bluetooth;
10
+ import java.util.List;
11
+ import java.util.Set;
12
+
13
+ final class VendorAndroidDeviceCatalog implements AndroidPrinterManager.DeviceCatalog {
14
+ private final Context appContext;
15
+ private final Bluetooth bluetooth;
16
+ private final BluetoothAdapter adapter;
17
+
18
+ VendorAndroidDeviceCatalog(Context context) {
19
+ appContext = context.getApplicationContext();
20
+ bluetooth = Bluetooth.getInstance();
21
+ bluetooth.initialize(appContext);
22
+ adapter = BluetoothAdapter.getDefaultAdapter();
23
+ }
24
+
25
+ @Override
26
+ @SuppressLint("MissingPermission")
27
+ public JSArray discover(List<String> prefixes) {
28
+ JSArray devices = new JSArray();
29
+ if (adapter == null || !bluetooth.hasConnectPermission(appContext)) {
30
+ return devices;
31
+ }
32
+
33
+ Set<BluetoothDevice> bonded = adapter.getBondedDevices();
34
+ for (BluetoothDevice device : bonded) {
35
+ if (!matchesPrefix(device.getName(), prefixes)) {
36
+ continue;
37
+ }
38
+
39
+ JSObject item = new JSObject();
40
+ item.put("id", device.getAddress());
41
+ item.put("name", device.getName());
42
+ item.put("address", device.getAddress());
43
+ item.put("transport", "classic");
44
+ item.put("bonded", true);
45
+ devices.put(item);
46
+ }
47
+
48
+ return devices;
49
+ }
50
+
51
+ @Override
52
+ @SuppressLint("MissingPermission")
53
+ public AndroidPrinterManager.PrinterSession openSession(String deviceId) {
54
+ if (adapter == null || deviceId == null || !bluetooth.hasConnectPermission(appContext)) {
55
+ return null;
56
+ }
57
+
58
+ for (BluetoothDevice device : adapter.getBondedDevices()) {
59
+ if (deviceId.equalsIgnoreCase(device.getAddress())) {
60
+ return new VendorAndroidPrinterSession(bluetooth, device);
61
+ }
62
+ }
63
+
64
+ return null;
65
+ }
66
+
67
+ private boolean matchesPrefix(String value, List<String> prefixes) {
68
+ if (value == null) {
69
+ return false;
70
+ }
71
+ if (prefixes == null || prefixes.isEmpty()) {
72
+ return true;
73
+ }
74
+ for (String prefix : prefixes) {
75
+ if (value.startsWith(prefix)) {
76
+ return true;
77
+ }
78
+ }
79
+ return false;
80
+ }
81
+ }
@@ -0,0 +1,189 @@
1
+ package com.m430.capacitor.labelprinter;
2
+
3
+ import android.annotation.SuppressLint;
4
+ import android.bluetooth.BluetoothDevice;
5
+ import com.printer.psdk.device.adapter.ConnectedDevice;
6
+ import com.printer.psdk.device.adapter.ReadOptions;
7
+ import com.printer.psdk.device.adapter.types.WroteReporter;
8
+ import com.printer.psdk.frame.father.args.common.Raw;
9
+ import com.printer.psdk.device.bluetooth.Bluetooth;
10
+ import com.printer.psdk.device.bluetooth.ConnectListener;
11
+ import com.printer.psdk.device.bluetooth.Connection;
12
+ import com.printer.psdk.tspl.GenericTSPL;
13
+ import com.printer.psdk.tspl.TSPL;
14
+ import java.io.IOException;
15
+ import java.nio.charset.StandardCharsets;
16
+
17
+ final class VendorAndroidPrinterSession implements AndroidPrinterManager.PrinterSession {
18
+ private final Connection connection;
19
+ private final TsplTransport tsplTransport;
20
+ private final VendorConnectListener listener = new VendorConnectListener();
21
+
22
+ VendorAndroidPrinterSession(Bluetooth bluetooth, BluetoothDevice device) {
23
+ connection = bluetooth.createConnectionClassic(device, listener);
24
+ tsplTransport = new SdkTsplTransport(connection);
25
+ }
26
+
27
+ VendorAndroidPrinterSession(Connection connection, TsplTransport tsplTransport) {
28
+ this.connection = connection;
29
+ this.tsplTransport = tsplTransport;
30
+ }
31
+
32
+ @Override
33
+ public void connect() throws IOException {
34
+ if (connection == null) {
35
+ throw new IOException("unable to create classic bluetooth connection");
36
+ }
37
+
38
+ boolean success = connection.connect(null);
39
+ if (!success || !connection.isConnected()) {
40
+ throw new IOException(listener.lastErrorMessage != null ? listener.lastErrorMessage : "connect failed");
41
+ }
42
+ }
43
+
44
+ @Override
45
+ public void disconnect() {
46
+ if (connection != null) {
47
+ connection.disconnect();
48
+ }
49
+ }
50
+
51
+ @Override
52
+ public boolean isConnected() {
53
+ return connection != null && connection.isConnected();
54
+ }
55
+
56
+ @Override
57
+ public String getConnectionState() {
58
+ if (connection == null) {
59
+ return "disconnected";
60
+ }
61
+
62
+ switch (connection.getState()) {
63
+ case Connection.STATE_CONNECTING:
64
+ case Connection.STATE_PAIRING:
65
+ case Connection.STATE_PAIRED:
66
+ return "connecting";
67
+ case Connection.STATE_CONNECTED:
68
+ return "connected";
69
+ default:
70
+ return "disconnected";
71
+ }
72
+ }
73
+
74
+ @Override
75
+ @SuppressLint("MissingPermission")
76
+ public String getDeviceName() {
77
+ if (connection == null || connection.getDevice() == null) {
78
+ return null;
79
+ }
80
+ return connection.getDevice().getName();
81
+ }
82
+
83
+ public void print(byte[] payload) throws IOException {
84
+ print("tspl", payload);
85
+ }
86
+
87
+ @Override
88
+ public void print(String language, byte[] payload) throws IOException {
89
+ if (connection == null) {
90
+ throw new IOException("printer connection is unavailable");
91
+ }
92
+ if (isTsplLanguage(language)) {
93
+ tsplTransport.send(payload);
94
+ return;
95
+ }
96
+ connection.write(payload);
97
+ }
98
+
99
+ @Override
100
+ public byte[] queryStatus() throws IOException {
101
+ if (connection == null) {
102
+ return null;
103
+ }
104
+ return tsplTransport.queryStatus();
105
+ }
106
+
107
+ interface TsplTransport {
108
+ void send(byte[] payload) throws IOException;
109
+
110
+ byte[] queryStatus() throws IOException;
111
+ }
112
+
113
+ static final class SdkTsplTransport implements TsplTransport {
114
+ private final Connection connection;
115
+
116
+ SdkTsplTransport(Connection connection) {
117
+ this.connection = connection;
118
+ }
119
+
120
+ @Override
121
+ public void send(byte[] payload) throws IOException {
122
+ String[] commands = splitCommands(payload);
123
+ if (commands.length == 0) {
124
+ throw new IOException("tspl payload does not contain any printable commands");
125
+ }
126
+
127
+ GenericTSPL tspl = TSPL.generic(connection);
128
+ for (String command : commands) {
129
+ tspl.raw(Raw.builder().command(command, StandardCharsets.UTF_8).build());
130
+ }
131
+ requireReporterOk(tspl.write(), "failed to write tspl payload");
132
+ }
133
+
134
+ @Override
135
+ public byte[] queryStatus() throws IOException {
136
+ GenericTSPL tspl = TSPL.generic(connection).state();
137
+ requireReporterOk(tspl.write(), "failed to query printer status");
138
+ return tspl.read(ReadOptions.builder().timeout(1500).build());
139
+ }
140
+
141
+ static String[] splitCommands(byte[] payload) {
142
+ return new String(payload, StandardCharsets.UTF_8)
143
+ .replace("\r\n", "\n")
144
+ .replace('\r', '\n')
145
+ .lines()
146
+ .map(String::trim)
147
+ .filter(command -> !command.isEmpty())
148
+ .toArray(String[]::new);
149
+ }
150
+
151
+ private static void requireReporterOk(WroteReporter reporter, String fallbackMessage) throws IOException {
152
+ if (reporter.isOk()) {
153
+ return;
154
+ }
155
+
156
+ throw new IOException(
157
+ reporter.getException() != null ? reporter.getException().getMessage() : fallbackMessage,
158
+ reporter.getException()
159
+ );
160
+ }
161
+ }
162
+
163
+ private static boolean isTsplLanguage(String language) {
164
+ return language == null || language.trim().isEmpty() || "tspl".equalsIgnoreCase(language);
165
+ }
166
+
167
+ private static final class VendorConnectListener implements ConnectListener {
168
+ private String lastErrorMessage;
169
+
170
+ @Override
171
+ public void onConnectSuccess(ConnectedDevice connectedDevice) {
172
+ lastErrorMessage = null;
173
+ }
174
+
175
+ @Override
176
+ public void onConnectFail(String errMsg, Throwable throwable) {
177
+ if (throwable != null && throwable.getMessage() != null) {
178
+ lastErrorMessage = errMsg + ": " + throwable.getMessage();
179
+ return;
180
+ }
181
+ lastErrorMessage = errMsg;
182
+ }
183
+
184
+ @Override
185
+ public void onConnectionStateChanged(BluetoothDevice device, int state) {
186
+ // 状态直接从 Connection.getState() 读取,这里无需额外处理。
187
+ }
188
+ }
189
+ }
@@ -0,0 +1,21 @@
1
+ require 'json'
2
+
3
+ package = JSON.parse(File.read(File.join(__dir__, 'package.json')))
4
+ repository_url = package.dig('repository', 'url').to_s.sub(/^git\+/, '')
5
+ homepage_url = repository_url.sub(/\.git$/, '')
6
+
7
+ Pod::Spec.new do |s|
8
+ s.name = 'M430CapacitorLabelPrinter'
9
+ s.version = package['version']
10
+ s.summary = package['description']
11
+ s.license = package['license']
12
+ s.homepage = homepage_url
13
+ s.author = package['author']
14
+ s.source = { git: repository_url, tag: s.version.to_s }
15
+ s.source_files = 'ios/Plugin/**/*.{swift,h,m,mm}'
16
+ s.vendored_frameworks = 'ios/VendorFrameworks/*.framework', 'ios/VendorFrameworks/*.xcframework'
17
+ s.preserve_paths = 'ios/VendorFrameworks/**/*'
18
+ s.ios.deployment_target = '13.0'
19
+ s.dependency 'Capacitor'
20
+ s.swift_version = '5.9'
21
+ end