简体   繁体   中英

How to resolve not implemented exception with plugin.geolocator package?

I'm trying to create an app. Here I'm trying to get the user's current location by clicking the button. But it produces an exception like Not Implemented exception - This functionality is not implemented in the portable version of this assembly. You should reference the NuGet package from your main application project in order to reference the platform-specific implementation

  1. Already I did clean and rebuild the solution.
  2. And I've enabled the permission for access_fine_location, access_coarse_location.
  3. I've added plugin.current and add an activity inside the mainactivity.cs file.
           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;
            }

I need the result which contains the longitude and latitude values. What I've to do in my project?

Edited :

 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;
        }
    }

I'm getting error on the sixth line.

I have implemented GPS tracking functionality in my Xamarin.Forms application too. And as per my personal experience, Geolocator plugin doesn't work as expected with Xamarin.Forms and also have some issues and limitations too. This plugin is developed by taking reference of Xamarin Essentials Geolocation. I will suggest that you should use Xamarin Essentials instead of Geolocator plugin as it is well documented and easy to implement without any major issues. You can find step by step guid to implement Xamarin Essentials Geolocation from following link:

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

Did you install the NuGet package on both your shared project as well as your platform projects? The error message, in this case, is quite accurate. What basically happens here is that this plugin installs a form of dependency service that has a platform-specific implementation and just an interface on your shared project.

For some reason, your calls end up in the shared code, which only implements this exception to let you know you're in the wrong place. This is usually due to not having the package installed on your platform project, or, the package being "optimized away" by the linker. This tends to happen because the compiler notices there is no reference from your project to this library, so it strips it to let it take up less space.

To make sure this last thing doesn't happen, you can go into your platform project, in this case, Android and go into the MainActivity.cs and add a dummy reference to an object in this plugin. For instance, add this:

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());
}

This is actually the reason a lot of these libraries used to have an Init method.

Having said all this, I actually have to agree with Akshay in the other answer and if at all possible, you probably want to look at upgrading your project to use .NET Standard and move to the Xamarin.Essentials library which takes all of this pain away.

Here is a little advice for you, that I usually use: if you have an issue and can't resolve it, try to create a separate little project with step-by-step tutorial of how that works. Usually it works, and you can find out what exactly wrong with your main solution.

EDIT:

Link to DependencyService

Shortly, you have to create Interface that would be used by you, ie IMyInterface . After that, write platform-specific classes for Android/iOS with interface implementation. When you write it, you can use the methods like so: DependencyService.Get<IMyInterface>().YourMethod() .

EDIT 2 :

You have to add this for your platform-specific classes:

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

EDIT 3:

Call location Updates:

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

Method to request location updates:

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;
            }
        }

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM