如何解决plugin.geolocator包未实现的异常?

时间:2019-04-03 05:27:58

标签: c# android xamarin.forms

我正在尝试创建一个应用。在这里,我试图通过单击按钮来获取用户的当前位置。但是它会产生类似 Not Implemented exception的异常-此程序集的可移植版本中未实现此功能。您应该从主应用程序项目中引用NuGet包,以引用特定于平台的实现

  1. 我已经清理并重建了解决方案。
  2. 我已经启用了access_fine_location的权限, access_coarse_location。
  3. 我添加了plugin.current并在mainactivity.cs中添加了一个活动 文件。
           string answer ="";
           try
           {
                await CrossGeolocator.Current.StartListeningAsync(new 
                  TimeSpan(20000),10);
                if (CrossGeolocator.Current.IsListening)
                {
                    var locator = CrossGeolocator.Current;
                    locator.DesiredAccuracy = 50;
                    var position = await 
                      locator.GetPositionAsync(TimeSpan.FromSeconds(20000));
                    string lat = position.Latitude.ToString();
                    string lon = position.Longitude.ToString();
                    answer = lat + lon;
                }
                else
                {
                    answer= "Not listening";
                }

            }
            catch (Exception ex)
            {
                answer= ex.Message;
            }

我需要包含经度和纬度值的结果。 我在项目中必须做什么?

已编辑:

 public async Task<String> GetLastKnownLocationAsync()
    {
        Position ObjPosition = null;
        try
        {
            await DependencyService.Get<IGeolocator>().StartListeningAsync(new TimeSpan(20000), 10);
            if (CrossGeolocator.Current.IsListening)
            {
                var locator = CrossGeolocator.Current;
                locator.DesiredAccuracy = 50;
                ObjPosition = await DependencyService.Get<IGeolocator>().GetPositionAsync(TimeSpan.FromSeconds(20)); 
                string lat = ObjPosition.Latitude.ToString();
                string lon = ObjPosition.Longitude.ToString();
                Info = lat + lon;
            }
            else
            {
                Info = "Not listening";
            }
            return Info;
        }
        catch (Exception ex)
        {
            Info = ex.Message;
            return Info;
        }
    }

第六行出现错误。

3 个答案:

答案 0 :(得分:0)

我也在Xamarin.Forms应用程序中实现了GPS跟踪功能。根据我的个人经验,Geolocator插件无法与Xamarin.Forms一起使用,并且也存在一些问题和局限性。该插件是通过参考Xamarin Essentials Geolocation开发的。我建议您使用Xamarin Essentials而不是Geolocator插件,因为它已被充分记录并易于实现且没有任何重大问题。您可以从以下链接中找到逐步实施Xamarin Essentials地理位置的指南:

https://docs.microsoft.com/en-us/xamarin/essentials/geolocation?tabs=android

答案 1 :(得分:0)

您是否在共享项目和平台项目上都安装了NuGet软件包?在这种情况下,错误消息非常准确。基本上,这里发生的是该插件安装了一种形式的依赖服务,该服务具有特定于平台的实现,并且只是共享项目上的一个接口。

由于某种原因,您的调用最终以共享代码结尾,该代码仅实现此异常,以使您知道自己位置错误。这通常是由于没有在平台项目上安装软件包,或者是链接程序“优化了”了软件包。之所以会发生这种情况,是因为编译器注意到项目中没有对该库的引用,因此将其剥离以减少占用空间。

为确保最后的事情不会发生,您可以进入平台项目(在本例中为Android)并进入MainActivity.cs,然后在此插件中添加对对象的虚拟引用。例如,添加以下内容:

protected override void OnCreate(Bundle savedInstanceState)
{
    TabLayoutResource = Resource.Layout.Tabbar;
    ToolbarResource = Resource.Layout.Toolbar;

    base.OnCreate(savedInstanceState);

    global::Xamarin.Forms.Forms.Init(this, savedInstanceState);

    // THIS WAS ADDED
    var foo = new Plugin.Geolocator.Abstractions.Address();

    LoadApplication(new App());
}

这实际上是许多此类库以前都具有Init方法的原因。

说了这么多,我实际上必须在另一个答案中同意Akshay的建议,并且如果可能的话,您可能要考虑将项目升级为使用.NET Standard,然后移至Xamarin.Essentials库,该库包含所有内容。痛苦消除了。

答案 2 :(得分:0)

以下是我通常会给您的一些建议:如果您遇到问题而无法解决,请尝试创建一个单独的小项目,并提供有关其工作原理的分步教程。通常它可以正常工作,您可以找出主要解决方案到底出了什么问题。

编辑:

Link to DependencyService

很快,您必须创建供您使用的接口,即IMyInterface。之后,编写具有接口实现的Android / iOS平台特定的类。编写时,可以使用如下方法: DependencyService.Get<IMyInterface>().YourMethod()

编辑2

您必须为此添加特定于平台的类:

[assembly: Dependency(typeof(MyCustomClass))]    // Check this assembly
namespace ISSO_I.Droid.PlatformSpecific
{
    public class MyCustomClass: IMyInterface
    {
     /// your code here
    }
}

编辑3:

呼叫位置更新:

protected override void OnAppearing()
        {
            base.OnAppearing();
            ToIssoView = false;
            RequestLocationUpdates(); // Call this method
        }

请求位置更新的方法:

public async void RequestLocationUpdates()
        {
            /// check permission for location updates
            var hasPermission = await CommonStaffUtils.CheckPermissions(Permission.Location);
            if (!hasPermission)
                return;
            if (CrossGeolocator.Current.IsListening) return;
            MyMap.MyLocationEnabled = true;
            CrossGeolocator.Current.PositionChanged += Current_PositionChanged;
            CrossGeolocator.Current.PositionError += Current_PositionError;
            await CrossGeolocator.Current.StartListeningAsync(TimeSpan.FromSeconds(1), 5);
        }

public static async Task<bool> CheckPermissions(Permission permission)
        {
            var permissionStatus = await CrossPermissions.Current.CheckPermissionStatusAsync(permission);
            var request = false;
            if (permissionStatus == PermissionStatus.Denied)
            {
                if (Device.RuntimePlatform == Device.iOS)
                {

                    var title = $"{permission} Permission";
                    var question = $"To use this plugin the {permission} permission is required. Please go into Settings and turn on {permission} for the app.";
                    const string positive = "Settings";
                    const string negative = "Maybe Later";
                    var task = Application.Current?.MainPage?.DisplayAlert(title, question, positive, negative);
                    if (task == null)
                        return false;

                    var result = await task;
                    if (result)
                    {
                        CrossPermissions.Current.OpenAppSettings();
                    }

                    return false;
                }

                request = true;

            }

            if (!request && permissionStatus == PermissionStatus.Granted) return true;
            {
                var newStatus = await CrossPermissions.Current.RequestPermissionsAsync(permission);
                if (!newStatus.ContainsKey(permission) || newStatus[permission] == PermissionStatus.Granted) return true;
                var title = $"{permission} Permission";
                var question = $"To use the plugin the {permission} permission is required.";
                const string positive = "Settings";
                const string negative = "Maybe Later";
                var task = Application.Current?.MainPage?.DisplayAlert(title, question, positive, negative);
                if (task == null)
                    return false;

                var result = await task;
                if (result)
                {
                    CrossPermissions.Current.OpenAppSettings();
                }
                return false;
            }
        }