I finally found an answer to a sticky problem in my book’s Here My Am! app. The problem is that sometimes, on first launch, the Windows.Devices.Geolocation.Geolocator.getGeopositionAsync call fails even when I tap “Allow” in the consent dialog.

That is, in my startup sequence I have this code:

WinJS.Application.onactivated = function (…) {
var locator = new Windows.Devices.Geolocation.Geolocator();
locator.getGeopositionAsync().done(function (geocoord) { … };
}

The problem is that if the Geolocator object goes out of scope while the consent dialog is up, it will cancel the pending getGeopositionAsync operation, sending the error “Canceled” to the error handler just as if I tapped “Block” (though it all works on subseqeuent runs).

The simple solution is to just create the Geolocator outside of the event handler scope. That way the object sticks around and works just fine.

From what I can tell, this isn’t a universal behavior for WinRT objects; for example, in the same app I create a Windows.Media.Capture.CameraCaptureUI object, call captureFileAsync, and let the object go out of scope. This too has a consent prompt, but doesn’t cancel the capture operation.

In any case, it’s a good thing to be aware of–if you see odd behavior like this, try keeping the object in scope.


5 Comments

  1. Posted September 24, 2013 at 8:46 am | Permalink

    If the scope in question is the only reference to the object then surely letting it go out of scope means it is likely to be garbage collected? Thus this may always be a danger. Or am I missing something in what you mean by out of scope and the single threaded nature of JS?

    • Posted September 26, 2013 at 1:51 am | Permalink

      The issue isn’t whether the object gets garbage collected or not–that will happen when you just call new on a class, make an async call, then return from your function. Assuming that you don’t refer to the object in your completed handler then it will be gc’d.

      The issue here is that the Geolocator seems unique (in my experience) that it cancels any outstanding async requests when it gets disposed. It’s the only time I’ve run into a failure of an async call with this kind of coding pattern.

  2. Pablo
    Posted June 30, 2014 at 12:43 am | Permalink

    Hello, I’ve a strange problem using the Geolocator object in C#. Basically the first time my app call the getGeopositionAsync() or PositionChanged, no permission prompt appear.. by any change do you know why this happen?

    • kraigb
      Posted June 30, 2014 at 9:46 am | Permalink

      I’m assuming that the calls also fail? I suspect that you have not declared the Location capability in your manifest, in which case these calls always fail without prompting. If you declare the capability, then you should see the prompt on first run.

  3. Posted January 19, 2015 at 5:48 pm | Permalink

    I have a bing maps HTML store app that was behaving exactly the way you described.  It would randomly cancel the geolocation with an error on start.  And the fix (keeping a reference in my viewmodel) seemed to fix it.  Thanks!