首页 > 解决方案 > 尝试通过 Xam.Location.Geoplugin 获取 gps 位置时出现异常

问题描述

我以前使用相同的代码没有问题,但现在我无法获得位置,应用程序崩溃,异常如​​下。我改变的独特之处在于我调用 GetPosition 方法的方式,在我通过点击事件调用它之前,现在我必须在应用程序启动时调用它。

10-19 00:36:47.648 E/mono    (10400): Unhandled Exception:
10-19 00:36:47.648 E/mono    (10400): System.Threading.Tasks.TaskCanceledException: A task was canceled.
10-19 00:36:47.648 E/mono    (10400):   at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess (System.Threading.Tasks.Task task) [0x00026] in <43dbbdc147f2482093d8409abb04c233>:0 
10-19 00:36:47.648 E/mono    (10400):   at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification (System.Threading.Tasks.Task task) [0x00028] in <43dbbdc147f2482093d8409abb04c233>:0 
10-19 00:36:47.648 E/mono    (10400):   at System.Runtime.CompilerServices.TaskAwaiter.ValidateEnd (System.Threading.Tasks.Task task) [0x00008] in <43dbbdc147f2482093d8409abb04c233>:0 
10-19 00:36:47.648 E/mono    (10400):   at System.Runtime.CompilerServices.TaskAwaiter`1[TResult].GetResult () [0x00000] in <43dbbdc147f2482093d8409abb04c233>:0 
10-19 00:36:47.648 E/mono    (10400):   at Plugin.Geolocator.GeolocatorImplementation+<GetPositionAsync>d__41.MoveNext () [0x004d3] in <e6cb69436f5b455fa0a66dc46ca4b792>:0 Thread started: <Thread Pool> #18
10-19 00:36:47.648 E/mono    (10400): --- End of stack trace from previous location where exception was thrown ---
10-19 00:36:47.648 E/mono    (10400):   at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess (System.Threading.Tasks.Task task) [0x0001a] in <43dbbdc147f2482093d8409abb04c233>:0 Thread started: <Thread Pool> #19
10-19 00:36:47.648 E/mono    (10400):   at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification (System.Threading.Tasks.Task task) [0x00028] in <43dbbdc147f2482093d8409abb04c233>:0 
Thread started: <Thread Pool> #2010-19 00:36:47.648 E/mono    (10400):   at System.Runtime.CompilerServices.TaskAwaiter.ValidateEnd (System.Threading.Tasks.Task task) [0x00008] in <43dbbdc147f2482093d8409abb04c233>:0 
10-19 00:36:47.648 E/mono    (10400):   at System.Runtime.CompilerServices.TaskAwaiter`1[TResult].GetResult () [0x00000] in <43dbbdc147f2482093d8409abb04c233>:0 
10-19 00:36:47.648 E/mono    (10400):   at BatePapo.MainPage+<GetPosition>d__2.MoveNext () [0x000da] in D:\apps\BatePapo\BatePapo\BatePapo\MainPage.xaml.cs:29 
10-19 00:36:47.648 E/mono    (10400): --- End of stack trace from previous location where exception was thrown ---
10-19 00:36:47.648 E/mono    (10400):   at (wrapper dynamic-method) System.Object.75(intptr,intptr)
10-19 00:36:47.678 E/mono-rt (10400): [ERROR] FATAL UNHANDLED EXCEPTION: System.Threading.Tasks.TaskCanceledException: A task was canceled.
10-19 00:36:47.678 E/mono-rt (10400):   at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess (System.Threading.Tasks.Task task) [0x00026] in <43dbbdc147f2482093d8409abb04c233>:0 
10-19 00:36:47.678 E/mono-rt (10400):   at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification (System.Threading.Tasks.Task task) [0x00028] in <43dbbdc147f2482093d8409abb04c233>:0 
10-19 00:36:47.678 E/mono-rt (10400):   at System.Runtime.CompilerServices.TaskAwaiter.ValidateEnd (System.Threading.Tasks.Task task) [0x00008] in <43dbbdc147f2482093d8409abb04c233>:0 
10-19 00:36:47.678 E/mono-rt (10400):   at System.Runtime.CompilerServices.TaskAwaiter`1[TResult].GetResult () [0x00000] in <43dbbdc147f2482093d8409abb04c233>:0 
10-19 00:36:47.678 E/mono-rt (10400):   at Plugin.Geolocator.GeolocatorImplementation+<GetPositionAsync>d__41.MoveNext () [0x004d3] in <e6cb69436f5b455fa0a66dc46ca4b792>:0 
10-19 00:36:47.678 E/mono-rt (10400): --- End of stack trace from previous location where exception was thrown ---
10-19 00:36:47.678 E/mono-rt (10400):   at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess (System.Threading.Tasks.Task task) [0x0001a] in <43dbbdc147f2482093d8409abb04c233>:0 
10-19 00:36:47.678 E/mono-rt (10400):   at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification (System.Threading.Tasks.Task task) [0x00028] in <43dbbdc147f2482093d8409abb04c233>:0 
10-19 00:36:47.678 E/mono-rt (10400):   at System.Runtime.CompilerServices.TaskAwaiter.ValidateEnd (System.Threading.Tasks.Task task) [0x00008] in <43dbbdc147f2482093d8409abb04c233>:0 
10-19 00:36:47.678 E/mono-rt (10400):   at System.Runtime.CompilerServices.TaskAwaiter`1[TResult].GetResult () [0x00000] in <43dbbdc147f2482093d8409abb04c233>:0 
10-19 00:36:47.678 E/mono-rt (10400):   at BatePapo.MainPage+<GetPosition>d__2.MoveNext () [0x000da] in D:\apps\BatePapo\BatePapo\BatePapo\MainPage.xaml.cs:29 
10-19 00:36:47.678 E/mono-rt (10400): --- End of stack trace from previous location where exception was thrown ---
10-19 00:36:47.678 E/mono-rt (10400):   at (wrapper dynamic-method) System.Object.75(intptr,intptr)
10-19 00:36:47.684 D/        (10400): HostConnection::get() New Host Connection established 0xd09ad500, tid 10400

