Browse Source

蓝牙打印完成

周素华 10 months ago
parent
commit
3341081f4a

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

@@ -14,8 +14,6 @@ public class MainActivity extends FlutterActivity {
14 14
     public void configureFlutterEngine(@NonNull FlutterEngine flutterEngine) {
15 15
         super.configureFlutterEngine(flutterEngine);
16 16
 
17
-
18
-
19 17
         Log.e("AAAA", ">>> configureFlutterEngine");
20 18
         GeneratedPluginRegister.registerGeneratedPlugins(flutterEngine);
21 19
 

+ 135 - 0
android/app/src/main/java/io/flutter/plugins/BluetoothPlugin.java

@@ -10,6 +10,8 @@ import android.content.Intent;
10 10
 import android.content.IntentFilter;
11 11
 import android.content.SharedPreferences;
12 12
 import android.content.pm.PackageManager;
13
+import android.graphics.Bitmap;
14
+import android.graphics.BitmapFactory;
13 15
 import android.location.LocationManager;
14 16
 import android.os.Build;
15 17
 import android.text.TextUtils;
@@ -21,10 +23,13 @@ import androidx.annotation.NonNull;
21 23
 import androidx.core.app.ActivityCompat;
22 24
 import androidx.fragment.app.FragmentActivity;
23 25
 
26
+import com.gengcon.www.jcprintersdk.callback.PrintCallback;
24 27
 import com.permissionx.guolindev.PermissionX;
25 28
 import com.szls.lszlgl.MainActivity;
26 29
 
27 30
 import java.security.Permission;
31
+import java.util.ArrayList;
32
+import java.util.HashMap;
28 33
 import java.util.List;
29 34
 import java.util.concurrent.ExecutorService;
30 35
 import java.util.concurrent.LinkedBlockingDeque;
@@ -154,6 +159,17 @@ public class BluetoothPlugin implements FlutterPlugin, MethodChannel.MethodCallH
154 159
                 Log.d("ble", "endBluetoothConnect :"+methodCall.arguments);
155 160
                 endBluetoothConnect(methodCall, result);
156 161
                 break;
162
+            case "hasBluetoothConnectDevice":
163
+                Log.d("ble", "hasBluetoothConnectDevice :"+methodCall.arguments);
164
+                hasBluetoothConnectDevice(methodCall, result);
165
+                break;
166
+            case "startBluetoothPrint":
167
+                Log.d("ble", "startBluetoothPrint :"+methodCall.arguments);
168
+                startBluetoothPrint(methodCall, result);
169
+                break;
170
+
171
+
172
+
157 173
 
158 174
 
159 175
 
@@ -280,6 +296,125 @@ public class BluetoothPlugin implements FlutterPlugin, MethodChannel.MethodCallH
280 296
         result.success(0);
281 297
     }
282 298
 
299
+    void hasBluetoothConnectDevice(@NonNull MethodCall methodCall, @NonNull MethodChannel.Result result) {
300
+        if (PrintUtil.isConnection() == 0 && PrintUtil.getConnectedType()==0) {
301
+            Log.d("ble", "测试:配对状态改变:判断连接状态 2" );
302
+             result.success(true);
303
+        }else {
304
+            Log.d("ble", "测试:配对状态改变:判断连接状态4 " );
305
+            result.success(false);
306
+        }
307
+    }
308
+
309
+    void startBluetoothPrint(@NonNull MethodCall methodCall, @NonNull MethodChannel.Result result) {
310
+
311
+        byte[] imageByte = (byte[]) methodCall.arguments;
312
+
313
+        Log.d("ble", "imageByte:" + imageByte);
314
+        Bitmap bitmap = Bytes2Bimap(imageByte);
315
+
316
+        PrintUtil.getInstance().drawEmptyLabel(40, 60, 0, "");
317
+        if (PrintUtil.isConnection() != 0) {
318
+//            handler.post(() -> Toast.makeText(MyApplication.getInstance(), "未连接打印机", Toast.LENGTH_SHORT).show());
319
+            return;
320
+        }
321
+
322
+//        fragment = new MyDialogLoadingFragment("打印中");
323
+//        fragment.show(getSupportFragmentManager(), "PRINT");
324
+
325
+
326
+        //重置错误状态变量
327
+        boolean isError = false;
328
+        //重置取消打印状态变量
329
+        boolean isCancel = false;
330
+
331
+        int orientation = 0;
332
+
333
+        int pageCount = 1;
334
+        int quantity = 1;
335
+        int printMultiple = 8;
336
+        final int[] generatedPrintDataPageCount = {0};
337
+        int totalQuantity = pageCount * quantity;
338
+
339
+        //setTotalQuantityOfPrints已废弃,使用方法含义更明确的setTotalPrintQuantity
340
+        PrintUtil.getInstance().setTotalPrintQuantity(totalQuantity);
341
+        /*
342
+         * 参数1:打印浓度 ,参数2:纸张类型 参数3:打印模式
343
+         * 打印浓度 B50/B50W/T6/T7/T8 建议设置6或8,Z401/B32建议设置8,B3S/B21/B203/B1建议设置3
344
+         */
345
+        PrintUtil.getInstance().startPrintJob(3, 3, 1, new PrintCallback() {
346
+            @Override
347
+            public void onProgress(int pageIndex, int quantityIndex, HashMap<String, Object> hashMap) {
348
+//                handler.post(() -> fragment.setStateStr("打印进度:已打印到第" + pageIndex + "页,第" + quantityIndex + "份"));
349
+                Log.d("ble", "测试:打印进度:已打印到第: " + pageIndex);
350
+                //打印进度回调
351
+                if (pageIndex == pageCount && quantityIndex == quantity) {
352
+                    Log.d("ble", "测试:onProgress: 结束打印");
353
+                    //endJob已废弃,使用方法含义更明确的endPrintJob
354
+                    if (PrintUtil.getInstance().endPrintJob()) {
355
+                        Log.d("ble", "结束打印成功");
356
+                    } else {
357
+                        Log.d("ble", "结束打印失败");
358
+                    }
359
+//                    handlePrintResult(fragment, "打印成功");
360
+                }
361
+            }
362
+
363
+            @Override
364
+            public void onError(int i) {
365
+
366
+            }
367
+
368
+
369
+            @Override
370
+            public void onError(int errorCode, int printState) {
371
+                Log.d("ble", "测试:onError");
372
+//                isError = true;
373
+//                String errorMsg = ERROR_MESSAGES.getOrDefault(errorCode, "");
374
+//                handlePrintResult(fragment, errorMsg);
375
+            }
376
+
377
+            @Override
378
+            public void onCancelJob(boolean isSuccess) {
379
+                //取消打印成功回调
380
+//                isCancel = true;
381
+            }
382
+
383
+            @Override
384
+            public void onBufferFree(int pageIndex, int bufferSize) {
385
+                if (isError || isCancel || pageIndex > pageCount) {
386
+                    return;
387
+                }
388
+
389
+                if (generatedPrintDataPageCount[0] < pageCount) {
390
+//                    ArrayList<Dish> dishList = new ArrayList<>();
391
+//                    dishList.add(new Dish("辣椒炒肉", "中辣", 29.9, 1));
392
+//                    dishList.add(new Dish("土豆牛腩", "中辣", 49.9, 1));
393
+//
394
+//                    Bitmap bitmap = ImgUtil.Companion.generatePosReceiptImage(dishList);
395
+
396
+                    int bitmapWidth = bitmap.getWidth();
397
+                    int bitmapHeight = bitmap.getHeight();
398
+                    Log.d("ble", "bitmapWidth:"+bitmapWidth+",bitmapHeight:"+bitmapHeight);
399
+                    PrintUtil.getInstance().commitImageData(orientation, bitmap, (int) (bitmapWidth / printMultiple), (int) (bitmapHeight / printMultiple), 1, 0, 0, 0, 0, "");
400
+
401
+
402
+                }
403
+
404
+
405
+            }
406
+        });
407
+
408
+    }
409
+
410
+    public Bitmap Bytes2Bimap(byte[] b) {
411
+        if (b.length != 0) {
412
+            return BitmapFactory.decodeByteArray(b, 0, b.length);
413
+        } else {
414
+            return null;
415
+        }
416
+    }
417
+
283 418
     private final BroadcastReceiver receiver = new BroadcastReceiver() {
284 419
 
285 420
         @SuppressLint("MissingPermission")

+ 1 - 3
lib/page/home/home_page.dart

@@ -23,9 +23,7 @@ class _HomePageState extends BaseState<HomePage> with AutomaticKeepAliveClientMi
23 23
   late List<ServiceModel> serviceList;
24 24
 
25 25
   void startSampleList(StepType type) async {
26
-    var args = PrintPageArgs(count: 0);
27
-    await MyRouter.startPrint(args: args);
28
-    // MyRouter.startSampleTaskList(SampleTaskListTabPageArgs(type: type));
26
+    MyRouter.startSampleTaskList(SampleTaskListTabPageArgs(type: type));
29 27
   }
30 28
 
31 29
   @override

+ 14 - 12
lib/page/print/connect_print_page.dart

@@ -41,9 +41,6 @@ class _ConnectPrintPageState extends BaseLifecycleState<ConnectPrintPage> {
41 41
   late List<BlueDeviceInfo> deviceList;
42 42
   late List<String> deviceMacList;
43 43
 
44
-  late List<BlueDeviceInfo> connectedDeviceList;
45
-  late List<String> connectedDeviceMacList;
46
-
47 44
   String scanDeviceState = '';
48 45
 
49 46
   @override
@@ -54,8 +51,13 @@ class _ConnectPrintPageState extends BaseLifecycleState<ConnectPrintPage> {
54 51
     ];
55 52
     deviceList = [];
56 53
     deviceMacList = [];
57
-    connectedDeviceList = [];
58
-    connectedDeviceMacList = [];
54
+
55
+     PrintService.hasBluetoothConnectDevice().then((result) {
56
+       if(result == false) {
57
+         PrintService.connectedDeviceList = [];
58
+         PrintService.connectedDeviceMacList = [];
59
+       }
60
+     });
59 61
   }
60 62
 
61 63
   /// 去搜索
@@ -87,8 +89,8 @@ class _ConnectPrintPageState extends BaseLifecycleState<ConnectPrintPage> {
87 89
           });
88 90
         }
