Xamarin Link-os iOS, Doesn't work without data connectivity. ZQ510

// Expert user has replied.
V Vladimir Araque 2 years 11 months ago
4 1 0

Regards,
I have been working on an app using Xamarin with Link-os plugin and ZQ510 printer. The idea of ​​the app is that it can work in remote places where there is no internet connectivity.
The debug printing process always works. The iPhone can print without any problem with the Wi-Fi off and the data access off.
When the iPhone is disconnected from the PC and has some kind of data access, it is capable of printing. You can even remove the SIM card and connect it to a Wi-Fi without internet access and it will be able to print.
The problem occurs in conditions where there is no Wi-Fi and the operator does not provide data coverage.
I have done many tests between them discovering all the bluetooth printers connected to the device and on the other hand hard coding connections to the printer and in all cases the common factor to fail is always the absence of a connection to a network or to another device. That is, when trying to reproduce the fault conditions in debug mode, the iPhone prints.
It makes me think that it is something related to the SDK itself. But I am not sure.
//**********************************************************
using BGTix.Interfaces;
using LinkOS.Plugin;
using LinkOS.Plugin.Abstractions;
using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Text;
using System.Threading.Tasks;
using Xamarin.Forms;
namespace BGTix.Clases
{
public class PrinteLinkOs
{
public enum ConnectionType
{
Bluetooth,
USB,
Network
}
ObservableCollection printerList;
string ticket;
public PrinteLinkOs()
{
printerList = new ObservableCollection();
}
public void PrintAll()
{
foreach (IDiscoveredPrinter IDP in printerList)
{
new Task(new Action(() =>
{
PrintLineMode(IDP);
})).Start();
}
}
public void PrintAllOff()
{
IConnection connection = null;
connection = ConnectionBuilder.Current.Build("BT:XXRAJ183403613");
connection.Open();
IZebraPrinter printer = ZebraPrinterFactory.Current.GetInstance(connection);
if ((!CheckPrinterLanguage(connection)) || (!PreCheckPrinterStatus(printer)))
{
ResetPage();
return;
}
SendZplReceipt(connection);
}
private void PrintLineMode(IDiscoveredPrinter IDP)
{
IConnection connection = null;
try
{
connection = IDP.Connection;
connection.Open();
IZebraPrinter printer = ZebraPrinterFactory.Current.GetInstance(connection);
if ((!CheckPrinterLanguage(connection)) || (!PreCheckPrinterStatus(printer)))
{
ResetPage();
return;
}
SendZplReceipt(connection);
}
catch (Exception ex)
{
// Connection Exceptions and issues are caught here
//ShowErrorAlert(ex.Message);
}
finally
{
if ((connection != null) && (connection.IsConnected))
connection.Close();
ResetPage();
}
}
private void ResetPage()
{
Device.BeginInvokeOnMainThread(() => {
//printBtn.IsEnabled = true;
});
}
protected bool PreCheckPrinterStatus(IZebraPrinter printer)
{
// Check the printer status
IPrinterStatus status = printer.CurrentStatus;
if (!status.IsReadyToPrint)
{
//ShowErrorAlert("Unable to print. Printer is " + status.Status);
return false;
}
return true;
}
protected bool CheckPrinterLanguage(IConnection connection)
{
if (!connection.IsConnected)
connection.Open();
// Check the current printer language
byte[] response = connection.SendAndWaitForResponse(GetBytes("! U1 getvar \"device.languages\"\r\n"), 500, 100);
string language = Encoding.UTF8.GetString(response, 0, response.Length);
if (language.Contains("line_print"))
{
//ShowAlert("Switching printer to ZPL Control Language.", "Notification");
}
// printer is already in zpl mode
else if (language.Contains("zpl"))
{
return true;
}
// Set the printer command languege
connection.Write(GetBytes("! U1 setvar \"device.languages\" \"zpl\"\r\n"));
response = connection.SendAndWaitForResponse(GetBytes("! U1 getvar \"device.languages\"\r\n"), 500, 100);
language = Encoding.UTF8.GetString(response, 0, response.Length);
if (!language.Contains("zpl"))
{
//ShowErrorAlert("Printer language not set. Not a ZPL printer.");
return false;
}
return true;
}
private void SendZplReceipt(IConnection printerConnection)
{
printerConnection.Write(GetBytes(ticket));
}
protected static byte[] GetBytes(string str)
{
byte[] bytes = new byte[str.Length];
bytes = Encoding.UTF8.GetBytes(str);
return bytes;
}
private Dictionary CreateListOfItems()
{
string[] names = { "Microwave Oven", "Sneakers (Size 7)", "XL T-Shirt", "Socks (3-pack)", "Blender", "DVD Movie" };
string[] prices = { "79.99", "69.99", "39.99", "12.99", "34.99", "16.99" };
Dictionary retVal = new Dictionary();
for (int ix = 0; ix names.Length; ix++)
{
retVal.Add(names[ix], prices[ix]);
}
return retVal;
}
/////
///// Start discovery on all ports. USB, then Bluetooth, then Network.
/////
public void StartPrinterDiscovery(string tkr)
{
ticket = tkr;
new Task(new Action(() => {
if (printerList != null && printerList.Count > 0)
{
printerList.Clear();
}
StartDiscovery(ConnectionType.Bluetooth);
})).Start();
}
private void StartDiscovery(ConnectionType connectionType)
{
UpdateStatus($"Discovering {connectionType.ToString()} printers...");
try
{
System.Diagnostics.Debug.WriteLine($"Starting {connectionType.ToString()} discovery...");
switch (connectionType)
{
case ConnectionType.Bluetooth:
DependencyService.Get().FindBluetoothPrinters(new DiscoveryHandlerImplementation(this, ConnectionType.Bluetooth));
break;
case ConnectionType.Network:
NetworkDiscoverer.Current.LocalBroadcast(new DiscoveryHandlerImplementation(this, ConnectionType.Network));
break;
case ConnectionType.USB:
DependencyService.Get().FindUsbPrinters(new DiscoveryHandlerImplementation(this, ConnectionType.USB));
break;
}
}
catch (Exception e)
{
if (e is NotImplementedException && connectionType == ConnectionType.USB)
{
StartDiscovery(ConnectionType.Bluetooth);
}
else
{
string errorMessage = $"Error discovering {nameof(connectionType)} printers: {e.Message}";
}
}
}
private void UpdateStatus(string message)
{
Device.BeginInvokeOnMainThread(() => {
//statusLbl.Text = message;
});
}
private class DiscoveryHandlerImplementation : IDiscoveryHandler
{
private PrinteLinkOs Paja;
private ConnectionType connectionType;
public DiscoveryHandlerImplementation(PrinteLinkOs paja, ConnectionType connectionType)
{
this.Paja = paja;
this.connectionType = connectionType;
}
public void DiscoveryError(string message)
{
if (connectionType == ConnectionType.USB)
{
//selectPrinterPage.StartDiscovery(ConnectionType.Bluetooth);
}
else if (connectionType == ConnectionType.Bluetooth)
{
//selectPrinterPage.StartDiscovery(ConnectionType.Network);
}
//else selectPrinterPage.UpdateStatus("Discovery finished");
}
public void DiscoveryFinished()
{
if (connectionType == ConnectionType.USB)
{
Paja.StartDiscovery(ConnectionType.Bluetooth);
}
else if (connectionType == ConnectionType.Bluetooth)
{
Paja.StartDiscovery(ConnectionType.Network);
}
else
{
Paja.UpdateStatus("Discovery finished");
if (Paja.printerList.Count > 0)
{
Paja.PrintAll();
}
else
{
Paja.PrintAllOff();
}
}
}
public void FoundPrinter(IDiscoveredPrinter discoveredPrinter)
{
Paja.printerList.Add(discoveredPrinter);
}
}
} //End class
}

Please register or login to post a reply

1 Replies

S Steven Si

Hi Vladimir,
The Link-OS Xamarin SDK provides API for application to use. The SDK itself doesn't create dependency on external connectivity. If your iOS application relies on data coverage in order for the app to work, then the data coverage is required. If your iOS application only needs Bluetooth to connect with the printer to print, then the data coverage is not required, provided the application already has the data to print.
The SDK provides API for WiFi & network connectivity. If your application doesn't use WiFi or network connectivity, the SDK won't bother to check on WiFi or network connection.
I'm a bit confused with what you said that the data coverage is required for the Xamarine SDK to work. 
Rgds.

CONTACT
Can’t find what you’re looking for?