MainActivity.cs:

using System;
using Android;
using Android.App;
using Android.Content;
using Android.Runtime;
using Android.Views;
using Android.Widget;
using Android.OS;
using Android.Content.PM;
using Android.Util;
using Android.Support.V4.App;
using Android.Support.Design.Widget;
using System.Threading.Tasks;

namespace BatePapo.Droid
{
    [Activity(Label = "MyApp", Icon = "@mipmap/icon", Theme = "@style/MainTheme", MainLauncher = true, ConfigurationChanges = ConfigChanges.ScreenSize | ConfigChanges.Orientation)]
    public class MainActivity : global::Xamarin.Forms.Platform.Android.FormsAppCompatActivity, ActivityCompat.IOnRequestPermissionsResultCallback
    {
        protected async override void OnCreate(Bundle savedInstanceState)
        {
            await TryToGetPermissions();
            TabLayoutResource = Resource.Layout.Tabbar;
            ToolbarResource = Resource.Layout.Toolbar;

            base.OnCreate(savedInstanceState);
            global::Xamarin.Forms.Forms.Init(this, savedInstanceState);
            LoadApplication(new App());
        }

        #region RuntimePermissions
        async Task TryToGetPermissions()
        {
            if ((int)Build.VERSION.SdkInt >= 23)
            {
                await GetPermissionsAsync();
                return;
            }
        }
        const int RequestLocationId = 0;

        readonly string[] PermissionsGroupLocation =
        {
            Manifest.Permission.AccessCoarseLocation,
            Manifest.Permission.AccessFineLocation,
        };

        async Task GetPermissionsAsync()
        {
            const string permission = Manifest.Permission.AccessFineLocation;

            if (CheckSelfPermission(permission) == (int)Android.Content.PM.Permission.Granted)
            {
                //TODO change the message to show the permissions name
                Toast.MakeText(this, "Permissões concedidas.", ToastLength.Short).Show();
                return;
            }

            if (ShouldShowRequestPermissionRationale(permission))
            {
                //set alert for executing the task
                AlertDialog.Builder alert = new AlertDialog.Builder(this);
                alert.SetTitle("Permissões necessárias");
                alert.SetMessage("Esta aplicação precisa de permissões para continuar.");
                alert.SetPositiveButton("Conceder permissões", (senderAlert, args) =>
                {
                    RequestPermissions(PermissionsGroupLocation, RequestLocationId);
                });

                alert.SetNegativeButton("Cancelar", (senderAlert, args) =>
                {
                    Toast.MakeText(this, "Cancelado!", ToastLength.Short).Show();
                });

                Dialog dialog = alert.Create();
                dialog.Show();
                return;
            }
            RequestPermissions(PermissionsGroupLocation, RequestLocationId);
        }

        public override async void OnRequestPermissionsResult(int requestCode, string[] permissions, [GeneratedEnum] Android.Content.PM.Permission[] grantResults)
        {
            switch (requestCode)
            {
                case RequestLocationId:
                    {
                        if (grantResults[0] == (int)Android.Content.PM.Permission.Granted)
                        {
                            Toast.MakeText(this, "Permissões especiais concedidas.", ToastLength.Short).Show();

                        }
                        else
                        {
                            //Permission Denied :(
                            Toast.MakeText(this, "Permissões especiais negadas.", ToastLength.Short).Show();
                        }
                    }
                    break;
            }
            //base.OnRequestPermissionsResult(requestCode, permissions, grantResults);
        }
        #endregion
    }
}

MainPage.Xaml.Cs

namespace MyApp
{
    [XamlCompilation(XamlCompilationOptions.Compile)]
    public partial class MainPage : TabbedPage
    {
        public static Position position;
        public MainPage()
        {
            GetPosition();
            InitializeComponent();
        }

    private async void GetPosition()
    {
        try
        {
            var locator = CrossGeolocator.Current;
            locator.DesiredAccuracy = 50;
            position = await locator.GetPositionAsync(TimeSpan.FromSeconds(10));
        }
        catch (Exception)
        {
            throw;
        }
      }
    }
}

任何人都可以看到问题吗?

标签: c#xamaringeolocation

解决方案


GetPosition是一个异步方法,你必须等待它然后更新 UI。您不能在构造函数中等待,因此您需要将逻辑移至OnAppearing方法中

private async Task<Position> GetPositionAsync()
{
    try
    {
        var locator = CrossGeolocator.Current;
        locator.DesiredAccuracy = 50;
        return await locator.GetPositionAsync(TimeSpan.FromSeconds(10));
    }
    catch (Exception)
    {
        // handle it properly
        throw;
    }
  }
}

protected override async void OnAppearing()
{
    base.OnAppearing();
    var position = await GetPositionAsync();
}

始终为异步方法使用Task<T>返回类型,EventHandler 除外


推荐阅读