89 91
         setState(() {
90
-          connectedDeviceMacList.add(deviceInfo.deviceMac);
91
-          connectedDeviceList.add(deviceInfo);
92
+          PrintService.connectedDeviceMacList.add(deviceInfo.deviceMac);
93
+          PrintService.connectedDeviceList.add(deviceInfo);
92 94
         });
93 95
       } else {
94 96
         MyNavigator.dismiss();
@@ -98,10 +100,10 @@ class _ConnectPrintPageState extends BaseLifecycleState<ConnectPrintPage> {
98 100
       int connectResult =  await PrintService.endBluetoothConnect(deviceInfo);
99 101
       if(connectResult == 0) {  // 断开成功
100 102
         deviceInfo.disConnectSuccess();
101
-        if(connectedDeviceMacList.contains(deviceInfo.deviceMac)) {
103
+        if(PrintService.connectedDeviceMacList.contains(deviceInfo.deviceMac)) {
102 104
           setState(() {
103
-            connectedDeviceMacList.removeWhere((element) => element == deviceInfo.deviceMac);
104
-            connectedDeviceList.removeWhere((element) => element.deviceMac == deviceInfo.deviceMac);
105
+            PrintService.connectedDeviceMacList.removeWhere((element) => element == deviceInfo.deviceMac);
106
+            PrintService.connectedDeviceList.removeWhere((element) => element.deviceMac == deviceInfo.deviceMac);
105 107
           });
106 108
         }
107 109
         setState(() {
@@ -158,8 +160,8 @@ class _ConnectPrintPageState extends BaseLifecycleState<ConnectPrintPage> {
158 160
           ).toList(),
159 161
           const Text('已连接打印机'),
160 162
           ...List.generate(
161
-            connectedDeviceList.length,
162
-                (index) => buildDeviceItem(connectedDeviceList[index]),
163
+            PrintService.connectedDeviceList.length,
164
+                (index) => buildDeviceItem(PrintService.connectedDeviceList[index]),
163 165
           ).toList(),
164 166
           const Text('可用打印机'),
165 167
           ...List.generate(

+ 6 - 32
lib/page/print/print_page.dart

@@ -9,14 +9,14 @@ import '../../service/print_service.dart';
9 9
 import '../home/home_page.dart';
10 10
 
11 11
 class PrintPageArgs {
12
-  /// 签名数量
13
-  int count;
12
+  /// 二维码数据
13
+  Uint8List? bytes;
14 14
 
15
-  PrintPageArgs({this.count = 1});
15
+  PrintPageArgs({this.bytes});
16 16
 
17 17
   @override
18 18
   String toString() {
19
-    return {'count': count}.toString();
19
+    return {'bytes': bytes}.toString();
20 20
   }
21 21
 }
22 22
 
@@ -34,13 +34,6 @@ class PrintPage extends StatefulWidget {
34 34
 }
35 35
 
36 36
 class _PrintPageState extends BaseLifecycleState<PrintPage> {
37
-  late int count;
38
-  late List<SignatureController> ctrlList;
39
-  late PageController pageCtrl;
40
-
41
-  final previousEnable = false.notifier<bool>();
42
-  final nextEnable = false.notifier<bool>();
43
-  final submitEnable = false.notifier<bool>();
44 37
 
45 38
   late List<ServiceModel> serviceList;
46 39
 
@@ -61,29 +54,13 @@ class _PrintPageState extends BaseLifecycleState<PrintPage> {
61 54
 
62 55
   /// 去打印
63 56
   Future<void> startPrint() async {
64
-    // await PrintService.startBluetoothPair(deviceInfo);
57
+
58
+    await PrintService.startBluetoothPrint(widget.args.bytes!);
65 59
   }
66 60
 
67 61
   @override
68 62
   void onInit() {
69 63
 
70
-    // 创建签名列表
71
-    count = widget.args.count;
72
-    ctrlList = List.generate(
73
-      count,
74
-          (index) => SignatureController(
75
-        penStrokeWidth: 6,
76
-        penColor: Colors.black,
77
-        strokeJoin: StrokeJoin.round,
78
-        strokeCap: StrokeCap.round,
79
-      ),
80
-    ).toList();
81
-    pageCtrl = PageController();
82
-    if (count == 1) {
83
-      submitEnable.value = true;
84
-    } else {
85
-      nextEnable.value = true;
86
-    }
87 64
   }
88 65
 
89 66
   @override
@@ -92,9 +69,6 @@ class _PrintPageState extends BaseLifecycleState<PrintPage> {
92 69
       DeviceOrientation.portraitUp,
93 70
       DeviceOrientation.portraitDown,
94 71
     ]);
95
-    for (var ctrl in ctrlList) {
96
-      ctrl.dispose();
97
-    }
98 72
   }
99 73
 
100 74
   @override

+ 12 - 1
lib/page/sample_task/reap_sample_detail/reap_sample_task_page.dart

@@ -23,6 +23,7 @@ import '../../../plugin/bluetooth_plugin.dart';
23 23
 import '../../../utils/file_utils.dart';
24 24
 import '../../../widget/button.dart';
25 25
 import '../../../widget/page_widget.dart';
26
+import 'dart:ui' as ui;
26 27
 
27 28
 class ReapSampleTaskPageArgs {
28 29
   final bool detail;
@@ -199,7 +200,17 @@ class _ReapSampleTaskPageState extends BaseLifecycleState<ReapSampleTaskPage> wi
199 200
   }
200 201
 
201 202
   Future<void> printPic(String? name) async {
202
-    var args = PrintPageArgs(count: 0);
203
+
204
+    Uint8List? bytes = await FileUtils.getBitmapFromContext(ewmKey.currentContext);
205
+    final codec = await ui.instantiateImageCodec(
206
+      bytes!,
207
+      targetHeight: 450,
208
+      targetWidth: 80*4,
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);
203 214
     await MyRouter.startPrint(args: args);
204 215
   }
205 216
 

+ 11 - 6
lib/plugin/bluetooth_plugin.dart

@@ -71,19 +71,24 @@ class BluetoothPlugin {
71 71
     return _channel.invokeMethod('endBluetoothConnect', deviceInfoStr).then<int>((d) => d);
72 72
   }
73 73
 
74
-
75
-  //开始打印
76
-  Future<int> startBluetoothPrint(BlueDeviceInfo deviceInfo) async {
74
+  //断开连接
75
+  Future<bool> hasBluetoothConnectDevice() async {
77 76
 
78 77
     if (Platform.isIOS) {
79
-      return 0;
78
+      return false;
80 79
     }
81
-    String deviceInfoStr = deviceInfo.deviceName+delimiterStr+deviceInfo.deviceMac+delimiterStr+deviceInfo.connectState;
82
-    return _channel.invokeMethod('startBluetoothPrint', deviceInfoStr).then<int>((d) => d);
80
+    return _channel.invokeMethod('hasBluetoothConnectDevice').then<bool>((d) => d);
83 81
   }
84 82
 
85 83
 
84
+  //开始打印
85
+  Future<int> startBluetoothPrint(Uint8List bytes) async {
86 86
 
87
+    if (Platform.isIOS) {
88
+      return 0;
89
+    }
90
+    return _channel.invokeMethod('startBluetoothPrint', bytes).then<int>((d) => d);
91
+  }
87 92
 
88 93
 
89 94
 

+ 21 - 2
lib/service/print_service.dart

@@ -1,14 +1,21 @@
1 1
 
2 2
 
3
+import 'dart:ffi';
4
+
3 5
 import 'package:lszlgl/utils/permission_utils.dart';
4 6
 import 'package:permission_handler/permission_handler.dart';
5 7
 
6 8
 import '../plugin/bluetooth_plugin.dart';
7 9
 import '../router/my_navigator.dart';
10
+import 'package:flutter/material.dart';
11
+import 'package:flutter/services.dart';
8 12
 
9 13
 class PrintService {
10 14
   PrintService._();
11 15
 
16
+  static List<BlueDeviceInfo> connectedDeviceList = [];
17
+  static List<String> connectedDeviceMacList = [];
18
+
12 19
   //是否打开蓝牙
13 20
   static Future<bool> isBleOpen() async {
14 21
     return await BluetoothPlugin.instance.isBleOpen();
@@ -101,17 +108,29 @@ class PrintService {
101 108
     }
102 109
   }
103 110
 
111
+  //是否有连接中的设备
112
+  static Future<bool> hasBluetoothConnectDevice() async {
113
+
114
+    if(await canExecAction()) {
115
+      return await BluetoothPlugin.instance.hasBluetoothConnectDevice();
116
+    } else {
117
+      return false;
118
+    }
119
+  }
120
+
104 121
   //开始打印
105
-  static Future<int> startBluetoothPrint(BlueDeviceInfo deviceInfo) async {
122
+  static Future<int> startBluetoothPrint(Uint8List bytes) async {
106 123
 
107 124
     if(await canExecAction()) {
108
-      return await BluetoothPlugin.instance.startBluetoothPrint(deviceInfo);
125
+      return await BluetoothPlugin.instance.startBluetoothPrint(bytes);
109 126
     } else {
110 127
       return 0;
111 128
     }
112 129
   }
113 130
 
114 131
 
132
+
133
+
115 134
 }
116 135
 
117 136
 

+ 1 - 0
lib/utils/file_utils.dart

@@ -4,6 +4,7 @@ import 'dart:ui' as ui;
4 4
 
5 5
 import 'package:flutter/cupertino.dart';
6 6
 import 'package:flutter/rendering.dart';
7
+import 'package:lszlgl/main.dart';
7 8
 import 'package:path_provider/path_provider.dart';
8 9
 
9 10
 class FileUtils {