Select to view content in your preferred language

Xamarin - Managing NmeaLocationDataSource when going into background

296
0
02-02-2023 09:46 AM
JoeHershman
MVP Regular Contributor

When an iOS application goes into background there are two conditions that can occur in regards to receiving location

  1. The user just goes to home screen or goes to another application that is not connected to the external gps device
  2. The user goes to an application that does connect to the external gps device.  This is a common occurrence if the user need to go into an application that connects to an NTrip server.

What I have observed is that in each of these condition is it seems different things happen to the underlying EASession associated to the EAAccessoryStream object

 

 

      public EAAccessoryStream(EAAccessory accessory, string protocol)
      {
        this._accessory = accessory;
        this._session = new EASession(accessory, protocol);
        this._session.InputStream?.Open();
        this._session.OutputStream?.Open();
      }

 

 

In case (1), the session is maintained in case (2) the EASession object would seem to be disposed.  The problem is that there is no way to know which case has occurred.

They way I have implemented things is that when the user returns to the application

 

//_sxblueAccessory is connected EAAccessory Protocal is the protocal string
_internaLocationDataSource = NmeaLocationDataSource.FromAccessory(_sxblueAccessory, Protocal);

_internaLocationDataSource.StartAsync();

 

 In case (2) above this works without issue. 

However, in case (1) you will get a "Starting" status changed followed by a "Failed to Start" status message.  In this case there is also an ErrorOccured notification sent with the following:

 

 

Could not initialize an instance of the type 'ExternalAccessory.EASession': the native 'initWithAccessory:forProtocol:' method returned nil.

It is possible to ignore this condition by setting ObjCRuntime.Class.ThrowOnInitFailure to false.

What appears to happen in this case is that when it tries to create the EAAccessoryStream is it throws this exception because there is already an existing EASession object being held by the NmeaLocationDataSource object.  This is somewhat conjecture just based on what I observe through a lot of logging and going through various scenarios in testing.  As there is no access to the underlying EASession it is hard to see in exactly what happening. 

So what would a best practice of how to manage the NmeaLocationDataSource when the app goes into background. 

What I am trying now is to call StopAsync when the app goes into background.  This allows just restarting everything without error when the app comes back into foreground.  This does seem to be working. 

Honestly, I am not too happy with this solution.  I think the location provider should be able to run in the background unless it is forced to stop because another app took over the connection to the external device.  However, I am unable to see anything that indicates which of the two scenarios has occurred to allow the application to restore in the correct way based on the different conditions.

Thanks,
-Joe
0 Kudos
0 Replies