如何使用Delphi FMX实现Android设备端Canvas打印功能
Delphi FMX 安卓平台打印Canvas内容实现方案
FMX自带的TPrintDialog、标准打印组件仅适配Windows、macOS等桌面平台,安卓端没有对应实现,直接调用会报错或无响应。安卓平台打印不需要手动处理打印机连接逻辑,直接调用系统原生打印框架即可,系统会自动识别WiFi、蓝牙、局域网、云打印等各类已配置的可用打印机,具体实现步骤如下:
前置准备
- 打开项目的安卓平台权限配置:
- 网络打印机/云打印场景勾选
android.permission.INTERNET - 安卓13及以上版本额外勾选附近设备相关权限,否则无法搜索到局域网/蓝牙直连打印机
- 网络打印机/云打印场景勾选
- 代码中引用必要单元:
FMX.Graphics、Androidapi.Helpers、Androidapi.JNI.GraphicsContentViewText、Androidapi.JNI.Print、Androidapi.JNI.JavaTypes
具体实现步骤
- 导出待打印内容为高清位图
不要直接用屏幕分辨率的画布生成打印内容,否则打印出来会模糊,按打印需求的DPI(常规打印用300DPI即可,A4尺寸对应像素为2480*3508)创建指定位图,把你原本在Windows端写的Canvas绘制逻辑,原封不动绘制到这个位图画布上:
var LPrintBitmap: TBitmap; begin // 按实际打印尺寸创建对应分辨率的位图 LPrintBitmap := TBitmap.Create(2480, 3508); try LPrintBitmap.Canvas.BeginScene; try // 此处替换为你自己的Canvas绘制逻辑 // 原本Windows端往Printer.Canvas绘制的所有代码,都可以直接复用在这里 DrawYourBusinessContent(LPrintBitmap.Canvas, LPrintBitmap.Width, LPrintBitmap.Height); finally LPrintBitmap.Canvas.EndScene; end;
- 拉起安卓系统打印服务
安卓4.4及以上版本内置系统打印服务,通过PrintManager拉起系统自带的打印选择界面即可,不需要自己实现打印机发现、连接、驱动适配的逻辑:
var LPrintManager: JPrintManager; var LPrintAdapter: JPrintDocumentAdapter; begin // 获取系统打印服务实例 LPrintManager := TJPrintManager.Wrap( TAndroidHelper.Context.getSystemService(TJContext.JavaClass.PRINT_SERVICE) ); if LPrintManager = nil then raise Exception.Create('当前设备系统版本低于4.4,不支持原生打印框架'); // 传入前面生成的位图,创建打印文档适配器 LPrintAdapter := TBitmapPrintAdapter.Create( StringToJString('打印任务'), LPrintBitmap ); // 拉起系统打印界面 LPrintManager.print( StringToJString('FMX文档打印'), LPrintAdapter, nil ); end; finally LPrintBitmap.Free; end; end;
- 实现打印适配器类
自定义继承自打印文档适配器基类的TBitmapPrintAdapter,重写onLayout(计算打印页面尺寸、总页数)和onWrite(把位图内容写入系统提供的输出流)两个核心方法即可完成整个流程。
注意事项
- 不要尝试在安卓端直接复用FMX桌面端的Printer对象逻辑:FMX的Printer类在安卓平台没有完整实现,强行调用大概率会输出空白页或者直接触发异常。
- 多页打印场景只需要在
onLayout回调中返回总页数,在onWrite回调中按传入的页码范围生成对应页面的内容写入输出流即可。 - 如果是对接热敏小票机、标签机这类专用打印机,不需要走系统通用打印框架,直接按照设备厂商提供的安卓SDK,通过蓝牙或局域网Socket发送对应打印指令即可。
内容的提问来源于stack exchange,提问作者Bradley Rice
相关产品推荐
相关产品推荐

