Zebra打印集成實踐
目的
Zebra ISV 技術團隊多年來一直與開發人員合作。該小組提供開發人員支持和測試服務。我們根據我們經常看到的常見問題創建了這些最佳實踐。我們希望為開發人員提供以下方面的指導:
-
我們已經多次看到的常見性能和穩定性錯誤。
-
如何為客戶創造最佳的用戶體驗。
-
如何最好地利用 Zebra 的增值功能
由于我們最初發布了最佳實踐來幫助避免其中一些問題,因此測試失敗的數量已經減少,并且我們收到了更多關于如何實施它們的問題。本文檔試圖改進原始文檔并使其更易于使用它們進行開發。
誰應該使用這個
本文檔有幾個主要受眾。
-
軟件開發人員編寫代碼以打印或管理 Zebra 打印機。
-
測試工程師正在尋找測試涉及 Zebra 打印機的應用程序的最佳方法。
-
用戶體驗工程師在涉及打印時尋求提供更好的建議。
-
希望讓 Zebra 對其軟件進行驗證的 Zebra 合作伙伴。
本文檔的組織方式
每個部分都有最佳實踐的名稱和描述。接下來是針對開發人員的“如何做”部分和針對測試人員的“如何測試”部分。任何一個部分都可能有代碼片段或其他注釋來詳細說明如何實現每個部分。
本文檔中的代碼示例使用 Java for Android,假設使用 Link-OS 多平臺 SDK 并使用 ZPL 打印語言。您可以使用幾乎任何操作系統的幾乎任何編程語言、任何 Zebra 打印機、任何打印頁面描述語言(無論是否使用 SDK)實施這些最佳實踐。SDK 使它更容易。此處的示例代碼僅作為示例,可能需要進行調整以適合您的用例。可以在 Zebra Github 存儲庫中找到更多實施最佳實踐的示例。如果您有實施方面的問題,請在 Zebra開發人員門戶中提問。
在線開發文檔: https://techdocs.zebra.com/link-os/
斑馬樣例庫:https://github.com/Zebra
1. 開箱即用
您的應用程序應與您指定的 Zebra 打印機一起使用。如果打印機是全新的開箱即用,它應該可以與該打印機一起使用。并非所有打印機都具有相同的默認行為。默認設置可能無法滿足您的應用程序的需要。
怎么做:
-
設置正確的連接(TCP、Cloud Connect、BT、BTLE、USB 等)
注意:可以在API 文檔中找到不同連接類型的示例。http://techdocs.zebra.com/link-os/
-
設置正確的 Zebra 打印頁面描述語言(ZPL、CPCL、line_print、PDF 等)
注意:請參閱頁面描述語言部分中的代碼示例。
-
設置標簽和打印設置(打印速度、濃度、標簽寬度、長度等) 代碼
注意:有關 SGD(Set-Get-Do)設置的完整列表,請參閱ZPL 編程指南。建議您為您的用戶提供一個界面,以便在您的應用中為他們的打印機調整這些設置。您可能希望根據這些設置調整打印輸出。要在打印機中設置它們,您可以使用前面的代碼。另請參閱Developer Portal上的博客。

-
(可選 - 如果需要)設置遠程管理設置(連接器、鏡像、配置文件管理器)
注意:有關在打印機中設置 Cloud Connect、連接器和 Profile Manager 的信息,請參閱有關 Weblink 命令的ZPL 編程指南。有關通過打印機上的 FTP 設置打印機管理的信息,請參閱鏡像部分。
-
(可選 - 如果需要)設置特殊功能(ZBI、虛擬設備等)
-
(可選 - 如果需要)驗證打印機固件版本 代碼

