Xamarin form Geolocation task cancelled exception

2020-03-30 05:52发布

问题:

I am working on Xamarin form app with andorid, UWP and Windows 8 project. I am using Geolocation plugin created by Jamesmontemagno to get the current device location. It is working fine in windows 8 and UWP but whenever I am trying to run it against the android device I keep getting task cancelled exception. I have checked all the permissions that are required as per suggestion but still no luck. My code to access location is below

  protected override void OnAppearing()
        {
            var locator = CrossGeolocator.Current;
            locator.DesiredAccuracy = 100; //100 is new default
            if (locator.IsGeolocationAvailable && locator.IsGeolocationEnabled)
            {
                try
                {
                    var position = locator.GetPositionAsync(timeoutMilliseconds: 60000).Result;
                    //var pp = helper.Setting.Location;
                    var Latitude = position.Latitude;
                    var Longitude = position.Longitude;
                }
                catch(Exception ex)
                {
                    var exc = ex;
                }
            }
        }

Below is an image for my settings for android manifest

回答1:

For anyone else who gets a timeout even with the await, only on Android, and even though the device's Google Maps app works fine, you are probably running into this bug which only happens on certain Android devices, but quite a few of them at that.

The issue is an old one that Google has never fixed. The solution, and one possible reason the Google Maps app works fine, is to use Google Play Services' fused location provider.

Currently the Geolocator Plugin just uses the regular Android Location Provider, but James has mentioned that he would like to use the Fused provider at some point. I have yet to try the fused provider myself though.



回答2:

Try using the await keyword like it is used in the original code:

try
{
  var locator = CrossGeolocator.Current;
  locator.DesiredAccuracy = 50;

  var position = await locator.GetPositionAsync (timeoutMilliseconds: 10000);

  Console.WriteLine ("Position Status: {0}", position.Timestamp);
  Console.WriteLine ("Position Latitude: {0}", position.Latitude);
  Console.WriteLine ("Position Longitude: {0}", position.Longitude);
}
catch(Exception ex)
{
  Debug.WriteLine("Unable to get location, may need to increase timeout: " + ex);
}

This should take care that there are no race condition and therefore TaskCancellationException.



回答3:

Thanks to @Radinator below is the working solution.

protected async override void OnAppearing()
        {
            var locator = CrossGeolocator.Current;
            locator.DesiredAccuracy = 100; //100 is new default
            if (locator.IsGeolocationAvailable && locator.IsGeolocationEnabled)
            {
                try
                {
                    await SetLocation();
                }
                catch (Exception ex)
                {
                    var exc = ex;
                }
            }
        }

        private async Task SetLocation()
        {
            var locator = CrossGeolocator.Current;
            locator.DesiredAccuracy = 100; //100 is new default
            if (locator.IsGeolocationAvailable && locator.IsGeolocationEnabled)
            {
                try
                {
                    var position = await locator.GetPositionAsync(timeoutMilliseconds: 60000);

                    var Latitude = position.Latitude;
                    var Longitude = position.Longitude;
                }
                catch (Exception ex)
                {
                    //log ex;
                    throw ex;
                }
            }
        }


回答4:

Faced 'Task killed' issue with v3.0.4. The following worked for me:

  1. Uninstall the app
  2. Update Geolocator to prerelease 4.0