Search code examples
bluetoothxamarin.androidzebra-printers

Zebra label printer in Mono for Android causes unexpected crash with no exceptions


I have created a Mono for Android application which uses the Zebra printing API. I have managed to get the ZSDK_API.jar file referenced in both a Java Bindings Library and a Standard Mono for Android application as defined HERE

  • I have added the .jar file to the JBL project (Jars folder) and set it's build action to InputJar
  • I also added the jar to the Mono for Android application with the build action set to AndroidJavaLibrary.

DiscoveryHandler

public class DiscoveryHandler : IDiscoveryHandler
{
    private Discovery _reference;

    public DiscoveryHandler(Discovery reference)
    {
        _reference = reference;
    }

    public void DiscoveryError(string message)
    {
        new UIHelper(_reference).showErrorDialogOnGuiThread(message);
    }

    public void DiscoveryFinished()
    {
        _reference.RunOnUiThread(() =>
        {
            Toast.MakeText(_reference, " Discovered " + _reference.discoveredPrinters.Count + " devices", ToastLength.Short).Show();
            _reference.SetProgressBarIndeterminateVisibility(false);
        });
    }

    public void FoundPrinter(DiscoveredPrinter printer)
    {
        _reference.RunOnUiThread(() => 
        {
            DiscoveredPrinterBluetooth p = (DiscoveredPrinterBluetooth)printer;
            _reference.discoveredPrinters.Add(p.Address + " (" + p.FriendlyName + ")");
            _reference.mArrayAdapter.NotifyDataSetChanged();
        }); 
    }

    public void Dispose()
    {

    }

    public IntPtr Handle
    {
        get { return _reference.Handle; }
    }
}

Discovery.cs

public class Discovery : ListActivity
{
    public List<string> discoveredPrinters = null;
    public ArrayAdapter<string> mArrayAdapter;
    private static IDiscoveryHandler btDiscoveryHandler = null;


    protected override void OnCreate(Bundle bundle)
    {
        base.OnCreate(bundle);
        RequestWindowFeature(WindowFeatures.IndeterminateProgress);
        SetContentView(Resource.Layout.discovery_results);

        SetProgressBarIndeterminateVisibility(true);
        discoveredPrinters = new List<string>();
        SetupListAdapter();
        btDiscoveryHandler = new DiscoveryHandler(this);

        try
        {
            new Thread(new ThreadStart(() =>
                {
                    Looper.Prepare();

                    try
                    {
                        RunOnUiThread(() => Toast.MakeText(this, "Trying", ToastLength.Short).Show());
                        BluetoothDiscoverer.FindPrinters(this, btDiscoveryHandler);
                        RunOnUiThread(() => Toast.MakeText(this, "And...", ToastLength.Short).Show());
                    }
                    catch (ZebraPrinterConnectionException zex)
                    {
                        new UIHelper(this).showErrorDialogOnGuiThread(zex.Message);
                    }
                    catch (ThreadInterruptedException iex)
                    {
                        new UIHelper(this).showErrorDialogOnGuiThread(iex.Message);
                    }
                    catch (Exception ex)
                    {
                        new UIHelper(this).showErrorDialogOnGuiThread(ex.Message);
                    }
                    finally
                    {
                        RunOnUiThread(() => Toast.MakeText(this, "Quitting looper", ToastLength.Short).Show());
                        Looper.MyLooper().Quit();
                        RunOnUiThread(() => Toast.MakeText(this, "Finished", ToastLength.Short).Show());
                    }
                })).Start();
        }
        catch (Exception ex)
        {
            new UIHelper(this).showErrorDialogOnGuiThread(ex.Message);
        }            
    }

    private void SetupListAdapter()
    {
        mArrayAdapter = new ArrayAdapter<string>(this, global::Android.Resource.Layout.SimpleListItem1, discoveredPrinters);
        ListAdapter = mArrayAdapter;
    }
}

I have made sure the manifest is requesting Bluetooth and Bluetooth_Admin as well as internet.

The application builds, but when run simply crashes, no exception and just says "The Application Has Stopped Unexpectedly"

All the classes are being detected and compiled, but I have no idea why it is bombing like this. Has anyone succeeded with a Mono for Android - Zebra integration?


Solution

  • Dammit - I am a chop! Just as I posted it I got to thinking - it probably has something to do with the fact that I was implementing IntPtr Handle as the parent's handle - I was right. Here is the first step of working code (FIRST STEP - if I have to answer my own questions!):

    public class Discovery : ListActivity, IDiscoveryHandler
    {
        public List<string> discoveredPrinters = null;
        public ArrayAdapter<string> mArrayAdapter;        
    
        protected override void OnCreate(Bundle bundle)
        {
            base.OnCreate(bundle);
            RequestWindowFeature(WindowFeatures.IndeterminateProgress);
            SetContentView(Resource.Layout.discovery_results);
    
            SetProgressBarIndeterminateVisibility(true);
            discoveredPrinters = new List<string>();
            SetupListAdapter();            
    
            try
            {
                new Thread(new ThreadStart(() =>
                    {
                        Looper.Prepare();
    
                        try
                        {                            
                            BluetoothDiscoverer.FindPrinters(this, this);                         
                        }
                        catch (ZebraPrinterConnectionException zex)
                        {
                            new UIHelper(this).showErrorDialogOnGuiThread(zex.Message);
                        }
                        catch (ThreadInterruptedException iex)
                        {
                            new UIHelper(this).showErrorDialogOnGuiThread(iex.Message);
                        }
                        catch (Exception ex)
                        {
                            new UIHelper(this).showErrorDialogOnGuiThread(ex.Message);
                        }
                        finally
                        {
                            RunOnUiThread(() => Toast.MakeText(this, "Quitting looper", ToastLength.Short).Show());
                            Looper.MyLooper().Quit();
                            RunOnUiThread(() => Toast.MakeText(this, "Finished", ToastLength.Short).Show());
                        }
                    })).Start();
            }
            catch (Exception ex)
            {
                new UIHelper(this).showErrorDialogOnGuiThread(ex.Message);
            }            
        }
    
        private void SetupListAdapter()
        {
            mArrayAdapter = new ArrayAdapter<string>(this, global::Android.Resource.Layout.SimpleListItem1, discoveredPrinters);
            ListAdapter = mArrayAdapter;
        }
    
        public void DiscoveryError(string message)
        {
            new UIHelper(this).showErrorDialogOnGuiThread(message);
        }
    
        public void DiscoveryFinished()
        {
            RunOnUiThread(() =>
            {
                Toast.MakeText(this, " Discovered " + discoveredPrinters.Count + " devices", ToastLength.Short).Show();
                SetProgressBarIndeterminateVisibility(false);
            });
        }
    
        public void FoundPrinter(DiscoveredPrinter printer)
        {
            RunOnUiThread(() =>
            {
    
                DiscoveredPrinterBluetooth p = printer.JavaCast<DiscoveredPrinterBluetooth>();
                discoveredPrinters.Add(p.Address + " (" + p.FriendlyName + ")");
                mArrayAdapter.NotifyDataSetChanged();
            }); 
        }
    }
    

    }