-
驗證是否滿足以下部分的最佳實踐
如何測試它:
-
獲取新打印機或將打印機默認為出廠規格。按照以下頁面上的安裝驅動和設置應用程序。
https://www.zebra.cn/cn/zh/support-downloads/printer-software/printer-setup-utilities.html
-
有幾種方法可以默認 Zebra 打印機,但一種常見的方法是使用 Setup Utility 軟件。
-
安裝設置實用程序 Setup Utility軟件
-
連接到打印機
-
選擇打印機工具
-
在“操作”下,選擇“加載出廠默認值”
-
2. 穩定性
嘗試打印時,應用程序不應崩潰或凍結。這包括在未通知用戶原因的情況下無法打印。
怎么做:
-
始終在 UI 以外的線程上與打印機通信。
-
始終圍繞任何打印機通信使用 try/catch 語句。
-
完成打印后關閉打印機連接。
相關代碼如下
public class PrintTask extends AsyncTask{
protected void backgroudPrint(Void... params){ // Instantiate connection for ZPL TCP port at given address Connection printerConnection = new TcpConnection(theIpAddress, TcpConnection.DEFAULT_ZPL_TCP_PORT); try { // Open the connection - physical connection is established here. printerConnection.open(); // Set settings, check status, print, etc. } catch (ConnectionException e) { // Handle communications error here. e.printStackTrace(); } finally { try { // Close the connection to release resources. printerConnection.close(); } catch (ConnectionException ec) { // Handle connection close error here.
如何測試它:
-
在運行應用程序時,在此過程中隨機關閉打印機。驗證應用程序不會崩潰或掛起。
-
在不同的時間打開它。確保應用程序仍然穩定并通知連接問題。
3. 安全
與打印機的通信應被視為潛在的安全風險。遵循您的組織或客戶的安全最佳實踐。默認情況下,打印機對大多數通信開放。
怎么做:
-
盡可能使用與打印機的安全通信方法,從藍牙安全級別到使用 Wi-Fi 證書和 HTTPS 通信。
-
關閉您不打算使用的通信方法。詢問您需要支持的特定協議/系統。
-
不要將個人信息作為存儲格式或存儲圖像的一部分
注意:更完整的安全最佳實踐集即將發布
如何測試它:
-
假設與打印機的通信存在潛在的安全風險并進行相應的測試。
請參閱從此處開始的SGD 通信命令。
-
假設存儲在打印機中的所有數據(密碼、證書和其他已知的安全文件和設置除外)都可以提取并進行相應的測試。
請參閱 ZPL 命令^HF、^HG和 SGD file.type
4. 格式化輸出
客戶希望他們的打印輸出易于閱讀和掃描。他們還希望自己的品牌引人注目。
怎么做:
-
盡可能使用 ZPL 打印頁面描述語言。
注意:請參閱頁面描述語言部分中的代碼示例。
-
應至少使用圖像,尤其是那些包含條形碼的圖像。圖像使用大量數據,因此打印速度較慢。條形碼在轉換為圖像時有時會失真。如果您必須使用圖像,請確認 DPI 與打印機相同。
-
使用設計工具來幫助創建標簽格式。查看Zebra Designer應用程序或聯系我們的設計合作伙伴之一
-
根據客戶反饋選擇介質(紙張或標簽紙)。我們推薦Zebra 認證耗材以獲得最佳打印質量和打印機壽命。
-
使用Setup Utility應用程序設置打印機的打印質量并在您的應用程序中設置相同的設置。
-
適當設置打印濃度。如果條形碼是要讀取的最重要的數據,請將暗度設置為比讀取文本的最佳值更亮。考慮為較淺的文本使用粗體。
如何測試它:
-
該應用程序以可接受的打印質量產生預期的打印輸出。
-
條形碼應為 B 級或更高。條碼分級是使用條碼驗證工具完成的。這確保了條形碼的可掃描性。如果您沒有,我們可以與您合作以確保您的條形碼是可掃描的。
-
打印輸出不應超出頁面、太小而無法閱讀或間距太緊
最佳
5.頁面描述語言
Zebra 打印機支持多種不同的格式化語言。不同的打印機使用不同的默認格式語言。
怎么做:
-
設置您打算在 SDK 中使用的頁面描述語言。

-
設置您打算在打印機中使用的頁面描述語言。這是兩個不同的步驟。有關選項,請參閱ZPL 指南。
-

-
驗證語言是您想要的,因為并非所有打印機都支持所有命令語言。 見上面的代碼.
注意:推薦使用 ZPL,因為:
-
這是 Zebra 致力于不斷改進的語言。大多數其他語言僅支持用于錯誤修復。
-
它是具有最佳字體和本地化功能的語言。
-
它是幾乎每臺 Zebra 打印機都附帶的一種語言,因此您可以從一臺打印機切換到另一臺打印機,而無需更改您的應用程序。
-
如何測試它:
-
使用您打算支持的不同打印機型號進行測試。
-
更改頁面描述語言并確認應用程序仍然有效。驗證打印機接受更改。
使用設置實用程序設置和驗證頁面描述語言。有關選項,請參閱ZPL 指南。
-
在 Android 上 - 選擇“設備語言”,然后選擇“設置設備語言”以將語言選擇為“ZPL”。選擇“應用”并驗證顯示的“當前設備語言”。
-
在 PC 上 - 選擇“打開與打印機的通信”。在頂部框中輸入:
! U1 setvar "device.languages" "zpl"
! U1 getvar "device.languages"點擊輸入。換行符非常重要,并且完全如圖所示使用直雙引號。單擊“發送到打印機”兩次。在大多數 ZPL 打印機上,響應應該是:“hybrid_xml_zpl”。
-
安裝設置實用程序軟件
-
連接到打印機
-
設置頁面描述語言
-
在您的應用程序中測試打印。
-
將設備語言更改為“line_print”并驗證,如步驟 3 所示。
-
在您的應用程序中測試打印。
-
最佳
6.狀態
狀態將告訴您打印機是否準備好打印或處于錯誤狀態。
怎么做:
-
打印前檢查打印機的狀態,確保打印機處于準備打印狀態。

-
檢查打印期間和打印后的狀態,以確保打印成功。

-
另一種選擇是使用打印機警報系統。可以將打印機設置為在打印機進入錯誤狀態時在特定端口上發送通知。這對于始終連接到打印機的服務器端應用程序(24/7 用例)最有用。
-
建議應用程序等待發送打印作業,直到清除所有錯誤。
-
提供在打印過程中出現的錯誤重印。
-
狀態通道是檢查狀態的首選方法。這應該會提高性能。

-
您還可以使用打印機里程表檢查打印是否完成。這可能比此驗證的狀態檢查更準確,但也可能沒有必要。

如何測試它:
-
打印前,打開介質門或取出紙張。
-
在打印過程中,打開介質門。
這些問題是否會導致應用不穩定?
-
驗證以下內容:
-
媒體門打開
-
出紙
-
打印機無法訪問(關閉或斷開連接/超出范圍)。
-
色帶輸出
-
打印頭太熱(高濃度、高速、大量黑色)
-
暫停
-
接收緩沖區已滿(快速發送多個作業)
-
7. 顯示打印機錯誤狀態
應提醒用戶注意打印機的狀態問題。他們不應該查看打印機來發現這一點。
怎么做:
-
檢查狀態時,提醒用戶您的應用程序中打印機上發生的確切錯誤。
在 Android 中,您可以使用 Toast、Java 和 C# - ShowDialog 等……
如何測試它:
-
在測試狀態問題時,應用程序是否會以明確的最終用戶語言提醒用戶,確切的打印機問題是什么?
驗證以下狀態:
-
媒體門打開
-
出紙
-
打印機無法訪問(關閉或斷開連接/超出范圍)。
-
色帶輸出
-
打印頭太熱(高濃度、高速、大量黑色)
-
暫停
-
接收緩沖區已滿(快速發送多個作業)
-
8. 性能
打印機性能是根據幾個因素來衡量的。打印時間(用戶激活打印操作和打印機開始打印之間的時間)和移動打印機電池壽命是受軟件交互影響的一些最重要的性能問題
怎么做:
-
使用打印頁面描述語言來優化性能,如果可能避免使用圖形,我們建議使用模板或格式。有關格式打印的詳細信息,請參閱API 參考。
-
RFID 編碼或 BTLE 連接 -
-
不要以每種格式發送內聯圖形。
-
使用打印頁面描述語言而不是圖像進行打印。
-
將圖形和格式存儲在打印機中,以最少的數據傳輸進行調用。
-
-
在移動打印機中,設置睡眠模式并關閉連接以節省電池壽命。并非在所有打印機上都可用

-
使用狀態通道優化打印時間。有關詳細信息,請參閱狀態部分。
-
為了快速連接和配對,您可以使用 NFC(打印觸摸)或掃描進行連接。 示例代碼
-
使用虛擬設備時,請確認虛擬設備正在打印機上運行。示例代碼
如何測試它:
-
可接受的打印時間取決于您的用例。
-
電池壽命健康通過充電循環計數來衡量。
要檢查您的電池健康狀況,請使用Setup Utility軟件。使用命令檢查:
! U1 getvar "power.health"后跟 Enter
• 如果 power.cycle_count < 300 且容量比(實際容量與
設計容量的比率)大于或等于 0.80,則運行狀況為“良好”。
• 如果power.cycle_count 介于300 和600 之間,則運行狀況為“replace”。如果# of Cycles < 550 但> 300,
打印機將顯示一條消息“請更換電池組”,然后發出三聲嗶聲。如果
充電周期數≤550 但< 600,則提示應為:“警告 - 電池已過
使用壽命”,然后發出三聲嗶嗶聲。
• 如果power.cycle_count 大于600,則運行狀況為“差”。打印機將閃爍一條消息:“請在繼續
之前更換電池– 關機”并伴隨30 秒的嗶嗶聲,
然后關閉。
常問問題
如果……我該怎么辦?
我的應用程序在與打印機通信時崩潰了?
如果您認為應用程序崩潰是因為您正在與打印機通信:
-
設備可能因為超出范圍或打印機關閉而無法通信,因此會引發異常。確保與打印機的所有通信都在 try/catch 語句中。
public class PrintTask extends AsyncTask{ protected void backgroudPrint(Void... params){ // Instantiate connection for ZPL TCP port at given address Connection printerConnection = new TcpConnection(theIpAddress, TcpConnection.DEFAULT_ZPL_TCP_PORT); try { // Open the connection - physical connection is established here. printerConnection.open(); // Set settings, check status, print, etc. } catch (ConnectionException e) { // Handle communications error here. e.printStackTrace(); } finally { try { // Close the connection to release resources. printerConnection.close(); } catch (ConnectionException ec) { // Handle connection close error here. ec.printStackTrace(); } } } }
-
驗證您具有適當的通信權限(請參閱文檔)
-
與打印機通信有時需要一些時間,有時需要幾秒鐘。將其作為一項長期運行的任務來處理。始終在 UI 以外的線程上與打印機通信。(見上面的代碼)
如果您擔心未打印打印作業:
-
要驗證打印作業是否已發送和打印,有兩個選項。結合使用,它們可以在關鍵任務打印應用中為您提供幫助:
-
在打印過程中檢查打印狀態 代碼
-
跟蹤打印機中的里程表以檢查打印的標簽。 代碼
-
如果……我該怎么辦?
我的打印機不打印或不打印我想要的內容?
-
檢查并顯示打印機狀態。打印機可能處于無法打印的良好狀態。
// Check during / after printing private boolean postPrintCheckPrinterStatus(Connection connection) { ZebraPrinter printer = ZebraPrinterFactory.getLinkOsPrinter(connection, PrinterLanguage.ZPL); if (null == printer) { printer = ZebraPrinterFactory.getInstance(PrinterLanguage.ZPL, connection); } PrinterStatus printerStatus = printer.getCurrentStatus(); // loop while printing until print is complete or there is an error while ((printerStatus.numberOfFormatsInReceiveBuffer > 0) && (printerStatus.isReadyToPrint)) { Thread.sleep(500); printerStatus = printer.getCurrentStatus(); } if (printerStatus.isReadyToPrint) { System.out.println("Ready To Print"); return true; } else if (printerStatus.isPaused) { System.out.println("Cannot Print because the printer is paused."); } else if (printerStatus.isHeadOpen) { System.out.println("Cannot Print because the printer head is open."); } else if (printerStatus.isPaperOut) { System.out.println("Cannot Print because the paper is out."); } else { System.out.println("Cannot Print."); } return false; }
-
驗證頁面描述語言是否設置為您想要的。
// Set settings, check status, print, etc. if (setPrintLanguage(statusConnection) && checkPrinterStatus(statusConnection)) { int labelCount = Integer.parseInt(SGD.GET("odometer.total_label_count", statusConnection)); // Send Print Job (1 label) String zplData = "^XA^FO20,20^A0N,25,25^FDThis is a ZPL test.^FS^XZ"; printerConnection.write(zplData.getBytes()); if (postPrintCheckPrinterStatus(statusConnection)) { int newLabelCount = Integer.parseInt(SGD.GET("odometer.total_label_count", statusConnection)); if (newLabelCount == labelCount + 1) { System.out.println("Print Successful."); } } //else reprint? }
-
驗證您在應用程序中具有適當的通信權限(請參閱文檔)
-
驗證您的 ZPL 是否正確
-
使用打印機網頁預覽
-
通過第三方網頁預覽http://labelary.com/viewer.html
-
使用ZebraDesigner等標簽設計工具設計您的標簽。
-
-
校準打印機(ZPL 命令^JC,或查看您的特定打印機用戶指南)
-
驗證濃度、標簽尺寸和其他設置是否正確(請參閱設置實用程序)
最佳
如果……我該怎么辦?
打印需要很長時間?
-
打印最慢的部分往往是數據傳輸速度。要優化這一點,請通過以下方式減少發送到打印機的數據量:
-
使用頁面描述語言
-
避免使用圖形并確認必要的圖形很小
-
使用模板或存儲格式(參見Github上的代碼)
-
-
使用狀態通道檢查狀態和設置
// With Bluetooth you have to open a raw connection before opening a status connection. Connection btConnection = new BluetoothConnection(theBtMacAddress); btConnection.open(); Connection btStatusConnection = new BluetoothStatusConnection(theBtMacAddress); // or Connection nwStatusConnection = new TcpStatusConnection(theIpAddress, TcpStatusConnection.DEFAULT_STATUS_TCP_PORT);
-
將打印速度設置為不影響打印質量的最快設置。
-
如果您要在短時間內打印多個作業,請不要在每次打印后關閉連接。使用計時器來決定何時關閉連接



