8 Replies Latest reply on Feb 12, 2018 6:31 PM by John Ferlazzo

    getCurrentStatus error on iOS 11.2.2 on Zebra iMZ320 with Xamarin

    Nicola Lazzara

      Hi to all,

      I've an application devoloped with Xamarin.Forms that use an Ipad for device. I can print all before the last update of ios version (with ios 11.2.1 i can print all very well). With the last update, my printer doesn't print, the error in "Malformed Status"

       

      I use LinkOS_Xamarin_SDK 1.1.75. The error is systematic on the method that check the printer status .. I think it's something similar to what is shown here :

       

      https://developer.zebra.com/community/technologies/printers/label-printers/blog/2017/11/01/ios-11-bluetooth-disconnectio…

       

      and here :

       

      iMZ320 in iOS:Sometimes getCurrentStatus shows ErrorCode=7

       

      i'm sure that only one device is connected with the printer. Please someone can tell me a solution to get around the problem (i try to remove the call on method for the printer status, but error still persist. Expetion is throwning on the following line in bold :

       

              public bool CheckPrinterStatus(IConnection connection)

              {

                  IZebraPrinter printer = ZebraPrinterFactory.Current.GetInstance(PrinterLanguage.ZPL, connection);

                  IPrinterStatus status = printer.CurrentStatus;

       

                  if (!status.IsReadyToPrint)

                  {

                      //Log.Debug(tag, "Printer in Error: " + status.ToString());

                      string error = "Printer in Error: " + status.ToString();

                  }

                  return true;

              }

       

       

      Thanks in advance.

        • Re: getCurrentStatus error on Ios 11.2.2 on Zebra iMZ320
          Nicola Lazzara

          The problem remains the same even on version 11.2.5 of ios.

           

          Someone have a solution or workaround?

            • Re: getCurrentStatus error on Ios 11.2.2 on Zebra iMZ320
              John Ferlazzo

              Hi Nicole,

               

              This may be similar to the issue in Code no longer works using Xamarin LinkOS to print to ZQ510 via Bluetooth on iPad

              You can check that you are not opening any connections and communicating with the printer on the main thread. Try to keep everything in one separate thread (Open connection, get printer instance/status and write to connection).

                • Re: getCurrentStatus error on Ios 11.2.2 on Zebra iMZ320
                  Nicola Lazzara

                  Hi john thanks for your help, but dosen't work for me.

                   

                  My code is this :

                   

                  When i click on print button my code is :

                   

                              bool isPrintOK = await CheckPrinterStatus();

                   

                   

                              if (!string.IsNullOrEmpty(address))

                              {

                                  if (isPrintOK)

                                  {

                                     

                                      myZpl = myHelper.BuildPrintTemplate();

                   

                                      var printingTask = Task<bool>.Factory.StartNew(() =>

                                      {

                                          PrinterHelper myPrinterHelper = new PrinterHelper();

                                          myPrinterHelper.Print2(address, myZpl);

                                          return App.printingOK;

                                      });

                                      printingTask.Wait();

                  }

                  }

                   

                  The first problem is on CheckPrinterStatus() call;

                   

                  After your response i changed with this logic :

                   

                   

                          public static void CheckPrinter(string address)

                          {

                              bool connectionOK = false;

                              bool statusValid = false;

                              string _messagePaper = string.Empty;

                              string _messageHeadOpen = string.Empty;

                              string _messageSleepingMode = string.Empty;

                   

                   

                              var t = Task.Run(() =>

                              {

                                  try

                                  {

                                      IConnection connectionCheckStatus = ConnectionBuilder.Current.Build("BT:" + address);

                                      connectionCheckStatus.Open();

                   

                   

                                      if (connectionCheckStatus.IsConnected)

                                      {

                                          connectionOK = true;

                   

                   

                                          IZebraPrinter printer = ZebraPrinterFactory.Current.GetInstance(PrinterLanguage.ZPL, connectionCheckStatus);

                   

                   

                                          IPrinterStatus status = printer.CurrentStatus;

                   

                   

                                          if (status != null)

                                          {

                                              statusValid = true;

                   

                   

                                              if (status.IsPaperOut)

                                                  _messagePaper = "\n Attention, paper on printer is Ended, please insert before continue";

                   

                   

                                              if (status.IsHeadOpen)

                                                  _messageHeadOpen = "\n Attetion, printer cover is not closed, please close cover before continue";

                   

                                          }

                                          else

                                          {

                                              _messagePaper = string.Empty;

                                              _messageHeadOpen = string.Empty;

                                              _messageSleepingMode = string.Empty;

                                              statusValid = false;

                                          }

                   

                   

                                      }

                                      else

                                      {

                                          connectionOK = false;

                                      }

                                  }

                                  catch(Exception ex)

                                  {

                                     

                                  }

                                  finally

                                  {

                   

                   

                                  }

                              });

                   

                   

                              t.Wait();

                   

                   

                              if(!connectionOK || !statusValid)

                              {

                                  App.messagePaper = string.Empty;

                                  App.messageHeadOpen = string.Empty;

                                  App.messageSleepingMode = string.Empty;

                                  App.printerStatusValid = statusValid;

                                  App.printerConnection = connectionOK;

                              }

                              else

                              {

                                  App.messagePaper = _messagePaper;

                                  App.messageHeadOpen = _messageHeadOpen;

                                  App.messageSleepingMode = _messageSleepingMode;

                                  App.printerStatusValid = statusValid;

                                  App.printerConnection = connectionOK;

                              }

                          }

                   

                  This is the situation at run time :

                   

                  Check_1.png

                   

                  And when start printer.CurrentStatus call, the result is this :

                  Check_2.png

                   

                   

                  I try to ingnore this excption and continue the execution of code. So i start a new thread for printig (called printingTask) as you can see and wait in main thread the response. This is Print2 method :

                   

                          public void Print2(string address, string myZpl)

                          {

                              string zpl = myZpl;

                   

                   

                              try

                              {

                                  var t = Task.Run(() =>

                                  {

                                      try

                                      {

                                          IConnection connectionPrint = ConnectionBuilder.Current.Build("BT:" + address);

                                          connectionPrint.Open();

                   

                   

                                          if ((SetPrintLanguage(connectionPrint)) && (CheckPrinterStatus(connectionPrint)))

                                          {

                                              connectionPrint.Write(Encoding.UTF8.GetBytes(zpl));

                                              App.printingOK = true;

                                          }

                                          else

                                              App.printingOK = false;

                                      }

                                      catch (Exception ex)

                                      {

                                          App.printingOK = false;

                                      }

                                  });

                                  t.Wait();

                              }

                              catch (Exception e)

                              {

                                  //if the device is unable to connect, an exception is thrown

                                  PrinterExceptions myPrinterExcepiton = new PrinterExceptions();

                                  string error = e.ToString();

                                  App.printingOK = false;

                              }

                              finally

                              {

                              }

                          }

                   

                  And this is SetPrintLanguage and check printer status method :

                   

                          private bool SetPrintLanguage(IConnection connection)

                          {

                   

                              string setLanguage = string.Format("! U1 setvar \"device.languages\" \"zpl\"\r\n\r\n! U1 setvar \"formats.cancel_all\" \"\"\r\n\r\n!U1 setvar \"ezpl.media_type\" \"continuous\"\r\n\r\n! U1 setvar \"media.type\" \"journal\"\r\n\r\n! U1 getvar \"device.languages\"\r\n\r\n");

                   

                   

                              byte[] response = connection.SendAndWaitForResponse(Encoding.UTF8.GetBytes(setLanguage), 1000, 1000);

                              string s = Encoding.UTF8.GetString(response, 0, response.Length);

                              if (!s.Contains("zpl"))

                              {

                                  string error = "Not a ZPL printer.";

                                  return false;

                              }

                              return true;

                          }

                   

                          public bool CheckPrinterStatus(IConnection connection)

                          {

                              bool returnValue = false;

                              try

                              {

                                  if (connection.IsConnected)

                                  {

                                      IZebraPrinter printer = ZebraPrinterFactory.Current.GetInstance(PrinterLanguage.ZPL, connection);

                                      IPrinterStatus status = printer.CurrentStatus;

                   

                                      if (!status.IsReadyToPrint)

                                      {

                                          string error = "Printer in Error: " + status.ToString();

                                      }

                                      else

                                      {

                                          returnValue = true;

                                      }

                                  }

                                  else

                                  {

                                      string connectionLose = "no connection available with printer";

                                  }

                              }

                              catch(Exception ex)

                              {

                                  string message = ex.Message;

                                  returnValue = false;

                              }

                              return returnValue;

                          }

                   

                  On call on "connection.SendAndWaitForResponse" .. system go in exception (connection is ok as you can see) : Print_2_step1.png

                   

                  Print2_step2.png

                   

                  I think I have correctly replicated the logic to put checks and printing on the same task, but as you can see I still can not print. Am I doing something wrong?

                    • Re: getCurrentStatus error on Ios 11.2.2 on Zebra iMZ320
                      Steven Si

                      Here are the recommendations for using Link-OS SDK API, including Xamarin SDK.

                      1. As a best pracitce, Zebra recommends not making calls to our API from the GUI thread. Use a seperate Thread or Task to accomplish this.
                      2. Each ZebraPrinter object should only be used on a single thread

                      By following the recommendations, a lot of failures can be avoided. In the above code, the Task.Run() and Task.Wait() are used, which sounds like that a GUI thread is held until the Task.Run() finishes. Can we try using new Thread.run() or new Task() to spawn a thread or task to run on itself without synchronizing with the GUI thread? Hope this helps.

                        • Re: getCurrentStatus error on Ios 11.2.2 on Zebra iMZ320
                          Nicola Lazzara

                          Hi Steven, I thank you for your availability, I also tried putting the "new" on the print thread (or on the thread to check the status of the printer), although in reality use Task.Run is the implicit way to instantiate a new task, the error remains exactly the same. I repeat that until the ios 11.2.1 version I was able to print successfully. Is your development team with the configuration I use able to print with a Zebra printer?

                           

                          my application has been developed in xamarin.forms (pcl), the reference device is an ipad (with now the IOS version 11.2.5 installed). The version of the Zebra plugin for printing that I use is as follows: "LinkOS_Xamarin_SDK 1.1.75", while the firmware installed on the printer is this: "V73.20.10.10Z".

                           

                           

                          Currently the release of the application is likely not to be successful if you can not print.

                           

                           

                          Thank you for your kind attention

                           

                          Nicola

                            • Re: getCurrentStatus error on Ios 11.2.2 on Zebra iMZ320
                              Steven Si

                              Hi Nicola,

                               

                              Here is a simple program that prints out a barcode on iMZ320 (with V73.20.10Z). It demonstrates the flow of creating a connection, checking status and printing label. I verified that it works on iOS 11.2.5 and iMZ320 with LinkOS_Xamarin_SDK 1.1.75. You will need to change the namespace and the printer serial number in the code to match with yours. You may disable your code that related to Zebra SDK API. Simply plug in the below code and assign a button to Print() function. Hope this helps for debugging your code further.

                               

                              using LinkOS.Plugin;
                              using LinkOS.Plugin.Abstractions;
                              using System;
                              using System.Threading;
                              using System.Text;
                              using Xamarin.Forms;
                              
                              namespace HelloWorld // Update the namespace to yours
                              {
                                  public class LabelPrintTest
                                  {
                                      public LabelPrintTest() { }
                              
                                      public void Print()
                                      {
                                          new Thread(printLabel).Start(); // Run a background thread for print and print related.
                                      }
                              
                                      public void printLabel()
                                      {
                                          string message = "";
                                          IConnection connection = null;
                              
                                          try
                                          {
                                              connection = ConnectionBuilder.Current.Build("BT:XXXXJ134101571"); // iMZ320. Change it to the Serial Number of yours.
                                              connection.Open();
                                              IZebraPrinter printer = ZebraPrinterFactory.Current.GetInstance(PrinterLanguage.ZPL, connection);
                                              IPrinterStatus status = printer.CurrentStatus;
                              
                                              if (status.IsReadyToPrint) {
                                                  String testLabel1 = @"^XA^FO20, 10^BY2^BEN,70,Y,N^FD8033609249442^FS^XZ";
                                                  connection.Write(Encoding.UTF8.GetBytes(testLabel1));
                                              }
                                          }
                                          catch (Exception e)
                                          {
                                              message = "Exception: " + (e.Message);
                                          }
                                          finally
                                          {
                                              if ((connection != null) && (connection.IsConnected))
                                              {
                                                  connection.Close();
                                              }
                                          }
                                      }
                                  }
                              }
                              
                                • Re: getCurrentStatus error on Ios 11.2.2 on Zebra iMZ320
                                  Nicola Lazzara

                                  thanks steve, you have been very kindly, but I would like to ask you how to handle the possibility of waiting for the end of the printing process so you can notify if it was successful or not.

                                   

                                  if i write this code :

                                   

                                                      Task myPrintTask = new Task(Print);                 

                                                      myPrintTask .Start();

                                                      myPrintTask .Wait();

                                   

                                  the code go in catch on printer.GetStatus .. meanwhile if i call Print with this :

                                   

                                  newTask(Print) .. print is ok, but main thread  continues its execution without waiting for the printing process