Browse Source

打印机对接完成

周素华 10 months ago
parent
commit
c83f1e7ae7

+ 4 - 0
android/app/src/main/java/com/szls/lszlgl/MainActivity.java

@@ -10,6 +10,10 @@ import io.flutter.embedding.engine.plugins.util.GeneratedPluginRegister;
10 10
 import io.flutter.plugins.BluetoothPlugin;
11 11
 
12 12
 public class MainActivity extends FlutterActivity {
13
+
14
+    static {
15
+        System.loadLibrary("LabelPrinterSDK");
16
+    }
13 17
     @Override
14 18
     public void configureFlutterEngine(@NonNull FlutterEngine flutterEngine) {
15 19
         super.configureFlutterEngine(flutterEngine);

+ 29 - 6
android/app/src/main/java/io/flutter/plugins/BluetoothPlugin.java

@@ -27,6 +27,8 @@ import com.gengcon.www.jcprintersdk.callback.PrintCallback;
27 27
 import com.permissionx.guolindev.PermissionX;
28 28
 import com.szls.lszlgl.MainActivity;
29 29
 
30
+import java.io.ByteArrayOutputStream;
31
+import java.nio.ByteBuffer;
30 32
 import java.security.Permission;
31 33
 import java.util.ArrayList;
32 34
 import java.util.HashMap;
@@ -164,9 +166,13 @@ public class BluetoothPlugin implements FlutterPlugin, MethodChannel.MethodCallH
164 166
                 Log.d("ble", "hasBluetoothConnectDevice :" + methodCall.arguments);
165 167
                 hasBluetoothConnectDevice(methodCall, result);
166 168
                 break;
167
-            case "startBluetoothPrint":
169
+            case "startBluetoothPrintBitMap":
168 170
                 Log.d("ble", "startBluetoothPrint :" + methodCall.arguments);
169
-                startBluetoothPrint(methodCall, result);
171
+                startBluetoothPrintBitMap(methodCall, result);
172
+                break;
173
+            case "startBluetoothPrintBarCode":
174
+                Log.d("ble", "startBluetoothPrintBarCode :" + methodCall.arguments);
175
+                startBluetoothPrintBarCode(methodCall, result);
170 176
                 break;
171 177
 
172 178
 
@@ -284,8 +290,7 @@ public class BluetoothPlugin implements FlutterPlugin, MethodChannel.MethodCallH
284 290
             PrintUtil.setConnectedType(-1);
285 291
             int connectResult = 1;
286 292
             if (blueDeviceInfo.getDeviceName().contains("BTP")) {
287
-                BTPPrintUtil btpPrintUtil = new BTPPrintUtil();
288
-                connectResult = btpPrintUtil.connectBluetoothPrinter(blueDeviceInfo.getDeviceHardwareAddress());
293
+                connectResult = BTPPrintUtil.connectBluetoothPrinter(blueDeviceInfo.getDeviceHardwareAddress());
289 294
             } else {
290 295
                 connectResult = PrintUtil.connectBluetoothPrinter(blueDeviceInfo.getDeviceHardwareAddress());
291 296
             }
@@ -309,7 +314,7 @@ public class BluetoothPlugin implements FlutterPlugin, MethodChannel.MethodCallH
309 314
         }
310 315
     }
311 316
 
312
-    void startBluetoothPrint(@NonNull MethodCall methodCall, @NonNull MethodChannel.Result result) {
317
+    void startBluetoothPrintBitMap(@NonNull MethodCall methodCall, @NonNull MethodChannel.Result result) {
313 318
 
314 319
         byte[] imageByte = (byte[]) methodCall.arguments;
315 320
 
@@ -322,8 +327,26 @@ public class BluetoothPlugin implements FlutterPlugin, MethodChannel.MethodCallH
322 327
         }
323 328
         BlueDeviceInfo blueDeviceInfo = new BlueDeviceInfo(bluetoothDevice.getName(), bluetoothDevice.getAddress(), itemPosition.getConnectState());
324 329
         if(blueDeviceInfo.getDeviceName().contains("BTP")) {
330
+            BTPPrintUtil.printBitMap(bitmap, blueDeviceInfo.getDeviceName(), result);
331
+        } else {
332
+            PrintUtil.printBitMap(bitmap, result);
333
+        }
334
+    }
325 335
 
