jamesmontemagno / Xamarin.Plugins

Cross-platform Native API Access from Shared Code!
MIT License
1.3k stars 380 forks source link

[crash] GeoLocator WinPhone8.1 / Geolocator does not stop #242

Closed maurikke closed 8 years ago

maurikke commented 8 years ago

Please take a moment to fill out the following (change to preview to check or place x in []):

This is a

Which plugin does this impact:

Version Number of Plugin: Device Tested On: Simulator Tested On:

Expected Behavior

That I can start and stop the Geolocator with the functions StartListeningAsync() and StopListeningAsync()

Actual Behavior

The Geolocator does not stop after calling StopLiseningAsync. An exception is thrown in the Windows GeoLocator with the second start.

Steps to reproduce the Behavior

use the following code:

IGeolocator o = CrossGeolocator.Current;

o.StartListeningAsync(0,10).Wait(); o.StopListeningAsync().Wait(); // geolocator incon still active on screen o.StartListeningAsync(0, 10).Wait(); // crash on loc.ReportInterval = (uint)minTime; in the public // Task StartListeningAsync(int minTime, double minDistance, bool includeHeading = false) method.

Probable cause: Both problems (does stop and crash) seam related to the fact to in the StopListeningAsync() there is no removal of the loc.StatusChanged event handler. When this event is unsubscribed everything seams to work fine.

maurikke commented 8 years ago

Typo: loc.StatusChanged should be locator.StatusChanged.

jamesmontemagno commented 8 years ago

you should never call .Wait() on a async method, ever.

can you try: await o.StartListeningAsync(1000,10); await o.StopListeningAsync(); await o.StartListeningAsync(1000, 10);

maurikke commented 8 years ago

Even with the await the problem remains the same. This problem has nothing to do with async behavior.

jamesmontemagno commented 8 years ago

Are you Win Phone 8.1 RT or Silverlight?

jamesmontemagno commented 8 years ago

Additionally you should do:

if(!o.IsListening)
  await o.StartListeningAsync(1000,10);

if(o.IsListening)
    await o.StopListeningAsync();

if(!o.IsListening)
    await o.StartListeningAsync(1000, 10);

Also, why are you calling them back to back like this? Is this just a sample or are you calling them all three in a row as that doesn't make a lot of sense.

maurikke commented 8 years ago

I tried to investigate the problem and minimize the code to show the problem. I made the problem reproducible with only 4 lines of code. Just so that you don't need to read so much :)

To my shame: I cannot tel you if I use RT or Siverlight. How can I see this? I created a Xamarin shared forms project, and i'm using the windows phone 81. project, not the windows or the universal windows project. I cannot see a refrence to either WinRT or Silverlight in my project settings. But maybe i'm looging on the wrong place. :)

The tests of IsListening are already handeled in your library (throwing an exception or return true). In this case they are beside the point, see example below. Futhermore: The IsListening properties is controlled by your library and it will say that the geolocatoes is not listening even when the phone indicates that the location service is still active.

Actually I wrote a test program without your plug-in library that uses the winphone geolocator device directly and if a place there the code that is now in the start and stop method of your library it also reproduces:

Windows.Devices.Geolocation.Geolocator o = new Windows.Devices.Geolocation.Geolocator();
o.ReportInterval = 10; / this works fine o.PositionChanged += PositionChangedHandler; o.StatusChanged += StatusChangedHandler;

// do something

//o.PositionChanged -= PositionChangedHandler; // do not unsubscribe one of the events. o.StatusChanged -= StatusChangedHandler;

//do something

o.ReportInterval = 10; //crash

And it goes wrong by multiple properties (ReportInterval, MovementThreshold)

Only6 when both events are unsubscribed, it is possible to change these properties, and the phone indicates that your appe is not using the GPS/location service.

In your library the Statuschanged event is not 'released', which causes the problem.

In my real application I want the location services only available when a certain page is active. That's why I activate and deactivate the geolocator. In android this works without problems, iOS I did not test yet, and winphone show the behavior as written above.

maurikke commented 8 years ago

I tried it on Silverlight and on WinRT: only the winRT version crashes, in Silverlight it works as expected.

jamesmontemagno commented 8 years ago

There was PR to fix this in alpha2