5.6 KiB
5.6 KiB
打印机插件设计文档
日期: 2026-04-22 状态: 已确认 目标: 将 printer 插件开发为完整的打印插件,支持通过 CH34 串口 + autoreplyprint.aar 进行打印
1. 项目概述
用途
公司内部多个 Flutter 项目共用的打印插件,用于打印拉曼检测结果(简单文字票据)。
技术架构
- CH34 插件提供串口通道
- 本项目 Android 原生层集成 autoreplyprint.aar
- Dart 层通过 MethodChannel 调用原生层
- 底层指令式 API:调用方控制打开→打印→关闭全流程
2. 整体架构
┌─────────────────────────────────────────────┐
│ 调用方 Flutter 项目 │
│ Printer.openComPort() → PrinterPortHandle │
│ handle.printText() → handle.close() │
└──────────────┬───────────────────────────────┘
│ MethodChannel 调用
┌──────────────▼───────────────────────────────┐
│ Flutter 插件 Dart 层 │
│ Printer → PrinterPlatform │
│ → MethodChannelPrinterPort │
│ → PrinterPortHandle │
└──────────────┬───────────────────────────────┐
│ MethodChannel + portHandle
┌──────────────▼───────────────────────────────┐
│ Android 原生层 (Java) │
│ PrinterPlugin (MethodCallHandler) │
│ → PortHandleManager │
│ → autoreplyprint.aar │
└───────────────────────────────────────────────┘
3. API 设计
使用示例
// 打开端口
PrinterPortHandle port = await Printer.openComPort(
portName: 'COM3',
baudRate: 9600,
dataBits: 8,
parity: Parity.none,
stopBits: StopBits.one,
flowControl: FlowControl.none,
);
// 设置编码
await port.setMultiByteMode();
await port.setMultiByteEncoding(MultiByteEncoding.utf8);
// 打印
await port.setAlignment(Alignment.center);
await port.setTextScale(width: 2, height: 2);
await port.printText('拉曼检测结果报告');
// 走纸切纸
await port.feedLine(3);
await port.halfCutPaper();
// 关闭
await port.close();
API 分类
| 类别 | 方法 |
|---|---|
| 端口管理 | openComPort, close |
| 打印文本 | printText, printTextInUtf8, printTextInGbk |
| 格式控制 | setAlignment, setTextScale, setTextBold, setTextUnderline |
| 走纸切纸 | feedLine, feedDot, halfCutPaper, fullCutPaper |
| 编码模式 | setMultiByteMode, setSingleByteMode, setMultiByteEncoding |
| 条码/二维码 | printBarcode, printQRCode |
| 图片 | printRasterImageFromData |
| 其他 | resetPrinter, kickOutDrawer, beep |
4. MethodChannel 协议
协议格式
MethodChannel 名称: "printer"
Method: "openComPort"
Args: { portName, baudRate, dataBits, parity, stopBits, flowControl, autoReplyMode }
Return: { success: bool, portHandle: int?, error: String? }
Method: "closePort"
Args: { portHandle }
Return: { success: bool, error: String? }
Method: "printText"
Args: { portHandle, text }
Return: { success: bool, error: String? }
... // 每个操作对应一个 method call
错误处理
- 原生层异常通过
result.error()返回 - Dart 层统一包装为
PrinterException
5. 原生层设计
端口句柄管理
PrinterPlugin.java维护Map<Integer, Pointer> portHandlesopenComPort调用CP_Port_OpenCom返回 Pointer 存入 map- 生成递增 int 作为 Dart 层 portHandle
- 每个 method call 从 map 中取出 Pointer,调用对应 AAR 函数
AAR 集成
- 将
docs/autoreplyprint.aar移至android/libs/ build.gradle.kts配置implementation files('libs/autoreplyprint.aar')
6. 项目结构
printer/
├── lib/
│ ├── printer.dart # 主入口
│ ├── printer_platform_interface.dart # 平台接口
│ ├── printer_method_channel.dart # MethodChannel 实现
│ └── src/
│ ├── models/
│ │ ├── parity.dart # 串口校验枚举
│ │ ├── alignment.dart # 对齐枚举
│ │ ├── encoding.dart # 字符编码枚举
│ │ └── printer_exception.dart # 自定义异常
│ └── port_handle.dart # 端口句柄封装
├── android/
│ ├── build.gradle.kts
│ ├── libs/
│ │ └── autoreplyprint.aar
│ └── src/main/java/com/xiarui/printer/
│ ├── PrinterPlugin.java
│ └── PortHandleManager.java
└── test/
└── printer_test.dart
7. 关键决策
| 决策 | 选择 | 理由 |
|---|---|---|
| SDK 集成方式 | 原生层调用 AAR | 利用已有封装,可靠 |
| API 风格 | 底层指令式 | 灵活,调用方控制流程 |
| 字符编码 | UTF8 | 中文支持,现代标准 |
| 连接方式 | 串口 (通过 CH34) | 项目实际硬件需求 |
| 状态回调 | 暂不需要 | 最小实现,后续可扩展 |