CrossGeolocator's GetPositionAsync does not wo

2020-04-02 10:03发布

I am using CrossGeolocator to retrieve the current latitude and longitude of the device. However I am using it inside an OnAppearing override method and it is not working. The GetPositionAsync method hangs the App.

 protected override void OnAppearing()
 {
     base.OnAppearing();

     var position = GetPosition().Result;
     var lat = position.Latitude;
     var lon = position.Longitude;
 }

 private static async Task<Position> GetPosition()
 {
     var locator = CrossGeolocator.Current;
     locator.DesiredAccuracy = 50;

     var position = await locator.GetPositionAsync(10000);
     return position;
 }

Detail is that I am using this same GetPosition method in buttons in the application and works perfectly.

Could someone help me in this matter?

5条回答
家丑人穷心不美
2楼-- · 2020-04-02 10:13

This worked for me.

Set up the xamarin forms maps as stated in the link. https://developer.xamarin.com/guides/xamarin-forms/user-interface/map/

set permissions as stated in below link https://jamesmontemagno.github.io/GeolocatorPlugin/GettingStarted.html

you may make use of https://jamesmontemagno.github.io/GeolocatorPlugin/CurrentLocation.html

using Plugin.Geolocator;
using System;
using Xamarin.Forms;
using Xamarin.Forms.Maps;
using Xamarin.Forms.Xaml;
namespace MapApp
{
    [XamlCompilation(XamlCompilationOptions.Compile)]
    public partial class MapPage : ContentPage
    {
        private Position _position;
        public MapPage()
        {
            InitializeComponent();

            var map = new Map(
              MapSpan.FromCenterAndRadius(
                      new Position(37, -122), Distance.FromMiles(0.3)))
            {
                IsShowingUser = true,
                HeightRequest = 100,
                WidthRequest = 960,
                VerticalOptions = LayoutOptions.FillAndExpand
            };



            if (IsLocationAvailable())
            {
                GetPosition();
                map.MoveToRegion(MapSpan.FromCenterAndRadius(_position, Distance.FromMiles(1)));

            }

            map.MapType = MapType.Street;
            var stack = new StackLayout { Spacing = 0 };
            stack.Children.Add(map);
            Content = stack;

        }

        public bool IsLocationAvailable()
        {
            if (!CrossGeolocator.IsSupported)
                return false;

            return CrossGeolocator.Current.IsGeolocationAvailable;
        }
        public async void GetPosition()
        {
            Plugin.Geolocator.Abstractions.Position position = null;
            try
            {
                var locator = CrossGeolocator.Current;
                locator.DesiredAccuracy = 100;

                position = await locator.GetLastKnownLocationAsync();

                if (position != null)
                {
                    _position = new Position(position.Latitude, position.Longitude);
                    //got a cahched position, so let's use it.
                    return;
                }

                if (!locator.IsGeolocationAvailable || !locator.IsGeolocationEnabled)
                {
                    //not available or enabled
                    return;
                }

                position = await locator.GetPositionAsync(TimeSpan.FromSeconds(20), null, true);

            }
            catch (Exception ex)
            {
                throw ex;
                //Display error as we have timed out or can't get location.
            }
            _position = new Position(position.Latitude, position.Longitude);
            if (position == null)
                return;

        }

    }
}
查看更多
forever°为你锁心
3楼-- · 2020-04-02 10:15

Try this:

Create a global variable:

private Position _position;

Then call ur method to get the position on constructor. Re-write ur method like this:

public async void GetPosition()
{
    var locator = CrossGeolocator.Current;
    locator.DesiredAccuracy = 50;
    var myPosition = await locator.GetPositionAsync();
    _position = new Position(myPosition.Latitude, myPosition.Longitude);
}

Then make a while where u want to use this:

while(_position == new Postion(0,0))
      GetPosition();
查看更多
Summer. ? 凉城
4楼-- · 2020-04-02 10:27

I solved my problem just adding the parameters in GetPositionAsync: null and true.

var location = await locator.GetPositionAsync(TimeSpan.FromSeconds(20), null, true);

and turn on the GPS

My problem was on Android 4.4

查看更多
贼婆χ
5楼-- · 2020-04-02 10:28

Things to take care is

calling the method in constructor. have available lat long if exists. VERY IMP have try catch, without try catch the application crashes. Not writing any thing in catch as don;t want to catch exception.

    using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

using Foundation;
using UIKit;
using System.Threading.Tasks;
using Plugin.Geolocator.Abstractions;
using Plugin.Geolocator;
using System.Diagnostics;
using Xamarin.Forms;
using abcde.iOS;

[assembly: Xamarin.Forms.Dependency(typeof(GPSLocation_iOS))]

namespace abcde.iOS
{
public class GPSLocation_iOS : IGPSLocation
{
public Position _position;

    public GPSLocation_iOS()
    {
        GetPosition();
    }

    public Dictionary<string, string> GetGPSLocation()
    {
    Dictionary<string, string> dictPosition = new Dictionary<string, string>();

    dictPosition.Add("latitude", _position.Latitude.ToString());
    dictPosition.Add("longitude", _position.Longitude.ToString());

      return dictPosition;
    }

    public async void GetPosition()
    {
        try
        {
            var locator = CrossGeolocator.Current;

            _position = await locator.GetLastKnownLocationAsync();

            if (_position == null)
            {
      locator.DesiredAccuracy = 50;
      var myPosition = await locator.GetPositionAsync();
      _position = new Position(myPosition.Latitude, myPosition.Longitude);
            }
        }
        catch (Exception ex)
        {

        }
    }
查看更多
【Aperson】
6楼-- · 2020-04-02 10:28

latest 2018-07-10 version update,

To support iOS 11 and earlier, you can include all three keys:

  • NSLocationWhenInUseUsageDescription,
  • NSLocationAlwaysAndWhenInUseUsageDescription
  • NSLocationAlwaysUsageDescription.

I use Xamarin to write app, and it works fine in my iOS project

reference : https://docs.microsoft.com/en-us/xamarin/xamarin-forms/user-interface/map

查看更多
登录 后发表回答