326
-            BTPPrintUtil.printBitMap(imageByte, bitmap.getWidth(), bitmap.getHeight(), result);
336
+    void startBluetoothPrintBarCode(@NonNull MethodCall methodCall, @NonNull MethodChannel.Result result) {
337
+
338
+        byte[] imageByte = (byte[]) methodCall.arguments;
339
+
340
+        Log.d("ble", "imageByte:" + imageByte);
341
+        Bitmap bitmap = Bytes2Bimap(imageByte);
342
+
343
+        BluetoothDevice bluetoothDevice = mBluetoothAdapter.getRemoteDevice(itemPosition.getDeviceHardwareAddress());
344
+        if (ActivityCompat.checkSelfPermission(_applicationContext, Manifest.permission.BLUETOOTH_CONNECT) != PackageManager.PERMISSION_GRANTED) {
345
+            return;
346
+        }
347
+        BlueDeviceInfo blueDeviceInfo = new BlueDeviceInfo(bluetoothDevice.getName(), bluetoothDevice.getAddress(), itemPosition.getConnectState());
348
+        if(blueDeviceInfo.getDeviceName().contains("BTP")) {
349
+            BTPPrintUtil.printBitMap(bitmap, blueDeviceInfo.getDeviceName(), result);
327 350
         } else {
328 351
             PrintUtil.printBitMap(bitmap, result);
329 352
         }

+ 32 - 9
android/app/src/main/java/io/flutter/plugins/utils/BTPPrintUtil.java

@@ -8,6 +8,9 @@ import androidx.annotation.NonNull;
8 8
 
9 9
 import com.snbc.sdk.LabelPrinter;
10 10
 
11
+import java.io.ByteArrayOutputStream;
12
+import java.nio.ByteBuffer;
13
+
11 14
 import io.flutter.plugin.common.MethodChannel;
12 15
 
13 16
 public class BTPPrintUtil {
@@ -25,7 +28,7 @@ public class BTPPrintUtil {
25 28
      *
26 29
      * @return LabelPrinter 实例
27 30
      */
28
-    public  LabelPrinter getInstance() {
31
+    public static LabelPrinter getInstance() {
29 32
         // 双重检查锁定以确保只初始化一次实例
30 33
         if (labelPrinter == null) {
31 34
             synchronized (BTPPrintUtil.class) {
@@ -44,19 +47,39 @@ public class BTPPrintUtil {
44 47
      * @param address 打印机地址
45 48
      * @return 成功与否
46 49
      */
47
-    public  int connectBluetoothPrinter(String address) {
48
-        LabelPrinter   labelPrinter = new LabelPrinter();
50
+    public static int connectBluetoothPrinter(String address) {
49 51
 //        return 1;
50 52
         // 获取单例实例以确保线程安全
51
-        return labelPrinter.ConnectPrinter(7, "04:7F:0E:AD:20:3A", 2);
53
+        return getInstance().ConnectPrinter(7, address, 4);
54
+    }
55
+
56
+    public static void printBitMap(Bitmap bitmap, String deviceName, @NonNull MethodChannel.Result result) {
57
+
58
+        int x = 0;
59
+        if(deviceName.contains("BTP-UP321")) {
60
+            x = 0;
61
+        } else if(deviceName.contains("BTP-P398PLUS")) {
62
+            x = 40;
63
+        }
64
+        int bytes = bitmap.getByteCount();
65
+        ByteBuffer buf = ByteBuffer.allocate(bytes);
66
+        bitmap.copyPixelsToBuffer(buf);
67
+        ByteArrayOutputStream LionData=new ByteArrayOutputStream();
68
+        bitmap.compress(Bitmap.CompressFormat.PNG, 100, LionData);
69
+
70
+        getInstance().SetLabelSize(560,640);
71
+        int code = getInstance().PrintImageData(x, 0, LionData.toByteArray());
72
+        getInstance().PrintLabel(1,1);
73
+        result.success(code == 0 ? true : false);
52 74
     }
53 75
 
54
-    public static void printBitMap(byte[] imageByte, int bitmapWidth, int bitmapHeight, @NonNull MethodChannel.Result result) {
76
+    public  static void printBarCodeWithText(String barCode, String text, @NonNull MethodChannel.Result result) {
55 77
 
56
-//        result.success(1);
57
-        Log.d("ble", "bitmapWidth:"+bitmapWidth+",bitmapHeight:"+bitmapHeight);
58
-//        int code = getInstance().PrintImageData(bitmapWidth, bitmapHeight, imageByte);
59
-//        result.success(code);
78
+        getInstance().SetLabelSize(560,640);
79
+        labelPrinter.PrintBarcodeQR(80, 20,  0, "SHXM2024007404", 'H', 18, 2);
80
+        labelPrinter.PrintText(100, 500, "8", "SHXM2024007404", 0, 7, 3, 0);
81
+        int code = getInstance().PrintLabel(1,1);
82
+        result.success(code == 0 ? true : false);
60 83
     }
61 84
 
62 85
 }

+ 13 - 15
android/app/src/main/java/io/flutter/plugins/utils/PrintUtil.java

@@ -218,20 +218,16 @@ public class PrintUtil {
218 218
     public static void printBitMap(Bitmap bitmap, @NonNull MethodChannel.Result result) {
219 219
         if (PrintUtil.isConnection() != 0) {
220 220
 //            handler.post(() -> Toast.makeText(MyApplication.getInstance(), "未连接打印机", Toast.LENGTH_SHORT).show());
221
-            result.success(1);
221
+            result.success(false);
222 222
             return;
223 223
         }
224 224
 
225
-//        fragment = new MyDialogLoadingFragment("打印中");
226
-//        fragment.show(getSupportFragmentManager(), "PRINT");
227
-
228
-
229 225
         //重置错误状态变量
230
-        boolean isError = false;
226
+        final boolean[] isError = {false};
231 227
         //重置取消打印状态变量
232
-        boolean isCancel = false;
228
+        final boolean[] isCancel = {false};
233 229
 
234
-        int orientation = 0;
230
+        final int[] orientation = {0};
235 231
 
236 232
         int pageCount = 1;
237 233
         int quantity = 1;
@@ -259,32 +255,34 @@ public class PrintUtil {
259 255
                     } else {
260 256
                         Log.d("ble", "结束打印失败");
261 257
                     }
262
-                    result.success(0);
258
+                    result.success(true);
263 259
                 }
264 260
             }
265 261
 
266 262
             @Override
267 263
             public void onError(int i) {
268
-                result.success(i == 0 ? 1 : i);
264
+
269 265
             }
270 266
 
271 267
 
272 268
             @Override
273 269
             public void onError(int errorCode, int printState) {
274 270
                 Log.d("ble", "测试:onError");
275
-                result.success(errorCode == 0 ? 1 : errorCode);
271
+                isError[0] = true;
272
+                result.success(false);
276 273
             }
277 274
 
278 275
             @Override
279 276
             public void onCancelJob(boolean isSuccess) {
280 277
                 //取消打印成功回调
281
-                result.success(1);
278
+                isCancel[0] = true;
282 279
             }
283 280
 
284 281
             @Override
285 282
             public void onBufferFree(int pageIndex, int bufferSize) {
286
-                if (isError || isCancel || pageIndex > pageCount) {
287
-                    result.success(1);
283
+                if (isError[0] || isCancel[0] || pageIndex > pageCount) {
284
+                    Log.d("ble", "测试:onBufferFree error");
285
+                    return;
288 286
                 }
289 287
 
290 288
                 if (generatedPrintDataPageCount[0] < pageCount) {
@@ -292,7 +290,7 @@ public class PrintUtil {
292 290
                     int bitmapWidth = bitmap.getWidth();
293 291
                     int bitmapHeight = bitmap.getHeight();
294 292
                     Log.d("ble", "bitmapWidth:"+bitmapWidth+",bitmapHeight:"+bitmapHeight);
295
-                    PrintUtil.getInstance().commitImageData(orientation, bitmap, (int) (bitmapWidth / printMultiple), (int) (bitmapHeight / printMultiple), 1, 0, 0, 0, 0, "");
293
+                    PrintUtil.getInstance().commitImageData(orientation[0], bitmap, (int) (bitmapWidth / printMultiple), (int) (bitmapHeight / printMultiple), 1, 0, 0, 0, 0, "");
296 294
                 }
297 295
             }
298 296
         });

BIN
assets/images/print_ble.png


BIN
assets/images/search_ble.png


+ 7 - 0
lib/config/pics.dart

@@ -33,3 +33,10 @@ const String imgUserCenterSetting = 'assets/images/user_center_setting.webp';
33 33
 const String imgItemArrowRight = 'assets/images/item_arrow_right.webp';
34 34
 // 列表项下箭头
35 35
 const String imgItemArrowDown = 'assets/images/item_arrow_down.webp';
36
+
37
+
38
+// 搜索图标
39
+const String imgBleSearch = 'assets/images/search_ble.png';
40
+// 打印图标
41
+const String imgBlePrint = 'assets/images/print_ble.png';
42
+

+ 1 - 1
lib/drfit/dao/device_info_table_dao.dart

@@ -9,7 +9,7 @@ class DeviceInfoTableDao extends DatabaseAccessor<MyDatabase> {
9 9
   DeviceInfoTableDao(MyDatabase db) : super(db);
10 10
 
11 11
   Future<int> addOneDeviceComp(DeviceInfoTableCompanion deviceInfoTableCompanion) async {
12
-    return into(db.deviceInfoTable).insert(deviceInfoTableCompanion);
12
+    return into(db.deviceInfoTable).insert(deviceInfoTableCompanion, mode: InsertMode.insertOrReplace);
13 13
   }
14 14
 
15 15
 

+ 1 - 7
lib/drfit/database.dart

@@ -24,16 +24,10 @@ class MyDatabase extends _$MyDatabase {
24 24
 
25 25
 LazyDatabase _openConnection() {
26 26
 
27
-  getApplicationDocumentsDirectory().then((value) {
28
-    logger.d('==============zhouzhou 111 ${value.path}');
29
-  });
30
-
31
-
32 27
   return LazyDatabase(() async {
33
-    logger.d('==============zhouzhou');
34 28
 
35 29
     final documentsDir = await getApplicationDocumentsDirectory();
36
-    final file = File(p.join(documentsDir.path, 'db.sqlite'));
30
+    final file = File(p.join(documentsDir.path, 'myDatabase.db'));
37 31
 
38 32
     return NativeDatabase.createInBackground(file);
39 33
   });

+ 2 - 1
lib/main.dart

@@ -20,7 +20,7 @@ late MyDatabase database;
20 20
 void main() async {
21 21
   logger = Logger(printer: PrettyPrinter(methodCount: 0));
22 22
 
23
-  database = MyDatabase();
23
+
24 24
   // database = MyDatabase(NativeDatabase.memory());
25 25
 
26 26
   initReportException(() async {
@@ -31,6 +31,7 @@ void main() async {
31 31
     ]);
32 32
 
33 33
     runApp(const MyApp());
34
+    database = MyDatabase();
34 35
   });
35 36
 }
36 37
 

+ 39 - 204
lib/page/print/connect_print_page.dart

@@ -39,125 +39,8 @@ class ConnectPrintPage extends StatefulWidget {
39 39
 
40 40
 class _ConnectPrintPageState extends BaseLifecycleState<ConnectPrintPage> {
41 41
 
42
-  late List<ServiceModel> serviceList;
43
-  late List<BlueDeviceInfo> deviceList;
44
-  late List<String> deviceMacList;
45 42
 
46
-  String scanDeviceState = '';
47
-
48
-  @override
49
-  void initState() {
50
-    super.initState();
51
-    serviceList = [
52
-      ServiceModel(name: '搜索', icon: imgHomeListPzjc, onTap: () => startScan()),
53
-    ];
54
-    deviceList = [];
55
-    deviceMacList = [];
56
-
57
-     PrintService.hasBluetoothConnectDevice().then((result) {
58
-       if(result == false) {
59
-         PrintService.connectedDeviceList = [];
60
-         PrintService.connectedDeviceMacList = [];
61
-       }
62
-     });
63
-  }
64
-
65
-  /// 去搜索
66
-  Future<void> startScan() async {
67
-
68
-    setState(() {
69
-      deviceList = [];
70
-      deviceMacList = [];
71
-    });
72
-    await PrintService.startBluetoothDiscovery();
73
-  }
74
-
75
-  Future<int> savaToSqlite(BlueDeviceInfo deviceInfo) async {
76
-    DeviceInfoTableCompanion tableCompanion = ModelFactory.convertToTSlideComp(deviceInfo.deviceMac, deviceInfo.deviceName);
77
-    return await database.deviceInfoTableDao.addOneDeviceComp(tableCompanion);
78
-  }
79
-
80
-  /// 去连接
81
-  Future<void> startConnect(BlueDeviceInfo deviceInfo) async {
82
-    if(deviceInfo.connectStateStr == '未配对') {
83
-      MyNavigator.showLoading(msg: '配对中...');
84
-      await PrintService.startBluetoothPair(deviceInfo);
85
-    } else if(deviceInfo.connectStateStr == '已配对') {
86
-      MyNavigator.showLoading(msg: '连接中...');
87
-      int connectResult =  await PrintService.startBluetoothConnect(deviceInfo);
88
-      if(connectResult == 0) { // 连接成功
89
-        MyNavigator.dismiss();
90
-        MyNavigator.showToast('连接成功');
91
-        deviceInfo.connectSuccess();
92
-        //addOneSlideComp
93
-
94
-        if(deviceMacList.contains(deviceInfo.deviceMac)) {
95
-          setState(() {
96
-            deviceMacList.removeWhere((element) => element == deviceInfo.deviceMac);
97
-            deviceList.removeWhere((element) => element.deviceMac == deviceInfo.deviceMac);
98
-          });
99
-        }
100
-        setState(() {
101
-          PrintService.connectedDeviceMacList.add(deviceInfo.deviceMac);
102
-          PrintService.connectedDeviceList.add(deviceInfo);
103
-        });
104
-        await savaToSqlite(deviceInfo); // 保存记录到数据库
105
-      } else {
106
-        MyNavigator.dismiss();
107
-        MyNavigator.showToast('连接失败');
108
-      }
109
-    } else if(deviceInfo.connectStateStr == '断开') {
110
-      int connectResult =  await PrintService.endBluetoothConnect(deviceInfo);
111
-      if(connectResult == 0) {  // 断开成功
112
-        deviceInfo.disConnectSuccess();
113
-        if(PrintService.connectedDeviceMacList.contains(deviceInfo.deviceMac)) {
114
-          setState(() {
115
-            PrintService.connectedDeviceMacList.removeWhere((element) => element == deviceInfo.deviceMac);
116
-            PrintService.connectedDeviceList.removeWhere((element) => element.deviceMac == deviceInfo.deviceMac);
117
-          });
118
-        }
119
-        setState(() {
120
-          deviceMacList.add(deviceInfo.deviceMac);
121
-          deviceList.add(deviceInfo);
122
-        });
123
-      }
124
-    }
125
-  }
126
-
127
-
128
-
129
-  @override
130
-  void onInit() {
131
-
132
-    BluetoothPlugin.instance.onReceiveDataStream.listen((deviceInfo) {
133
-      if(deviceInfo != null) {
134
-        if(deviceMacList.contains(deviceInfo.deviceMac)) {
135
-          setState(() {
136
-            deviceMacList.removeWhere((element) => element == deviceInfo.deviceMac);
137
-            deviceList.removeWhere((element) => element.deviceMac == deviceInfo.deviceMac);
138
-          });
139
-        }
140
-        setState(() {
141
-          deviceMacList.add(deviceInfo.deviceMac);
142
-          deviceList.add(deviceInfo);
143
-        });
144
-      }
145
-    });
146
-
147
-    BluetoothPlugin.instance.onDeviceStateStream.listen((deviceState) {
148
-      if(deviceState == DeviceState.pairEnd) {
149
-        MyNavigator.dismiss();
150
-      }
151
-      setState(() {
152
-        scanDeviceState = deviceState ?? "";
153
-      });
154
-    });
155
-  }
156
-
157
-  @override
158
-  void onDestroy() {
159
-
160
-  }
43
+  
161 44
 
162 45
   @override
163 46
   Widget build(BuildContext context) {
@@ -166,95 +49,47 @@ class _ConnectPrintPageState extends BaseLifecycleState<ConnectPrintPage> {
166 49
         children: [
167 50
           myAppBar(title: '连接打印机'),
168 51
           const SizedBox(height: 18),
169
-          ...List.generate(
170
-            serviceList.length,
171
-                (index) => buildServiceItem(serviceList[index]),
172
-          ).toList(),
173
-          const Text('已连接打印机'),
174
-          ...List.generate(
175
-            PrintService.connectedDeviceList.length,
176
-                (index) => buildDeviceItem(PrintService.connectedDeviceList[index]),
177
-          ).toList(),
178
-          const Text('可用打印机'),
179
-          ...List.generate(
180
-            deviceList.length,
181
-                (index) => buildDeviceItem(deviceList[index]),
182
-          ).toList(),
52
+          // ...List.generate(
53
+          //   serviceList.length,
54
+          //       (index) => buildServiceItem(serviceList[index]),
55
+          // ).toList(),
56
+          
183 57
         ],
184 58
       ),
185 59
     );
186 60
   }
187 61
 
188
-  Widget buildServiceItem(ServiceModel service) {
189
-    return GestureDetector(
190
-      onTap: service.onTap,
191
-      child: Container(
192
-        margin: const EdgeInsets.only(left: 12, right: 12, bottom: 22),
193
-        padding: const EdgeInsets.symmetric(vertical: 20, horizontal: 40),
194
-        clipBehavior: Clip.hardEdge,
195
-        decoration: BoxDecoration(
196
-          borderRadius: const BorderRadius.all(Radius.circular(12)),
197
-          boxShadow: [BoxShadow(color: Colors.black.withOpacity(0.1), offset: const Offset(0, 5), blurRadius: 4)],
198
-          image: const DecorationImage(image: AssetImage(imgHomeListBg), fit: BoxFit.fill),
199
-        ),
200
-        child: Row(
201
-          children: [
202
-            Image.asset(service.icon, height: 64),
203
-            const SizedBox(width: 12),
204
-            Expanded(
205
-              child: Column(
206
-                mainAxisSize: MainAxisSize.min,
207
-                children: [
208
-                  Text(
209
-                    "${service.name}${scanDeviceState == DeviceState.scanStart ? "中..." : ""}",
210
-                    textAlign: TextAlign.center,
211
-                    style: const TextStyle(color: Color(0xFF333333), fontSize: 20, fontWeight: FontWeight.w500),
212
-                  ),
213
-                ],
214
-              ),
215
-            ),
216
-          ],
217
-        ),
218
-      ),
219
-    );
220
-  }
221
-
222
-  Widget buildDeviceItem(BlueDeviceInfo deviceInfo) {
223
-    return GestureDetector(
224
-      onTap: () {
225
-        // 连接
226
-        startConnect(deviceInfo);
227
-      },
228
-      child: Container(
229
-        margin: const EdgeInsets.only(left: 12, right: 12, bottom: 22),
230
-        padding: const EdgeInsets.symmetric(vertical: 10),
231
-        clipBehavior: Clip.hardEdge,
232
-        decoration: BoxDecoration(
233
-          borderRadius: const BorderRadius.all(Radius.circular(12)),
234
-          boxShadow: [BoxShadow(color: Colors.black.withOpacity(0.1), offset: const Offset(0, 5), blurRadius: 4)],
235
-          image: const DecorationImage(image: AssetImage(imgHomeListBg), fit: BoxFit.fill),
236
-        ),
237
-        child: Row(
238
-          mainAxisAlignment: MainAxisAlignment.spaceAround,
239
-          children: [
240
-            Text(
241
-              deviceInfo.deviceName,
242
-              textAlign: TextAlign.center,
243
-              style: const TextStyle(color: Color(0xFF333333), fontSize: 15, fontWeight: FontWeight.w500),
244
-            ),
245
-            Text(
246
-              deviceInfo.deviceMac,
247
-              textAlign: TextAlign.center,
248
-              style: const TextStyle(color: Color(0xFF333333), fontSize: 15, fontWeight: FontWeight.w500),
249
-            ),
250
-            Text(
251
-              deviceInfo.connectStateStr,
252
-              textAlign: TextAlign.center,
253
-              style: const TextStyle(color: Color(0xFF333333), fontSize: 15, fontWeight: FontWeight.w500),
254
-            ),
255
-          ],
256
-        ),
257
-      ),
258
-    );
259
-  }
62
+  // Widget buildServiceItem(ServiceModel service) {
63
+  //   return GestureDetector(
64
+  //     onTap: service.onTap,
65
+  //     child: Container(
66
+  //       margin: const EdgeInsets.only(left: 12, right: 12, bottom: 22),
67
+  //       padding: const EdgeInsets.symmetric(vertical: 20, horizontal: 40),
68
+  //       clipBehavior: Clip.hardEdge,
69
+  //       decoration: BoxDecoration(
70
+  //         borderRadius: const BorderRadius.all(Radius.circular(12)),
71
+  //         boxShadow: [BoxShadow(color: Colors.black.withOpacity(0.1), offset: const Offset(0, 5), blurRadius: 4)],
72
+  //         image: const DecorationImage(image: AssetImage(imgHomeListBg), fit: BoxFit.fill),
73
+  //       ),
74
+  //       child: Row(
75
+  //         children: [
76
+  //           Image.asset(service.icon, height: 64),
77
+  //           const SizedBox(width: 12),
78
+  //           Expanded(
79
+  //             child: Column(
80
+  //               mainAxisSize: MainAxisSize.min,
81
+  //               children: [
82
+  //                 Text(
83
+  //                   "${service.name}${scanDeviceState == DeviceState.scanStart ? "中..." : ""}",
84
+  //                   textAlign: TextAlign.center,
85
+  //                   style: const TextStyle(color: Color(0xFF333333), fontSize: 20, fontWeight: FontWeight.w500),
86
+  //                 ),
87
+  //               ],
88
+  //             ),
89
+  //           ),
90
+  //         ],
91
+  //       ),
92
+  //     ),
93
+  //   );
94
+  // }
260 95
 }

+ 177 - 21
lib/page/print/print_page.dart

@@ -5,8 +5,13 @@ import 'package:lszlgl/page/print/connect_print_page.dart';
5 5
 import 'package:signature/signature.dart';
6 6
 import 'package:lszlgl/widget/button.dart';
7 7
 
8
+import '../../drfit/database.dart';
9
+import '../../drfit/model_factory.dart';
10
+import '../../main.dart';
11
+import '../../plugin/bluetooth_plugin.dart';
8 12
 import '../../service/print_service.dart';
9 13
 import '../home/home_page.dart';
14
+import 'dart:ui' as ui;
10 15
 
11 16
 class PrintPageArgs {
12 17
   /// 二维码数据
@@ -37,30 +42,146 @@ class _PrintPageState extends BaseLifecycleState<PrintPage> {
37 42
 
38 43
   late List<ServiceModel> serviceList;
39 44
 
45
+  late List<BlueDeviceInfo> deviceList;
46
+  late List<String> deviceMacList;
47
+
48
+  String scanDeviceState = '';
49
+
40 50
   @override
41 51
   void initState() {
42 52
     super.initState();
43 53
     serviceList = [
44
-      ServiceModel(name: '连接', icon: imgHomeListPzjc, onTap: () => startConnect()),
45
-      ServiceModel(name: '打印', icon: imgHomeListZcjy, onTap: () => startPrint()),
54
+      ServiceModel(name: '搜索', icon: imgBleSearch, onTap: () => startScan()),
55
+      ServiceModel(name: '打印', icon: imgBlePrint, onTap: () => startPrint()),
46 56
     ];
47
-  }
57
+    deviceList = [];
58
+    deviceMacList = [];
48 59
 
49
-  Future<void> startConnect() async {
50
-
51
-    var args = ConnectPrintPageArgs(count: 0);
52
-    await MyRouter.startConnectPrint(args: args);
60
+    PrintService.hasBluetoothConnectDevice().then((result) {
61
+      if(result == false) {
62
+        PrintService.connectedDeviceList = [];
63
+        PrintService.connectedDeviceMacList = [];
64
+      }
65
+    });
53 66
   }
54 67
 
55 68
   /// 去打印
56 69
   Future<void> startPrint() async {
57 70
 
58
-    await PrintService.startBluetoothPrint(widget.args.bytes!);
71
+
72
+    int targetWidth = 560;
73
+    if(PrintService.connectedDeviceList.last.deviceName.contains("BTP-UP321")) {
74
+      targetWidth = 500;
75
+    }
76
+
77
+    final codec = await ui.instantiateImageCodec(
78
+      widget.args.bytes!,
79
+      targetHeight: 590,  // 640
80
+      targetWidth: targetWidth, // 560
81
+    );
82
+
83
+    final smallImage = (await codec.getNextFrame()).image;
84
+    ByteData? smallBytes = await smallImage.toByteData(format: ui.ImageByteFormat.png);
85
+    Uint8List? smallUint8List = smallBytes?.buffer.asUint8List();
86
+
87
+
88
+    MyNavigator.showLoading(msg: '打印中...');
89
+    await PrintService.startBluetoothPrintBitMap(smallUint8List!);
90
+    MyNavigator.dismiss();
91
+    MyNavigator.showToast('打印成功');
92
+  }
93
+
94
+  /// 去搜索
95
+  Future<void> startScan() async {
96
+
97
+    setState(() {
98
+      deviceList = [];
99
+      deviceMacList = [];
100
+    });
101
+    await PrintService.startBluetoothDiscovery();
102
+  }
103
+
104
+  Future<int> savaToSqlite(BlueDeviceInfo deviceInfo) async {
105
+    DeviceInfoTableCompanion tableCompanion = ModelFactory.convertToTSlideComp(deviceInfo.deviceMac, deviceInfo.deviceName);
106
+    return await database.deviceInfoTableDao.addOneDeviceComp(tableCompanion);
107
+  }
108
+
109
+  /// 去连接
110
+  Future<void> startConnect(BlueDeviceInfo deviceInfo) async {
111
+    if(deviceInfo.connectStateStr.contains('未配对')) {
112
+      MyNavigator.showLoading(msg: '配对中...');
113
+      await PrintService.startBluetoothPair(deviceInfo);
114
+    } else if(deviceInfo.connectStateStr.contains('已配对')) {
115
+      MyNavigator.showLoading(msg: '连接中...');
116
+      int connectResult =  await PrintService.startBluetoothConnect(deviceInfo);
117
+      if(connectResult == 0) { // 连接成功
118
+        MyNavigator.dismiss();
119
+        MyNavigator.showToast('连接成功');
120
+        deviceInfo.connectSuccess();
121
+        //addOneSlideComp
122
+
123
+        if(deviceMacList.contains(deviceInfo.deviceMac)) {
124
+          setState(() {
125
+            deviceMacList.removeWhere((element) => element == deviceInfo.deviceMac);
126
+            deviceList.removeWhere((element) => element.deviceMac == deviceInfo.deviceMac);
127
+          });
128
+        }
129
+        setState(() {
130
+          PrintService.connectedDeviceMacList.add(deviceInfo.deviceMac);
131
+          PrintService.connectedDeviceList.add(deviceInfo);
132
+        });
133
+        await savaToSqlite(deviceInfo); // 保存记录到数据库
134
+      } else {
135
+        MyNavigator.dismiss();
136
+        MyNavigator.showToast('连接失败');
137
+      }
138
+    } else if(deviceInfo.connectStateStr.contains('断开')) {
139
+      int connectResult =  await PrintService.endBluetoothConnect(deviceInfo);
140
+      if(connectResult == 0) {  // 断开成功
141
+        deviceInfo.disConnectSuccess();
142
+        if(PrintService.connectedDeviceMacList.contains(deviceInfo.deviceMac)) {
143
+          setState(() {
144
+            PrintService.connectedDeviceMacList.removeWhere((element) => element == deviceInfo.deviceMac);
145
+            PrintService.connectedDeviceList.removeWhere((element) => element.deviceMac == deviceInfo.deviceMac);
146
+          });
147
+        }
148
+        setState(() {
149
+          deviceMacList.add(deviceInfo.deviceMac);
150
+          deviceList.add(deviceInfo);
151
+        });
152
+      }
153
+    }
59 154
   }
60 155
 
61 156
   @override
62 157
   void onInit() {
63 158
 
159
+    BluetoothPlugin.instance.onReceiveDataStream.listen((deviceInfo) {
160
+      if(deviceInfo != null) {
161
+        if(deviceMacList.contains(deviceInfo.deviceMac)) {
162
+          setState(() {
163
+            deviceMacList.removeWhere((element) => element == deviceInfo.deviceMac);
164
+            deviceList.removeWhere((element) => element.deviceMac == deviceInfo.deviceMac);
165
+          });
166
+        }
167
+        setState(() {
168
+          // 只显示支持的打印机
169
+          if(deviceInfo.deviceName.contains('BTP') || deviceInfo.deviceName.contains('B3S')) {
170
+            deviceMacList.add(deviceInfo.deviceMac);
171
+            deviceList.add(deviceInfo);
172
+          }
173
+        });
174
+      }
175
+    });
176
+
177
+    BluetoothPlugin.instance.onDeviceStateStream.listen((deviceState) {
178
+      if(deviceState == DeviceState.pairEnd) {
179
+        MyNavigator.dismiss();
180
+      }
181
+      setState(() {
182
+        scanDeviceState = deviceState ?? "";
183
+      });
184
+    });
64 185
   }
65 186
 
66 187
   @override
@@ -78,10 +199,21 @@ class _PrintPageState extends BaseLifecycleState<PrintPage> {
78 199
         children: [
79 200
           myAppBar(title: '打印二维码'),
80 201
           const SizedBox(height: 18),
202
+          buildServiceItem(serviceList[0]),
203
+          const Text('已连接打印机'),
204
+          ...List.generate(
205
+            PrintService.connectedDeviceList.length,
206
+                (index) => buildDeviceItem(PrintService.connectedDeviceList[index]),
207
+          ).toList(),
208
+          const Text('可用打印机'),
81 209
           ...List.generate(
82
-            serviceList.length,
83
-                (index) => buildServiceItem(serviceList[index]),
210
+            deviceList.length,
211
+                (index) => buildDeviceItem(deviceList[index]),
84 212
           ).toList(),
213
+          Offstage(
214
+            offstage: PrintService.connectedDeviceList.isEmpty,
215
+            child: buildServiceItem(serviceList[1]),
216
+          )
85 217
         ],
86 218
       ),
87 219
     );
@@ -108,20 +240,10 @@ class _PrintPageState extends BaseLifecycleState<PrintPage> {
108 240
                 mainAxisSize: MainAxisSize.min,
109 241
                 children: [
110 242
                   Text(
111
-                    service.name,
243
+                    "${service.name}${(service.name.contains('搜索')&&scanDeviceState == DeviceState.scanStart) ? "中..." : ""}",
112 244
                     textAlign: TextAlign.center,
113 245
                     style: const TextStyle(color: Color(0xFF333333), fontSize: 20, fontWeight: FontWeight.w500),
114 246
                   ),
115
-                  service.nameEn != null
116
-                      ? Padding(
117
-                    padding: const EdgeInsets.only(top: 4),
118
-                    child: Text(
119
-                      service.nameEn!,
120
-                      textAlign: TextAlign.center,
121
-                      style: const TextStyle(color: Color(0xFF333333), fontSize: 12, fontWeight: FontWeight.w500),
122
-                    ),
123
-                  )
124
-                      : const SizedBox.shrink(),
125 247
                 ],
126 248
               ),
127 249
             ),
@@ -130,4 +252,38 @@ class _PrintPageState extends BaseLifecycleState<PrintPage> {
130 252
       ),
131 253
     );
132 254
   }
255
+
256
+  Widget buildDeviceItem(BlueDeviceInfo deviceInfo) {
257
+    return GestureDetector(
258
+      onTap: () {
259
+        // 连接
260
+        startConnect(deviceInfo);
261
+      },
262
+      child: Container(
263
+        margin: const EdgeInsets.only(left: 12, right: 12, bottom: 22),
264
+        padding: const EdgeInsets.symmetric(vertical: 10),
265
+        clipBehavior: Clip.hardEdge,
266
+        decoration: BoxDecoration(
267
+          borderRadius: const BorderRadius.all(Radius.circular(12)),
268
+          boxShadow: [BoxShadow(color: Colors.black.withOpacity(0.1), offset: const Offset(0, 5), blurRadius: 4)],
269
+          image: const DecorationImage(image: AssetImage(imgHomeListBg), fit: BoxFit.fill),
270
+        ),
271
+        child: Row(
272
+          mainAxisAlignment: MainAxisAlignment.spaceAround,
273
+          children: [
274
+            Text(
275
+              deviceInfo.deviceName,
276
+              textAlign: TextAlign.center,
277
+              style: const TextStyle(color: Color(0xFF333333), fontSize: 15, fontWeight: FontWeight.w500),
278
+            ),
279
+            Text(
280
+              deviceInfo.connectStateStr,
281
+              textAlign: TextAlign.center,
282
+              style: const TextStyle(color: Color(0xFF333333), fontSize: 15, fontWeight: FontWeight.w500),
283
+            ),
284
+          ],
285
+        ),
286
+      ),
287
+    );
288
+  }
133 289
 }

+ 2 - 9
lib/page/sample_task/reap_sample_detail/reap_sample_task_page.dart

@@ -202,15 +202,8 @@ class _ReapSampleTaskPageState extends BaseLifecycleState<ReapSampleTaskPage> wi
202 202
   Future<void> printPic(String? name) async {
203 203
 
204 204
     Uint8List? bytes = await FileUtils.getBitmapFromContext(ewmKey.currentContext);
205
-    final codec = await ui.instantiateImageCodec(
206
-      bytes!,
207
-      targetHeight: 590,
208
-      targetWidth: 580,
209
-    );
210
-    final smallImage = (await codec.getNextFrame()).image;
211
-    ByteData? smallBytes = await smallImage.toByteData(format: ui.ImageByteFormat.png);
212
-    Uint8List? smallUint8List = smallBytes?.buffer.asUint8List();
213
-    var args = PrintPageArgs(bytes: smallUint8List);
205
+
206
+    var args = PrintPageArgs(bytes: bytes);
214 207
     await MyRouter.startPrint(args: args);
215 208
   }
216 209
 

+ 15 - 6
lib/plugin/bluetooth_plugin.dart

@@ -82,12 +82,21 @@ class BluetoothPlugin {
82 82
 
83 83
 
84 84
   //开始打印
85
-  Future<int> startBluetoothPrint(Uint8List bytes) async {
85
+  Future<bool> startBluetoothPrintBitMap(Uint8List bytes) async {
86 86
 
87 87
     if (Platform.isIOS) {
88
-      return 0;
88
+      return false;
89
+    }
90
+    return _channel.invokeMethod('startBluetoothPrintBitMap', bytes).then<bool>((d) => d);
91
+  }
92
+
93
+  //开始打印
94
+  Future<bool> startBluetoothPrintBarCodeWithText(String barCode, String text) async {
95
+
96
+    if (Platform.isIOS) {
97
+      return false;
89 98
     }
90
-    return _channel.invokeMethod('startBluetoothPrint', bytes).then<int>((d) => d);
99
+    return _channel.invokeMethod('startBluetoothPrintBarCodeWithText', {"barCode": barCode, "text": text}).then<bool>((d) => d);
91 100
   }
92 101
 
93 102
 
@@ -145,16 +154,16 @@ class BlueDeviceInfo {
145 154
   String get connectStateStr {
146 155
 
147 156
     if(connectState == '10') {
148
-      _connectStateStr = "未配对";
157
+      _connectStateStr = "未配对(点击进行配对)";
149 158
     }
150 159
     if(connectState == '11') {
151 160
       _connectStateStr = "配对中";
152 161
     }
153 162
     if(connectState == '12') {
154
-      _connectStateStr = "已配对";
163
+      _connectStateStr = "已配对(点击进行连接)";
155 164
     }
156 165
     if(connectState == '13') {
157
-      _connectStateStr = "断开";
166
+      _connectStateStr = "断开(点击断开连接)";
158 167
     }
159 168
     return _connectStateStr ?? "未知";
160 169
   }

+ 16 - 4
lib/service/print_service.dart

@@ -118,16 +118,28 @@ class PrintService {
118 118
     }
119 119
   }
120 120
 
121
-  //开始打印
122
-  static Future<int> startBluetoothPrint(Uint8List bytes) async {
121
+  //开始打印图片
122
+  static Future<bool> startBluetoothPrintBitMap(Uint8List bytes) async {
123 123
 
124 124
     if(await canExecAction()) {
125
-      return await BluetoothPlugin.instance.startBluetoothPrint(bytes);
125
+       return await BluetoothPlugin.instance.startBluetoothPrintBitMap(bytes);
126 126
     } else {
127
-      return 0;
127
+      return false;
128 128
     }
129 129
   }
130 130
 
131
+  //开始打印二维码和文本
132
+  static Future<bool> startBluetoothPrintBarCodeWithText(String barCode, String text) async {
133
+
134
+    if(await canExecAction()) {
135
+      return await BluetoothPlugin.instance.startBluetoothPrintBarCodeWithText(barCode, text);
136
+    } else {
137
+      return false;
138
+    }
139
+  }
140
+
141
+
142
+
131 143
 
132 144
 
133 145
 

+ 2 - 0
pubspec.yaml

@@ -91,6 +91,8 @@ dependencies:
91 91
   image_gallery_saver: ^2.0.3
92 92
   # 数据库
93 93
   drift: ^2.18.0
94
+  #
95
+  sqlite3_flutter_libs: ^0.5.0
94 96
 
95 97
 dev_dependencies:
96 98
   flutter_test: