3
votes

I am trying to access the current location of my device in a Xamarin forms app I am using the Geolocation plugin created by James Montemagno. I have added a reference in my pcl and platform project but every time my app hits the bold line of code I get a System.Threading.Tasks.TaskCanceledException: A task was canceled. I have also added all the necessary settings in the android manifest.

 var locator = CrossGeolocator.Current;

 locator.DesiredAccuracy = 100;

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

Here is StackTrace

System.Threading.Tasks.TaskCanceledException: A task was canceled.
at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess (System.Threading.Tasks.Task task) [0x0002d] in /Users/builder/data/lanes/2512/d3008455/source/mono/external/referencesource/mscorlib/system/runtime/compilerservices/TaskAwaiter.cs:193 at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification (System.Threading.Tasks.Task task) [0x0002e] in /Users/builder/data/lanes/2512/d3008455/source/mono/external/referencesource/mscorlib/system/runtime/compilerservices/TaskAwaiter.cs:170 at System.Runtime.CompilerServices.TaskAwaiter.ValidateEnd (System.Threading.Tasks.Task task) [0x0000b] in /Users/builder/data/lanes/2512/d3008455/source/mono/external/referencesource/mscorlib/system/runtime/compilerservices/TaskAwaiter.cs:142 at System.Runtime.CompilerServices.ConfiguredTaskAwaitable1+ConfiguredTaskAwaiter[TResult].GetResult () [0x00000] in /Users/builder/data/lanes/2512/d3008455/source/mono/external/referencesource/mscorlib/system/runtime/compilerservices/TaskAwaiter.cs:580 at Plugin.Geolocator.GeolocatorImplementation+<GetPositionAsync>d__27.MoveNext () [0x00597] in G:\GitHub\Xamarin.Plugins\Geolocator\Geolocator\Geolocator.Plugin.Android\GeolocatorImplementation.cs:195 at --- End of stack trace from previous location where exception was thrown --- at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw () [0x0000c] in /Users/builder/data/lanes/2512/d3008455/source/mono/external/referencesource/mscorlib/system/runtime/exceptionservices/exceptionservicescommon.cs:143 at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess (System.Threading.Tasks.Task task) [0x00027] in /Users/builder/data/lanes/2512/d3008455/source/mono/external/referencesource/mscorlib/system/runtime/compilerservices/TaskAwaiter.cs:190 at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification (System.Threading.Tasks.Task task) [0x0002e] in /Users/builder/data/lanes/2512/d3008455/source/mono/external/referencesource/mscorlib/system/runtime/compilerservices/TaskAwaiter.cs:170 at System.Runtime.CompilerServices.TaskAwaiter.ValidateEnd (System.Threading.Tasks.Task task) [0x0000b] in /Users/builder/data/lanes/2512/d3008455/source/mono/external/referencesource/mscorlib/system/runtime/compilerservices/TaskAwaiter.cs:142 at System.Runtime.CompilerServices.TaskAwaiter1[TResult].GetResult () [0x00000] in /Users/builder/data/lanes/2512/d3008455/source/mono/external/referencesource/mscorlib/system/runtime/compilerservices/TaskAwaiter.cs:372 at NetJetApp.Views.Home+d__52.MoveNext () [0x0003e] in c:\svn\Netjet\trunk\NetJetXamarin\NetJet\NetJetApp\NetJetApp\Views\Home.cs:552 at --- End of stack trace from previous location where exception was thrown --- at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw () [0x0000c] in /Users/builder/data/lanes/2512/d3008455/source/mono/external/referencesource/mscorlib/system/runtime/exceptionservices/exceptionservicescommon.cs:143 at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess (System.Threading.Tasks.Task task) [0x00027] in /Users/builder/data/lanes/2512/d3008455/source/mono/external/referencesource/mscorlib/system/runtime/compilerservices/TaskAwaiter.cs:190 at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification (System.Threading.Tasks.Task task) [0x0002e] in /Users/builder/data/lanes/2512/d3008455/source/mono/external/referencesource/mscorlib/system/runtime/compilerservices/TaskAwaiter.cs:170 at System.Runtime.CompilerServices.TaskAwaiter.ValidateEnd (System.Threading.Tasks.Task task) [0x0000b] in /Users/builder/data/lanes/2512/d3008455/source/mono/external/referencesource/mscorlib/system/runtime/compilerservices/TaskAwaiter.cs:142 at System.Runtime.CompilerServices.TaskAwaiter`1[TResult].GetResult () [0x00000] in /Users/builder/data/lanes/2512/d3008455/source/mono/external/referencesource/mscorlib/system/runtime/compilerservices/TaskAwaiter.cs:372 at NetJetApp.Views.Home+d__49.MoveNext () [0x00111] in c:\svn\Netjet\trunk\NetJetXamarin\NetJet\NetJetApp\NetJetAp at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw () [0x0000c] in /Users/builder/data/lanes/2512/d3008455p\Views\Home.cs:532 at --- End of stack trace from previous location where exception was thrown ---/source/mono/external/referencesource/mscorlib/system/runtime/exceptionservices/exceptionservicescommon.cs:143 at System.Runtime.CompilerServices.AsyncMethodBuilderCore.m__0 (System.Object state) [0x00000] in /Users/builder/data/lanes/2512/d3008455/source/mono/external/referencesource/mscorlib/system/runtime/compilerservices/AsyncMethodBuilder.cs:994 at Android.App.SyncContext+c__AnonStorey0.<>m__0 () [0x00000] in /Users/builder/data/lanes/2512/d3008455/source/monodroid/src/Mono.Android/src/Android.App/SyncContext.cs:18 at Java.Lang.Thread+RunnableImplementor.Run () [0x0000b] in /Users/builder/data/lanes/2512/d3008455/source/monodroid/src/Mono.Android/src/Java.Lang/Thread.cs:36 at Java.Lang.IRunnableInvoker.n_Run (IntPtr jnienv, IntPtr native__this) [0x00009] in /Users/builder/data/lanes/2512/d3008455/source/monodroid/src/Mono.Android/platforms/android-23/src/generated/Java.Lang.IRunnable.cs:71 at at (wrapper dynamic-method) System.Object:089044c0-4139-4792-8365-3f98e93136b3 (intptr,intptr)

2
A couple of things to try, even if only to rule them out. Have you tried a smaller DesiredAccuracy? Our apps use 50. Does the code check locator.IsGeolocationEnabled first?Mark Larter
I tried 50 but i find no win , no i did'nt do the check where should i do itsipho
I'll go ahead and post an answer with the code we are using.Mark Larter
I have managed to get the exception you are running into, while running the code in my answer in Visual Studio 2013 debugger using Android device. My perception while waiting for a breakpoint to inspect position is that the call to GetCurrentLocation took more than 10 second. If so that would have tripped the timeout and may have caused the task cancellation. I'll shorten the timeout to see if I can get more consistent failures.Mark Larter
A shorter timeout definitely increases the likelihood of the TaskCanceledException. At 1000 the exception is occurring almost every time. I modified my answer a bit, hope this helps.Mark Larter

2 Answers

0
votes

In my testing, there is a definite correlation between the GetPositionAsync timeout expiry and the TaskCanceledException, so a larger value could reduce the likelihood of that exception. I definitely want to thank you for your question, because it made me look into this code in our framework more closely.

For sure, the app code needs to handle the reality that the device may not be able to provide position in a reasonable amount of time, for any number of reasons.

To help with the crash, the code below is in a Xamarin.Forms PCL project, used from Xamarin.Android and Xamarin.iOS projects whose apps are in the app stores.

There are no essential differences between this and what you posted, other than the check for IsGeolocationEnabled and the exception handling, but with that exception handling and the debug statements hopefully it prevents app crash and helps you get further along.

public static async Task<Position> GetCurrentLocation()
{
    // Capture the current location.
    Position position = null;
    try
    {
        var locator = CrossGeolocator.Current;
        locator.DesiredAccuracy = 50;

        // Get the current device position. Leave it null if geo-location is disabled,
        // return position (0, 0) if unable to acquire.
        if (locator.IsGeolocationEnabled)
        {
            // Allow ten seconds for geo-location determination.                    
            position = await locator.GetPositionAsync(10000);
        }
        else
        {
            Debug.WriteLine("Location could not be acquired, geolocator is disabled.");
        }
    }
    catch (Exception le)
    {
        // TODO: Log this error.
        Debug.WriteLine("Location could not be acquired.");
        Debug.WriteLine(le.Message);
        Debug.WriteLine(le.StackTrace);
        position = new Position() { Latitude = 0, Longitude = 0 };
    }

    return position;
}
0
votes

I had the same problem using a shared Xamarin.Forms library. I solved it on iOS, but I am still working on the Android version.

Note: It is necessary to include the Xam.Plugin.Geolocator package in all the projects

I hope this code can help you


In the shared library I have the following:

  • App.xaml
  • App.xaml.cs
  • MyAppPage.xaml
  • MyAppPage.xaml.cs

In the iOS Library I changed only the

  • AppDelegate.cs

File Contents:

  • Changes in App.xaml.cs

    public App(IGeolocator geolocator)
    {
        InitializeComponent();
        MainPage = new MySpeedPage(geolocator);
    }
    
  • MyAppPage.xaml.cs

    public partial class MyAppPage : ContentPage
    {
        readonly IGeolocator geolocator;
    
        public MyAppPage(IGeolocator geolocator)
        {
            InitializeComponent();
            this.geolocator = geolocator;
            this.geolocator.DesiredAccuracy = 50;
            this.geolocator.PositionChanged += new EventHandler<PositionEventArgs>(OnGeolocatorPositionChanged);
        }
    
        void OnGeolocatorPositionChanged(object sender, PositionEventArgs e)
        {
            LabLatitude.Text = String.Format("Lat: {0:F4}", e.Position.Latitude);
            LabLongitude.Text = String.Format("Lon: {0:F4}", e.Position.Longitude);
        }
    
        void OnBtnStartClicked(object sender, EventArgs args)
        {
            BtnStart.IsEnabled = false;
            BtnStop.IsEnabled = true;
            geolocator.StartListeningAsync(2500, 10.0f, true);
        }
    
        void OnBtnStopClicked(object sender, EventArgs args)
        {
            BtnStart.IsEnabled = true;
            BtnStop.IsEnabled = false;
            geolocator.StopListeningAsync();
        }
    
     }
    
  • Changes in "AppDelegate.cs"

    public override bool FinishedLaunching(UIApplication app, NSDictionary options)
    {
        global::Xamarin.Forms.Forms.Init();
    
        var MyApp = new App(CrossGeolocator.Current);
        LoadApplication(MyApp);
    
        return base.FinishedLaunching(app, options);
    }