如何在Flutter应用中通过原生Java SDK调用Brother打印机打印标签?
问题根因
你遇到的android.os.NetworkOnMainThreadException是Android系统的强制限制:所有网络通信类操作禁止在UI主线程执行。当前Brother SDK的打印机连接、打印逻辑直接运行在Flutter MethodChannel的默认回调线程(即Android主线程),触发了系统拦截。
解决方案
1. 调整Java层打印逻辑到工作线程执行
将打印逻辑移到独立工作线程中运行,执行完成后切回主线程回调结果给Flutter,修改后的Java层代码如下:
if (call.method.equals("print")) { String address = call.argument("address"); String base64 = call.argument("bas64"); final Result finalResult = result; // 启动工作线程执行网络相关操作 new Thread(() -> { Printer printer = new Printer(); PrinterInfo settings = printer.getPrinterInfo(); settings.printerModel = PrinterInfo.Model.QL_810W; settings.port = PrinterInfo.Port.NET; settings.ipAddress = address; // 打印参数配置和原有逻辑保持一致 settings.paperSize = PrinterInfo.PaperSize.CUSTOM; settings.orientation = PrinterInfo.Orientation.LANDSCAPE; settings.valign = PrinterInfo.VAlign.MIDDLE; settings.align = PrinterInfo.Align.CENTER; settings.printMode = PrinterInfo.PrintMode.FIT_TO_PAGE; settings.numberOfCopies = 1; settings.labelNameIndex = LabelInfo.QL700.W52H29.ordinal(); //settings.labelNameIndex = LabelInfo.QL700.W62.ordinal(); settings.isAutoCut = true; settings.isCutAtEnd = false; settings.isHalfCut = false; settings.isSpecialTape = false; printer.setPrinterInfo(settings); PrinterStatus bit = new PrinterStatus(); if (printer.startCommunication()) { bit = printer.printImage(bmpFromBase64(base64)); printer.endCommunication(); // MethodChannel的结果回调必须在主线程执行 new Handler(Looper.getMainLooper()).post(() -> { if (bit.errorCode != PrinterInfo.ErrorCode.ERROR_NONE) { Log.d("TAG", "ERROR - " + bit.errorCode); finalResult.error("ERROR",bit.errorCode.toString(),"Error when Printing"); } else { finalResult.success(0); } }); } else { new Handler(Looper.getMainLooper()).post(() -> finalResult.error("ERROR", "CONNECTION_FAILED", "Failed to connect printer") ); } }).start(); }else{ result.notImplemented(); }
2. 配套检查项
- 确认
AndroidManifest.xml中已添加必要权限:
<!-- 网络通信权限 --> <uses-permission android:name="android.permission.INTERNET" /> <uses-permission android:name="android.permission.ACCESS_WIFI_STATE" /> <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
- 若你的应用适配Android 9及以上系统,打印机为内网IP使用明文Socket通信的话,需要在
AndroidManifest.xml的application标签添加android:usesCleartextTraffic="true"。 - 你当前传参使用的key为
bas64,只要Flutter端和Java端保持一致即可正常取值,若后续出现空图异常可优先核对该参数。
内容的提问来源于stack exchange,提问作者Abinandhan Selvaraj
相关产品推荐
相关产品推荐

